From 6e19a8dd13935b73be6b4ba3ca8fb7a003367229 Mon Sep 17 00:00:00 2001 From: plumedbot Date: Mon, 27 May 2024 13:05:18 +0000 Subject: [PATCH] Update to plumed/plumed2@eabfee2 --- .nojekyll | 0 README.md | 12 + coverage-libs/amber.png | Bin 0 -> 141 bytes .../asmjit/arch.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/arch.cpp.func.html | 80 + coverage-libs/asmjit/arch.cpp.gcov.html | 263 + coverage-libs/asmjit/arch.h.func-sort-c.html | 72 + coverage-libs/asmjit/arch.h.func.html | 72 + coverage-libs/asmjit/arch.h.gcov.html | 304 + .../asmjit/assembler.cpp.func-sort-c.html | 144 + coverage-libs/asmjit/assembler.cpp.func.html | 144 + coverage-libs/asmjit/assembler.cpp.gcov.html | 549 + .../asmjit/assembler.h.func-sort-c.html | 72 + coverage-libs/asmjit/assembler.h.func.html | 72 + coverage-libs/asmjit/assembler.h.gcov.html | 259 + .../asmjit/codebuilder.cpp.func-sort-c.html | 204 + .../asmjit/codebuilder.cpp.func.html | 204 + .../asmjit/codebuilder.cpp.gcov.html | 686 + .../asmjit/codebuilder.h.func-sort-c.html | 72 + coverage-libs/asmjit/codebuilder.h.func.html | 72 + coverage-libs/asmjit/codebuilder.h.gcov.html | 1020 + .../asmjit/codecompiler.cpp.func-sort-c.html | 216 + .../asmjit/codecompiler.cpp.func.html | 216 + .../asmjit/codecompiler.cpp.gcov.html | 675 + .../asmjit/codecompiler.h.func-sort-c.html | 72 + coverage-libs/asmjit/codecompiler.h.func.html | 72 + coverage-libs/asmjit/codecompiler.h.gcov.html | 843 + .../asmjit/codeemitter.cpp.func-sort-c.html | 196 + .../asmjit/codeemitter.cpp.func.html | 196 + .../asmjit/codeemitter.cpp.gcov.html | 338 + .../asmjit/codeemitter.h.func-sort-c.html | 72 + coverage-libs/asmjit/codeemitter.h.func.html | 72 + coverage-libs/asmjit/codeemitter.h.gcov.html | 604 + .../asmjit/codeholder.cpp.func-sort-c.html | 172 + coverage-libs/asmjit/codeholder.cpp.func.html | 172 + coverage-libs/asmjit/codeholder.cpp.gcov.html | 799 + .../asmjit/codeholder.h.func-sort-c.html | 72 + coverage-libs/asmjit/codeholder.h.func.html | 72 + coverage-libs/asmjit/codeholder.h.gcov.html | 853 + .../asmjit/constpool.cpp.func-sort-c.html | 104 + coverage-libs/asmjit/constpool.cpp.func.html | 104 + coverage-libs/asmjit/constpool.cpp.gcov.html | 613 + .../asmjit/constpool.h.func-sort-c.html | 72 + coverage-libs/asmjit/constpool.h.func.html | 72 + coverage-libs/asmjit/constpool.h.gcov.html | 362 + .../asmjit/cpuinfo.cpp.func-sort-c.html | 84 + coverage-libs/asmjit/cpuinfo.cpp.func.html | 84 + coverage-libs/asmjit/cpuinfo.cpp.gcov.html | 776 + .../asmjit/cpuinfo.h.func-sort-c.html | 72 + coverage-libs/asmjit/cpuinfo.h.func.html | 72 + coverage-libs/asmjit/cpuinfo.h.gcov.html | 478 + .../asmjit/func.cpp.func-sort-c.html | 100 + coverage-libs/asmjit/func.cpp.func.html | 100 + coverage-libs/asmjit/func.cpp.gcov.html | 288 + coverage-libs/asmjit/func.h.func-sort-c.html | 72 + coverage-libs/asmjit/func.h.func.html | 72 + coverage-libs/asmjit/func.h.gcov.html | 1403 + .../asmjit/globals.cpp.func-sort-c.html | 84 + coverage-libs/asmjit/globals.cpp.func.html | 84 + coverage-libs/asmjit/globals.cpp.gcov.html | 220 + .../asmjit/globals.h.func-sort-c.html | 72 + coverage-libs/asmjit/globals.h.func.html | 72 + coverage-libs/asmjit/globals.h.gcov.html | 446 + coverage-libs/asmjit/index-sort-f.html | 603 + coverage-libs/asmjit/index-sort-l.html | 603 + coverage-libs/asmjit/index.html | 603 + .../asmjit/inst.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/inst.cpp.func.html | 80 + coverage-libs/asmjit/inst.cpp.gcov.html | 179 + coverage-libs/asmjit/inst.h.func-sort-c.html | 72 + coverage-libs/asmjit/inst.h.func.html | 72 + coverage-libs/asmjit/inst.h.gcov.html | 213 + .../asmjit/logging.cpp.func-sort-c.html | 172 + coverage-libs/asmjit/logging.cpp.func.html | 172 + coverage-libs/asmjit/logging.cpp.gcov.html | 600 + .../asmjit/logging.h.func-sort-c.html | 72 + coverage-libs/asmjit/logging.h.func.html | 72 + coverage-libs/asmjit/logging.h.gcov.html | 393 + .../asmjit/moved_string.h.func-sort-c.html | 72 + coverage-libs/asmjit/moved_string.h.func.html | 72 + coverage-libs/asmjit/moved_string.h.gcov.html | 394 + .../asmjit/operand.h.func-sort-c.html | 72 + coverage-libs/asmjit/operand.h.func.html | 72 + coverage-libs/asmjit/operand.h.gcov.html | 1675 + .../asmjit/osutils.cpp.func-sort-c.html | 92 + coverage-libs/asmjit/osutils.cpp.func.html | 92 + coverage-libs/asmjit/osutils.cpp.gcov.html | 330 + .../asmjit/osutils.h.func-sort-c.html | 72 + coverage-libs/asmjit/osutils.h.func.html | 72 + coverage-libs/asmjit/osutils.h.gcov.html | 283 + .../asmjit/regalloc.cpp.func-sort-c.html | 124 + coverage-libs/asmjit/regalloc.cpp.func.html | 124 + coverage-libs/asmjit/regalloc.cpp.gcov.html | 696 + .../asmjit/regalloc_p.h.func-sort-c.html | 72 + coverage-libs/asmjit/regalloc_p.h.func.html | 72 + coverage-libs/asmjit/regalloc_p.h.gcov.html | 673 + .../asmjit/runtime.cpp.func-sort-c.html | 120 + coverage-libs/asmjit/runtime.cpp.func.html | 120 + coverage-libs/asmjit/runtime.cpp.gcov.html | 249 + .../asmjit/runtime.h.func-sort-c.html | 72 + coverage-libs/asmjit/runtime.h.func.html | 72 + coverage-libs/asmjit/runtime.h.gcov.html | 303 + .../asmjit/string.cpp.func-sort-c.html | 128 + coverage-libs/asmjit/string.cpp.func.html | 128 + coverage-libs/asmjit/string.cpp.gcov.html | 455 + coverage-libs/asmjit/utils.h.func-sort-c.html | 72 + coverage-libs/asmjit/utils.h.func.html | 72 + coverage-libs/asmjit/utils.h.gcov.html | 1463 + .../asmjit/vmem.cpp.func-sort-c.html | 128 + coverage-libs/asmjit/vmem.cpp.func.html | 128 + coverage-libs/asmjit/vmem.cpp.gcov.html | 1179 + .../asmjit/x86assembler.cpp.func-sort-c.html | 100 + .../asmjit/x86assembler.cpp.func.html | 100 + .../asmjit/x86assembler.cpp.gcov.html | 4721 +++ .../asmjit/x86assembler.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86assembler.h.func.html | 72 + coverage-libs/asmjit/x86assembler.h.gcov.html | 201 + .../asmjit/x86builder.cpp.func-sort-c.html | 92 + coverage-libs/asmjit/x86builder.cpp.func.html | 92 + coverage-libs/asmjit/x86builder.cpp.gcov.html | 168 + .../asmjit/x86compiler.cpp.func-sort-c.html | 100 + .../asmjit/x86compiler.cpp.func.html | 100 + .../asmjit/x86compiler.cpp.gcov.html | 478 + .../asmjit/x86compiler.h.func-sort-c.html | 80 + coverage-libs/asmjit/x86compiler.h.func.html | 80 + coverage-libs/asmjit/x86compiler.h.gcov.html | 398 + .../asmjit/x86emitter.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86emitter.h.func.html | 72 + coverage-libs/asmjit/x86emitter.h.gcov.html | 5225 +++ .../asmjit/x86inst.cpp.func-sort-c.html | 80 + coverage-libs/asmjit/x86inst.cpp.func.html | 80 + coverage-libs/asmjit/x86inst.cpp.gcov.html | 3829 ++ .../asmjit/x86inst.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86inst.h.func.html | 72 + coverage-libs/asmjit/x86inst.h.gcov.html | 2623 ++ .../asmjit/x86instimpl.cpp.func-sort-c.html | 84 + .../asmjit/x86instimpl.cpp.func.html | 84 + .../asmjit/x86instimpl.cpp.gcov.html | 833 + .../asmjit/x86internal.cpp.func-sort-c.html | 128 + .../asmjit/x86internal.cpp.func.html | 128 + .../asmjit/x86internal.cpp.gcov.html | 1458 + .../asmjit/x86logging.cpp.func-sort-c.html | 104 + coverage-libs/asmjit/x86logging.cpp.func.html | 104 + coverage-libs/asmjit/x86logging.cpp.gcov.html | 786 + .../asmjit/x86misc.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86misc.h.func.html | 72 + coverage-libs/asmjit/x86misc.h.gcov.html | 493 + .../asmjit/x86operand.h.func-sort-c.html | 72 + coverage-libs/asmjit/x86operand.h.func.html | 72 + coverage-libs/asmjit/x86operand.h.gcov.html | 1209 + .../asmjit/x86regalloc.cpp.func-sort-c.html | 188 + .../asmjit/x86regalloc.cpp.func.html | 188 + .../asmjit/x86regalloc.cpp.gcov.html | 4164 +++ .../asmjit/x86regalloc_p.h.func-sort-c.html | 72 + .../asmjit/x86regalloc_p.h.func.html | 72 + .../asmjit/x86regalloc_p.h.gcov.html | 810 + .../asmjit/zone.cpp.func-sort-c.html | 160 + coverage-libs/asmjit/zone.cpp.func.html | 160 + coverage-libs/asmjit/zone.cpp.gcov.html | 935 + coverage-libs/asmjit/zone.h.func-sort-c.html | 80 + coverage-libs/asmjit/zone.h.func.html | 80 + coverage-libs/asmjit/zone.h.gcov.html | 1233 + coverage-libs/blas/blas.cpp.func-sort-c.html | 216 + coverage-libs/blas/blas.cpp.func.html | 216 + coverage-libs/blas/blas.cpp.gcov.html | 3766 ++ coverage-libs/blas/index-sort-f.html | 93 + coverage-libs/blas/index-sort-l.html | 93 + coverage-libs/blas/index.html | 93 + 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 | 143 + coverage-libs/index-sort-l.html | 143 + coverage-libs/index.html | 143 + coverage-libs/lapack/index-sort-f.html | 93 + coverage-libs/lapack/index-sort-l.html | 93 + coverage-libs/lapack/index.html | 93 + .../lapack/lapack.cpp.func-sort-c.html | 796 + coverage-libs/lapack/lapack.cpp.func.html | 796 + coverage-libs/lapack/lapack.cpp.gcov.html | 31099 ++++++++++++++++ .../CompiledExpression.cpp.func-sort-c.html | 148 + .../lepton/CompiledExpression.cpp.func.html | 148 + .../lepton/CompiledExpression.cpp.gcov.html | 585 + .../CompiledExpression.h.func-sort-c.html | 72 + .../lepton/CompiledExpression.h.func.html | 72 + .../lepton/CompiledExpression.h.gcov.html | 240 + .../lepton/Exception.h.func-sort-c.html | 88 + coverage-libs/lepton/Exception.h.func.html | 88 + coverage-libs/lepton/Exception.h.gcov.html | 169 + .../ExpressionProgram.cpp.func-sort-c.html | 120 + .../lepton/ExpressionProgram.cpp.func.html | 120 + .../lepton/ExpressionProgram.cpp.gcov.html | 220 + .../ExpressionTreeNode.cpp.func-sort-c.html | 132 + .../lepton/ExpressionTreeNode.cpp.func.html | 132 + .../lepton/ExpressionTreeNode.cpp.gcov.html | 263 + .../lepton/Operation.cpp.func-sort-c.html | 300 + coverage-libs/lepton/Operation.cpp.func.html | 300 + coverage-libs/lepton/Operation.cpp.gcov.html | 746 + .../lepton/Operation.h.func-sort-c.html | 1232 + coverage-libs/lepton/Operation.h.func.html | 1232 + coverage-libs/lepton/Operation.h.gcov.html | 1378 + .../ParsedExpression.cpp.func-sort-c.html | 156 + .../lepton/ParsedExpression.cpp.func.html | 156 + .../lepton/ParsedExpression.cpp.gcov.html | 527 + .../ParsedExpression.h.func-sort-c.html | 72 + .../lepton/ParsedExpression.h.func.html | 72 + .../lepton/ParsedExpression.h.gcov.html | 241 + .../lepton/Parser.cpp.func-sort-c.html | 112 + coverage-libs/lepton/Parser.cpp.func.html | 112 + coverage-libs/lepton/Parser.cpp.gcov.html | 584 + coverage-libs/lepton/index-sort-f.html | 183 + coverage-libs/lepton/index-sort-l.html | 183 + coverage-libs/lepton/index.html | 183 + .../molfile/Gromacs.h.func-sort-c.html | 216 + coverage-libs/molfile/Gromacs.h.func.html | 216 + coverage-libs/molfile/Gromacs.h.gcov.html | 2089 ++ .../molfile/crdplugin.cpp.func-sort-c.html | 108 + coverage-libs/molfile/crdplugin.cpp.func.html | 108 + coverage-libs/molfile/crdplugin.cpp.gcov.html | 338 + .../molfile/dcdplugin.cpp.func-sort-c.html | 148 + coverage-libs/molfile/dcdplugin.cpp.func.html | 148 + coverage-libs/molfile/dcdplugin.cpp.gcov.html | 1393 + .../molfile/endianswap.h.func-sort-c.html | 88 + coverage-libs/molfile/endianswap.h.func.html | 88 + coverage-libs/molfile/endianswap.h.gcov.html | 293 + .../molfile/fastio.h.func-sort-c.html | 100 + coverage-libs/molfile/fastio.h.func.html | 100 + coverage-libs/molfile/fastio.h.gcov.html | 759 + .../gromacsplugin.cpp.func-sort-c.html | 164 + .../molfile/gromacsplugin.cpp.func.html | 164 + .../molfile/gromacsplugin.cpp.gcov.html | 936 + coverage-libs/molfile/index-sort-f.html | 173 + coverage-libs/molfile/index-sort-l.html | 173 + coverage-libs/molfile/index.html | 173 + .../molfile/pdbplugin.cpp.func-sort-c.html | 128 + coverage-libs/molfile/pdbplugin.cpp.func.html | 128 + coverage-libs/molfile/pdbplugin.cpp.gcov.html | 724 + .../molfile/periodic_table.h.func-sort-c.html | 88 + .../molfile/periodic_table.h.func.html | 88 + .../molfile/periodic_table.h.gcov.html | 324 + .../molfile/readpdb.h.func-sort-c.html | 104 + coverage-libs/molfile/readpdb.h.func.html | 104 + coverage-libs/molfile/readpdb.h.gcov.html | 523 + 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 | 113 + coverage-libs/xdrfile/index-sort-l.html | 113 + coverage-libs/xdrfile/index.html | 113 + .../xdrfile/xdrfile.cpp.func-sort-c.html | 396 + coverage-libs/xdrfile/xdrfile.cpp.func.html | 396 + coverage-libs/xdrfile/xdrfile.cpp.gcov.html | 2724 ++ .../xdrfile/xdrfile_trr.cpp.func-sort-c.html | 100 + .../xdrfile/xdrfile_trr.cpp.func.html | 100 + .../xdrfile/xdrfile_trr.cpp.gcov.html | 605 + .../xdrfile/xdrfile_xtc.cpp.func-sort-c.html | 92 + .../xdrfile/xdrfile_xtc.cpp.func.html | 92 + .../xdrfile/xdrfile_xtc.cpp.gcov.html | 241 + ...ActionWithInputMatrix.cpp.func-sort-c.html | 136 + .../ActionWithInputMatrix.cpp.func.html | 136 + .../ActionWithInputMatrix.cpp.gcov.html | 230 + .../ActionWithInputMatrix.h.func-sort-c.html | 80 + .../adjmat/ActionWithInputMatrix.h.func.html | 80 + .../adjmat/ActionWithInputMatrix.h.gcov.html | 148 + .../AdjacencyMatrixBase.cpp.func-sort-c.html | 116 + .../adjmat/AdjacencyMatrixBase.cpp.func.html | 116 + .../adjmat/AdjacencyMatrixBase.cpp.gcov.html | 273 + .../AdjacencyMatrixBase.h.func-sort-c.html | 80 + .../adjmat/AdjacencyMatrixBase.h.func.html | 80 + .../adjmat/AdjacencyMatrixBase.h.gcov.html | 181 + ...AdjacencyMatrixVessel.cpp.func-sort-c.html | 132 + .../AdjacencyMatrixVessel.cpp.func.html | 132 + .../AdjacencyMatrixVessel.cpp.gcov.html | 230 + .../AlignedMatrixBase.cpp.func-sort-c.html | 96 + .../adjmat/AlignedMatrixBase.cpp.func.html | 96 + .../adjmat/AlignedMatrixBase.cpp.gcov.html | 193 + .../ClusterAnalysisBase.cpp.func-sort-c.html | 132 + .../adjmat/ClusterAnalysisBase.cpp.func.html | 132 + .../adjmat/ClusterAnalysisBase.cpp.gcov.html | 182 + .../ClusterAnalysisBase.h.func-sort-c.html | 76 + .../adjmat/ClusterAnalysisBase.h.func.html | 76 + .../adjmat/ClusterAnalysisBase.h.gcov.html | 136 + .../ClusterDiameter.cpp.func-sort-c.html | 108 + coverage/adjmat/ClusterDiameter.cpp.func.html | 108 + coverage/adjmat/ClusterDiameter.cpp.gcov.html | 206 + .../ClusterDistribution.cpp.func-sort-c.html | 104 + .../adjmat/ClusterDistribution.cpp.func.html | 104 + .../adjmat/ClusterDistribution.cpp.gcov.html | 236 + .../ClusterProperties.cpp.func-sort-c.html | 104 + .../adjmat/ClusterProperties.cpp.func.html | 104 + .../adjmat/ClusterProperties.cpp.gcov.html | 197 + .../adjmat/ClusterSize.cpp.func-sort-c.html | 108 + coverage/adjmat/ClusterSize.cpp.func.html | 108 + coverage/adjmat/ClusterSize.cpp.gcov.html | 189 + .../ClusterWithSurface.cpp.func-sort-c.html | 136 + .../adjmat/ClusterWithSurface.cpp.func.html | 136 + .../adjmat/ClusterWithSurface.cpp.gcov.html | 269 + .../ClusteringBase.cpp.func-sort-c.html | 104 + coverage/adjmat/ClusteringBase.cpp.func.html | 104 + coverage/adjmat/ClusteringBase.cpp.gcov.html | 159 + .../adjmat/ClusteringBase.h.func-sort-c.html | 76 + coverage/adjmat/ClusteringBase.h.func.html | 76 + coverage/adjmat/ClusteringBase.h.gcov.html | 146 + .../ContactAlignedMatrix.cpp.func-sort-c.html | 104 + .../adjmat/ContactAlignedMatrix.cpp.func.html | 104 + .../adjmat/ContactAlignedMatrix.cpp.gcov.html | 199 + .../adjmat/ContactMatrix.cpp.func-sort-c.html | 108 + coverage/adjmat/ContactMatrix.cpp.func.html | 108 + coverage/adjmat/ContactMatrix.cpp.gcov.html | 226 + .../adjmat/DFSClustering.cpp.func-sort-c.html | 104 + coverage/adjmat/DFSClustering.cpp.func.html | 104 + coverage/adjmat/DFSClustering.cpp.gcov.html | 237 + .../adjmat/DumpGraph.cpp.func-sort-c.html | 108 + coverage/adjmat/DumpGraph.cpp.func.html | 108 + coverage/adjmat/DumpGraph.cpp.gcov.html | 190 + .../adjmat/HbondMatrix.cpp.func-sort-c.html | 112 + coverage/adjmat/HbondMatrix.cpp.func.html | 112 + coverage/adjmat/HbondMatrix.cpp.gcov.html | 308 + .../MatrixColumnSums.cpp.func-sort-c.html | 100 + .../adjmat/MatrixColumnSums.cpp.func.html | 100 + .../adjmat/MatrixColumnSums.cpp.gcov.html | 198 + .../adjmat/MatrixRowSums.cpp.func-sort-c.html | 100 + coverage/adjmat/MatrixRowSums.cpp.func.html | 100 + coverage/adjmat/MatrixRowSums.cpp.gcov.html | 184 + .../adjmat/OutputCluster.cpp.func-sort-c.html | 116 + coverage/adjmat/OutputCluster.cpp.func.html | 116 + coverage/adjmat/OutputCluster.cpp.gcov.html | 309 + .../adjmat/SMACMatrix.cpp.func-sort-c.html | 104 + coverage/adjmat/SMACMatrix.cpp.func.html | 104 + coverage/adjmat/SMACMatrix.cpp.gcov.html | 231 + coverage/adjmat/Sprint.cpp.func-sort-c.html | 104 + coverage/adjmat/Sprint.cpp.func.html | 104 + coverage/adjmat/Sprint.cpp.gcov.html | 317 + .../TopologyMatrix.cpp.func-sort-c.html | 116 + coverage/adjmat/TopologyMatrix.cpp.func.html | 116 + coverage/adjmat/TopologyMatrix.cpp.gcov.html | 400 + coverage/adjmat/index-sort-f.html | 343 + coverage/adjmat/index-sort-l.html | 343 + coverage/adjmat/index.html | 343 + coverage/amber.png | Bin 0 -> 141 bytes .../AnalysisBase.cpp.func-sort-c.html | 96 + coverage/analysis/AnalysisBase.cpp.func.html | 96 + coverage/analysis/AnalysisBase.cpp.gcov.html | 158 + .../analysis/AnalysisBase.h.func-sort-c.html | 148 + coverage/analysis/AnalysisBase.h.func.html | 148 + coverage/analysis/AnalysisBase.h.gcov.html | 256 + .../analysis/Average.cpp.func-sort-c.html | 124 + coverage/analysis/Average.cpp.func.html | 124 + coverage/analysis/Average.cpp.gcov.html | 226 + .../AverageVessel.cpp.func-sort-c.html | 96 + coverage/analysis/AverageVessel.cpp.func.html | 96 + coverage/analysis/AverageVessel.cpp.gcov.html | 139 + .../analysis/AverageVessel.h.func-sort-c.html | 76 + coverage/analysis/AverageVessel.h.func.html | 76 + coverage/analysis/AverageVessel.h.gcov.html | 127 + .../analysis/Committor.cpp.func-sort-c.html | 104 + coverage/analysis/Committor.cpp.func.html | 104 + coverage/analysis/Committor.cpp.gcov.html | 267 + .../DataCollectionObject.cpp.func-sort-c.html | 88 + .../DataCollectionObject.cpp.func.html | 88 + .../DataCollectionObject.cpp.gcov.html | 139 + .../DataCollectionObject.h.func-sort-c.html | 76 + .../analysis/DataCollectionObject.h.func.html | 76 + .../analysis/DataCollectionObject.h.gcov.html | 155 + ...anDissimilarityMatrix.cpp.func-sort-c.html | 116 + ...EuclideanDissimilarityMatrix.cpp.func.html | 116 + ...EuclideanDissimilarityMatrix.cpp.gcov.html | 222 + ...FarthestPointSampling.cpp.func-sort-c.html | 100 + .../FarthestPointSampling.cpp.func.html | 100 + .../FarthestPointSampling.cpp.gcov.html | 167 + .../analysis/Histogram.cpp.func-sort-c.html | 136 + coverage/analysis/Histogram.cpp.func.html | 136 + coverage/analysis/Histogram.cpp.gcov.html | 610 + ...LandmarkSelectionBase.cpp.func-sort-c.html | 96 + .../LandmarkSelectionBase.cpp.func.html | 96 + .../LandmarkSelectionBase.cpp.gcov.html | 162 + .../LandmarkSelectionBase.h.func-sort-c.html | 96 + .../LandmarkSelectionBase.h.func.html | 96 + .../LandmarkSelectionBase.h.gcov.html | 169 + .../LandmarkStaged.cpp.func-sort-c.html | 100 + .../analysis/LandmarkStaged.cpp.func.html | 100 + .../analysis/LandmarkStaged.cpp.gcov.html | 211 + .../OutputColvarFile.cpp.func-sort-c.html | 104 + .../analysis/OutputColvarFile.cpp.func.html | 104 + .../analysis/OutputColvarFile.cpp.gcov.html | 202 + .../OutputPDBFile.cpp.func-sort-c.html | 104 + coverage/analysis/OutputPDBFile.cpp.func.html | 104 + coverage/analysis/OutputPDBFile.cpp.gcov.html | 176 + ...ntDissimilarityMatrix.cpp.func-sort-c.html | 104 + .../PrintDissimilarityMatrix.cpp.func.html | 104 + .../PrintDissimilarityMatrix.cpp.gcov.html | 158 + .../ReadAnalysisFrames.cpp.func-sort-c.html | 116 + .../analysis/ReadAnalysisFrames.cpp.func.html | 116 + .../analysis/ReadAnalysisFrames.cpp.gcov.html | 232 + .../ReadAnalysisFrames.h.func-sort-c.html | 100 + .../analysis/ReadAnalysisFrames.h.func.html | 100 + .../analysis/ReadAnalysisFrames.h.gcov.html | 182 + ...adDissimilarityMatrix.cpp.func-sort-c.html | 136 + .../ReadDissimilarityMatrix.cpp.func.html | 136 + .../ReadDissimilarityMatrix.cpp.gcov.html | 241 + .../ReselectLandmarks.cpp.func-sort-c.html | 100 + .../analysis/ReselectLandmarks.cpp.func.html | 100 + .../analysis/ReselectLandmarks.cpp.gcov.html | 150 + .../SelectRandomFrames.cpp.func-sort-c.html | 100 + .../analysis/SelectRandomFrames.cpp.func.html | 100 + .../analysis/SelectRandomFrames.cpp.gcov.html | 156 + .../SelectWithStride.cpp.func-sort-c.html | 100 + .../analysis/SelectWithStride.cpp.func.html | 100 + .../analysis/SelectWithStride.cpp.gcov.html | 138 + .../WhamHistogram.cpp.func-sort-c.html | 96 + coverage/analysis/WhamHistogram.cpp.func.html | 96 + coverage/analysis/WhamHistogram.cpp.gcov.html | 198 + .../analysis/WhamWeights.cpp.func-sort-c.html | 96 + coverage/analysis/WhamWeights.cpp.func.html | 96 + coverage/analysis/WhamWeights.cpp.gcov.html | 183 + coverage/analysis/index-sort-f.html | 333 + coverage/analysis/index-sort-l.html | 333 + coverage/analysis/index.html | 333 + coverage/annfunc/ANN.cpp.func-sort-c.html | 108 + coverage/annfunc/ANN.cpp.func.html | 108 + coverage/annfunc/ANN.cpp.gcov.html | 473 + coverage/annfunc/index-sort-f.html | 93 + coverage/annfunc/index-sort-l.html | 93 + coverage/annfunc/index.html | 93 + coverage/bias/ABMD.cpp.func-sort-c.html | 100 + coverage/bias/ABMD.cpp.func.html | 100 + coverage/bias/ABMD.cpp.gcov.html | 262 + coverage/bias/Bias.cpp.func-sort-c.html | 88 + coverage/bias/Bias.cpp.func.html | 88 + coverage/bias/Bias.cpp.gcov.html | 170 + coverage/bias/Bias.h.func-sort-c.html | 76 + coverage/bias/Bias.h.func.html | 76 + coverage/bias/Bias.h.gcov.html | 157 + coverage/bias/BiasValue.cpp.func-sort-c.html | 100 + coverage/bias/BiasValue.cpp.func.html | 100 + coverage/bias/BiasValue.cpp.gcov.html | 193 + .../ExtendedLagrangian.cpp.func-sort-c.html | 104 + .../bias/ExtendedLagrangian.cpp.func.html | 104 + .../bias/ExtendedLagrangian.cpp.gcov.html | 343 + coverage/bias/External.cpp.func-sort-c.html | 100 + coverage/bias/External.cpp.func.html | 100 + coverage/bias/External.cpp.gcov.html | 256 + coverage/bias/LWalls.cpp.func-sort-c.html | 100 + coverage/bias/LWalls.cpp.func.html | 100 + coverage/bias/LWalls.cpp.gcov.html | 224 + coverage/bias/MaxEnt.cpp.func-sort-c.html | 128 + coverage/bias/MaxEnt.cpp.func.html | 128 + coverage/bias/MaxEnt.cpp.gcov.html | 564 + coverage/bias/MetaD.cpp.func-sort-c.html | 196 + coverage/bias/MetaD.cpp.func.html | 196 + coverage/bias/MetaD.cpp.gcov.html | 2395 ++ .../bias/MovingRestraint.cpp.func-sort-c.html | 100 + coverage/bias/MovingRestraint.cpp.func.html | 100 + coverage/bias/MovingRestraint.cpp.gcov.html | 342 + coverage/bias/PBMetaD.cpp.func-sort-c.html | 144 + coverage/bias/PBMetaD.cpp.func.html | 144 + coverage/bias/PBMetaD.cpp.gcov.html | 1396 + coverage/bias/Restraint.cpp.func-sort-c.html | 100 + coverage/bias/Restraint.cpp.func.html | 100 + coverage/bias/Restraint.cpp.gcov.html | 203 + .../bias/ReweightBase.cpp.func-sort-c.html | 88 + coverage/bias/ReweightBase.cpp.func.html | 88 + coverage/bias/ReweightBase.cpp.gcov.html | 133 + coverage/bias/ReweightBase.h.func-sort-c.html | 96 + coverage/bias/ReweightBase.h.func.html | 96 + coverage/bias/ReweightBase.h.gcov.html | 129 + .../bias/ReweightBias.cpp.func-sort-c.html | 100 + coverage/bias/ReweightBias.cpp.func.html | 100 + coverage/bias/ReweightBias.cpp.gcov.html | 174 + .../bias/ReweightMetad.cpp.func-sort-c.html | 100 + coverage/bias/ReweightMetad.cpp.func.html | 100 + coverage/bias/ReweightMetad.cpp.gcov.html | 171 + ...htTemperaturePressure.cpp.func-sort-c.html | 100 + .../ReweightTemperaturePressure.cpp.func.html | 100 + .../ReweightTemperaturePressure.cpp.gcov.html | 342 + .../bias/ReweightWham.cpp.func-sort-c.html | 116 + coverage/bias/ReweightWham.cpp.func.html | 116 + coverage/bias/ReweightWham.cpp.gcov.html | 253 + coverage/bias/UWalls.cpp.func-sort-c.html | 100 + coverage/bias/UWalls.cpp.func.html | 100 + coverage/bias/UWalls.cpp.gcov.html | 223 + coverage/bias/index-sort-f.html | 273 + coverage/bias/index-sort-l.html | 273 + coverage/bias/index.html | 273 + .../cltools/Completion.cpp.func-sort-c.html | 100 + coverage/cltools/Completion.cpp.func.html | 100 + coverage/cltools/Completion.cpp.gcov.html | 211 + coverage/cltools/Driver.cpp.func-sort-c.html | 120 + coverage/cltools/Driver.cpp.func.html | 120 + coverage/cltools/Driver.cpp.gcov.html | 1248 + .../cltools/DriverDouble.cpp.func-sort-c.html | 84 + coverage/cltools/DriverDouble.cpp.func.html | 84 + coverage/cltools/DriverDouble.cpp.gcov.html | 113 + .../cltools/DriverFloat.cpp.func-sort-c.html | 88 + coverage/cltools/DriverFloat.cpp.func.html | 88 + coverage/cltools/DriverFloat.cpp.gcov.html | 118 + .../cltools/GenExample.cpp.func-sort-c.html | 108 + coverage/cltools/GenExample.cpp.func.html | 108 + coverage/cltools/GenExample.cpp.gcov.html | 426 + coverage/cltools/GenJson.cpp.func-sort-c.html | 100 + coverage/cltools/GenJson.cpp.func.html | 100 + coverage/cltools/GenJson.cpp.gcov.html | 257 + .../cltools/GenTemplate.cpp.func-sort-c.html | 100 + coverage/cltools/GenTemplate.cpp.func.html | 100 + coverage/cltools/GenTemplate.cpp.gcov.html | 178 + coverage/cltools/Info.cpp.func-sort-c.html | 100 + coverage/cltools/Info.cpp.func.html | 100 + coverage/cltools/Info.cpp.gcov.html | 199 + coverage/cltools/Manual.cpp.func-sort-c.html | 100 + coverage/cltools/Manual.cpp.func.html | 100 + coverage/cltools/Manual.cpp.gcov.html | 177 + .../cltools/PdbRenumber.cpp.func-sort-c.html | 100 + coverage/cltools/PdbRenumber.cpp.func.html | 100 + coverage/cltools/PdbRenumber.cpp.gcov.html | 274 + .../cltools/SimpleMD.cpp.func-sort-c.html | 152 + coverage/cltools/SimpleMD.cpp.func.html | 152 + coverage/cltools/SimpleMD.cpp.gcov.html | 684 + .../cltools/SumHills.cpp.func-sort-c.html | 104 + coverage/cltools/SumHills.cpp.func.html | 104 + coverage/cltools/SumHills.cpp.gcov.html | 701 + coverage/cltools/index-sort-f.html | 223 + coverage/cltools/index-sort-l.html | 223 + coverage/cltools/index.html | 223 + coverage/cltools/kT.cpp.func-sort-c.html | 100 + coverage/cltools/kT.cpp.func.html | 100 + coverage/cltools/kT.cpp.gcov.html | 163 + coverage/cltools/pesmd.cpp.func-sort-c.html | 100 + coverage/cltools/pesmd.cpp.func.html | 100 + coverage/cltools/pesmd.cpp.gcov.html | 389 + coverage/colvar/Angle.cpp.func-sort-c.html | 100 + coverage/colvar/Angle.cpp.func.html | 100 + coverage/colvar/Angle.cpp.gcov.html | 224 + coverage/colvar/Cell.cpp.func-sort-c.html | 100 + coverage/colvar/Cell.cpp.func.html | 100 + coverage/colvar/Cell.cpp.gcov.html | 185 + coverage/colvar/Constant.cpp.func-sort-c.html | 100 + coverage/colvar/Constant.cpp.func.html | 100 + coverage/colvar/Constant.cpp.gcov.html | 209 + .../colvar/ContactMap.cpp.func-sort-c.html | 104 + coverage/colvar/ContactMap.cpp.func.html | 104 + coverage/colvar/ContactMap.cpp.gcov.html | 402 + .../colvar/Coordination.cpp.func-sort-c.html | 100 + coverage/colvar/Coordination.cpp.func.html | 100 + coverage/colvar/Coordination.cpp.gcov.html | 230 + .../CoordinationBase.cpp.func-sort-c.html | 104 + .../colvar/CoordinationBase.cpp.func.html | 104 + .../colvar/CoordinationBase.cpp.gcov.html | 283 + coverage/colvar/DHEnergy.cpp.func-sort-c.html | 100 + coverage/colvar/DHEnergy.cpp.func.html | 100 + coverage/colvar/DHEnergy.cpp.gcov.html | 220 + coverage/colvar/DRMSD.cpp.func-sort-c.html | 100 + coverage/colvar/DRMSD.cpp.func.html | 100 + coverage/colvar/DRMSD.cpp.gcov.html | 269 + coverage/colvar/Dimer.cpp.func-sort-c.html | 104 + coverage/colvar/Dimer.cpp.func.html | 104 + coverage/colvar/Dimer.cpp.gcov.html | 393 + coverage/colvar/Dipole.cpp.func-sort-c.html | 100 + coverage/colvar/Dipole.cpp.func.html | 100 + coverage/colvar/Dipole.cpp.gcov.html | 234 + coverage/colvar/Distance.cpp.func-sort-c.html | 100 + coverage/colvar/Distance.cpp.func.html | 100 + coverage/colvar/Distance.cpp.gcov.html | 305 + coverage/colvar/EEFSolv.cpp.func-sort-c.html | 116 + coverage/colvar/EEFSolv.cpp.func.html | 116 + coverage/colvar/EEFSolv.cpp.gcov.html | 1252 + coverage/colvar/ERMSD.cpp.func-sort-c.html | 100 + coverage/colvar/ERMSD.cpp.func.html | 100 + coverage/colvar/ERMSD.cpp.gcov.html | 291 + coverage/colvar/Energy.cpp.func-sort-c.html | 108 + coverage/colvar/Energy.cpp.func.html | 108 + coverage/colvar/Energy.cpp.gcov.html | 192 + coverage/colvar/ExtraCV.cpp.func-sort-c.html | 108 + coverage/colvar/ExtraCV.cpp.func.html | 108 + coverage/colvar/ExtraCV.cpp.gcov.html | 180 + coverage/colvar/Fake.cpp.func-sort-c.html | 100 + coverage/colvar/Fake.cpp.func.html | 100 + coverage/colvar/Fake.cpp.gcov.html | 199 + coverage/colvar/GHBFIX.cpp.func-sort-c.html | 100 + coverage/colvar/GHBFIX.cpp.func.html | 100 + coverage/colvar/GHBFIX.cpp.gcov.html | 294 + coverage/colvar/Gyration.cpp.func-sort-c.html | 100 + coverage/colvar/Gyration.cpp.func.html | 100 + coverage/colvar/Gyration.cpp.gcov.html | 448 + .../colvar/MultiRMSD.cpp.func-sort-c.html | 100 + coverage/colvar/MultiRMSD.cpp.func.html | 100 + coverage/colvar/MultiRMSD.cpp.gcov.html | 286 + coverage/colvar/PCARMSD.cpp.func-sort-c.html | 104 + coverage/colvar/PCARMSD.cpp.func.html | 104 + coverage/colvar/PCARMSD.cpp.gcov.html | 343 + coverage/colvar/PathMSD.cpp.func-sort-c.html | 96 + coverage/colvar/PathMSD.cpp.func.html | 96 + coverage/colvar/PathMSD.cpp.gcov.html | 205 + .../colvar/PathMSDBase.cpp.func-sort-c.html | 104 + coverage/colvar/PathMSDBase.cpp.func.html | 104 + coverage/colvar/PathMSDBase.cpp.gcov.html | 409 + .../colvar/PathMSDBase.h.func-sort-c.html | 72 + coverage/colvar/PathMSDBase.h.func.html | 72 + coverage/colvar/PathMSDBase.h.gcov.html | 177 + coverage/colvar/Position.cpp.func-sort-c.html | 100 + coverage/colvar/Position.cpp.func.html | 100 + coverage/colvar/Position.cpp.gcov.html | 253 + .../ProjectionOnAxis.cpp.func-sort-c.html | 100 + .../colvar/ProjectionOnAxis.cpp.func.html | 100 + .../colvar/ProjectionOnAxis.cpp.gcov.html | 245 + .../colvar/PropertyMap.cpp.func-sort-c.html | 96 + coverage/colvar/PropertyMap.cpp.func.html | 96 + coverage/colvar/PropertyMap.cpp.gcov.html | 228 + .../colvar/Puckering.cpp.func-sort-c.html | 108 + coverage/colvar/Puckering.cpp.func.html | 108 + coverage/colvar/Puckering.cpp.gcov.html | 496 + coverage/colvar/RMSD.cpp.func-sort-c.html | 100 + coverage/colvar/RMSD.cpp.func.html | 100 + coverage/colvar/RMSD.cpp.gcov.html | 314 + coverage/colvar/Template.cpp.func-sort-c.html | 100 + coverage/colvar/Template.cpp.func.html | 100 + coverage/colvar/Template.cpp.gcov.html | 190 + coverage/colvar/Torsion.cpp.func-sort-c.html | 100 + coverage/colvar/Torsion.cpp.func.html | 100 + coverage/colvar/Torsion.cpp.gcov.html | 271 + coverage/colvar/Volume.cpp.func-sort-c.html | 100 + coverage/colvar/Volume.cpp.func.html | 100 + coverage/colvar/Volume.cpp.gcov.html | 161 + coverage/colvar/index-sort-f.html | 393 + coverage/colvar/index-sort-l.html | 393 + coverage/colvar/index.html | 393 + coverage/config/Config.inc.func-sort-c.html | 172 + coverage/config/Config.inc.func.html | 172 + coverage/config/Config.inc.gcov.html | 276 + .../config/ConfigInstall.inc.func-sort-c.html | 172 + coverage/config/ConfigInstall.inc.func.html | 172 + coverage/config/ConfigInstall.inc.gcov.html | 276 + coverage/config/index-sort-f.html | 103 + coverage/config/index-sort-l.html | 103 + coverage/config/index.html | 103 + coverage/core/Action.cpp.func-sort-c.html | 192 + coverage/core/Action.cpp.func.html | 192 + coverage/core/Action.cpp.gcov.html | 355 + coverage/core/Action.h.func-sort-c.html | 176 + coverage/core/Action.h.func.html | 176 + coverage/core/Action.h.gcov.html | 506 + .../core/ActionAnyorder.cpp.func-sort-c.html | 84 + coverage/core/ActionAnyorder.cpp.func.html | 84 + coverage/core/ActionAnyorder.cpp.gcov.html | 114 + .../core/ActionAnyorder.h.func-sort-c.html | 80 + coverage/core/ActionAnyorder.h.func.html | 80 + coverage/core/ActionAnyorder.h.gcov.html | 124 + .../core/ActionAtomistic.cpp.func-sort-c.html | 160 + coverage/core/ActionAtomistic.cpp.func.html | 160 + coverage/core/ActionAtomistic.cpp.gcov.html | 383 + .../core/ActionAtomistic.h.func-sort-c.html | 88 + coverage/core/ActionAtomistic.h.func.html | 88 + coverage/core/ActionAtomistic.h.gcov.html | 397 + .../core/ActionPilot.cpp.func-sort-c.html | 96 + coverage/core/ActionPilot.cpp.func.html | 96 + coverage/core/ActionPilot.cpp.gcov.html | 131 + coverage/core/ActionPilot.h.func-sort-c.html | 72 + coverage/core/ActionPilot.h.func.html | 72 + coverage/core/ActionPilot.h.gcov.html | 134 + .../core/ActionRegister.cpp.func-sort-c.html | 116 + coverage/core/ActionRegister.cpp.func.html | 116 + coverage/core/ActionRegister.cpp.gcov.html | 218 + coverage/core/ActionSet.cpp.func-sort-c.html | 84 + coverage/core/ActionSet.cpp.func.html | 84 + coverage/core/ActionSet.cpp.gcov.html | 118 + coverage/core/ActionSet.h.func-sort-c.html | 172 + coverage/core/ActionSet.h.func.html | 172 + coverage/core/ActionSet.h.gcov.html | 223 + .../core/ActionSetup.cpp.func-sort-c.html | 84 + coverage/core/ActionSetup.cpp.func.html | 84 + coverage/core/ActionSetup.cpp.gcov.html | 121 + coverage/core/ActionSetup.h.func-sort-c.html | 80 + coverage/core/ActionSetup.h.func.html | 80 + coverage/core/ActionSetup.h.gcov.html | 124 + .../core/ActionShortcut.cpp.func-sort-c.html | 96 + coverage/core/ActionShortcut.cpp.func.html | 96 + coverage/core/ActionShortcut.cpp.gcov.html | 143 + .../core/ActionShortcut.h.func-sort-c.html | 80 + coverage/core/ActionShortcut.h.func.html | 80 + coverage/core/ActionShortcut.h.gcov.html | 131 + .../ActionWithArguments.cpp.func-sort-c.html | 120 + .../core/ActionWithArguments.cpp.func.html | 120 + .../core/ActionWithArguments.cpp.gcov.html | 386 + .../ActionWithArguments.h.func-sort-c.html | 92 + coverage/core/ActionWithArguments.h.func.html | 92 + coverage/core/ActionWithArguments.h.gcov.html | 208 + .../core/ActionWithValue.cpp.func-sort-c.html | 192 + coverage/core/ActionWithValue.cpp.func.html | 192 + coverage/core/ActionWithValue.cpp.gcov.html | 309 + .../core/ActionWithValue.h.func-sort-c.html | 100 + coverage/core/ActionWithValue.h.func.html | 100 + coverage/core/ActionWithValue.h.gcov.html | 296 + ...ActionWithVirtualAtom.cpp.func-sort-c.html | 120 + .../core/ActionWithVirtualAtom.cpp.func.html | 120 + .../core/ActionWithVirtualAtom.cpp.gcov.html | 184 + .../ActionWithVirtualAtom.h.func-sort-c.html | 72 + .../core/ActionWithVirtualAtom.h.func.html | 72 + .../core/ActionWithVirtualAtom.h.gcov.html | 196 + coverage/core/Atoms.cpp.func-sort-c.html | 312 + coverage/core/Atoms.cpp.func.html | 312 + coverage/core/Atoms.cpp.gcov.html | 748 + coverage/core/Atoms.h.func-sort-c.html | 80 + coverage/core/Atoms.h.func.html | 80 + coverage/core/Atoms.h.gcov.html | 379 + coverage/core/CLTool.cpp.func-sort-c.html | 112 + coverage/core/CLTool.cpp.func.html | 112 + coverage/core/CLTool.cpp.gcov.html | 292 + coverage/core/CLTool.h.func-sort-c.html | 132 + coverage/core/CLTool.h.func.html | 132 + coverage/core/CLTool.h.gcov.html | 241 + coverage/core/CLToolMain.cpp.func-sort-c.html | 92 + coverage/core/CLToolMain.cpp.func.html | 92 + coverage/core/CLToolMain.cpp.gcov.html | 367 + .../core/CLToolRegister.cpp.func-sort-c.html | 112 + coverage/core/CLToolRegister.cpp.func.html | 112 + coverage/core/CLToolRegister.cpp.gcov.html | 201 + coverage/core/Colvar.cpp.func-sort-c.html | 96 + coverage/core/Colvar.cpp.func.html | 96 + coverage/core/Colvar.cpp.gcov.html | 201 + coverage/core/Colvar.h.func-sort-c.html | 100 + coverage/core/Colvar.h.func.html | 100 + coverage/core/Colvar.h.gcov.html | 195 + .../DataFetchingObject.cpp.func-sort-c.html | 136 + .../core/DataFetchingObject.cpp.func.html | 136 + .../core/DataFetchingObject.cpp.gcov.html | 235 + .../DataFetchingObject.h.func-sort-c.html | 80 + coverage/core/DataFetchingObject.h.func.html | 80 + coverage/core/DataFetchingObject.h.gcov.html | 144 + .../ExchangePatterns.cpp.func-sort-c.html | 100 + coverage/core/ExchangePatterns.cpp.func.html | 100 + coverage/core/ExchangePatterns.cpp.gcov.html | 148 + .../core/FlexibleBin.cpp.func-sort-c.html | 100 + coverage/core/FlexibleBin.cpp.func.html | 100 + coverage/core/FlexibleBin.cpp.gcov.html | 412 + coverage/core/GREX.cpp.func-sort-c.html | 96 + coverage/core/GREX.cpp.func.html | 96 + coverage/core/GREX.cpp.gcov.html | 298 + .../core/GenericMolInfo.cpp.func-sort-c.html | 144 + coverage/core/GenericMolInfo.cpp.func.html | 144 + coverage/core/GenericMolInfo.cpp.gcov.html | 448 + .../core/GenericMolInfo.h.func-sort-c.html | 80 + coverage/core/GenericMolInfo.h.func.html | 80 + coverage/core/GenericMolInfo.h.gcov.html | 165 + coverage/core/MDAtoms.cpp.func-sort-c.html | 340 + coverage/core/MDAtoms.cpp.func.html | 340 + coverage/core/MDAtoms.cpp.gcov.html | 480 + coverage/core/ModuleMap.cpp.func-sort-c.html | 76 + coverage/core/ModuleMap.cpp.func.html | 76 + coverage/core/ModuleMap.cpp.gcov.html | 107 + coverage/core/PlumedMain.cpp.func-sort-c.html | 240 + coverage/core/PlumedMain.cpp.func.html | 240 + coverage/core/PlumedMain.cpp.gcov.html | 1240 + coverage/core/PlumedMain.h.func-sort-c.html | 72 + coverage/core/PlumedMain.h.func.html | 72 + coverage/core/PlumedMain.h.gcov.html | 623 + ...PlumedMainInitializer.cpp.func-sort-c.html | 136 + .../core/PlumedMainInitializer.cpp.func.html | 136 + .../core/PlumedMainInitializer.cpp.gcov.html | 494 + coverage/core/TargetDist.cpp.func-sort-c.html | 84 + coverage/core/TargetDist.cpp.func.html | 84 + coverage/core/TargetDist.cpp.gcov.html | 147 + coverage/core/Value.cpp.func-sort-c.html | 136 + coverage/core/Value.cpp.func.html | 136 + coverage/core/Value.cpp.gcov.html | 276 + coverage/core/Value.h.func-sort-c.html | 92 + coverage/core/Value.h.func.html | 92 + coverage/core/Value.h.gcov.html | 392 + coverage/core/WithCmd.h.func-sort-c.html | 76 + coverage/core/WithCmd.h.func.html | 76 + coverage/core/WithCmd.h.gcov.html | 129 + coverage/core/index-sort-f.html | 533 + coverage/core/index-sort-l.html | 533 + coverage/core/index.html | 533 + .../BondOrientation.cpp.func-sort-c.html | 104 + .../BondOrientation.cpp.func.html | 104 + .../BondOrientation.cpp.gcov.html | 211 + .../CubicHarmonicBase.cpp.func-sort-c.html | 88 + .../CubicHarmonicBase.cpp.func.html | 88 + .../CubicHarmonicBase.cpp.gcov.html | 226 + .../CubicHarmonicBase.h.func-sort-c.html | 76 + .../CubicHarmonicBase.h.func.html | 76 + .../CubicHarmonicBase.h.gcov.html | 127 + ...EnvironmentSimilarity.cpp.func-sort-c.html | 112 + .../EnvironmentSimilarity.cpp.func.html | 112 + .../EnvironmentSimilarity.cpp.gcov.html | 644 + .../Fccubic.cpp.func-sort-c.html | 100 + .../crystallization/Fccubic.cpp.func.html | 100 + .../crystallization/Fccubic.cpp.gcov.html | 209 + .../Gradient.cpp.func-sort-c.html | 104 + .../crystallization/Gradient.cpp.func.html | 104 + .../crystallization/Gradient.cpp.gcov.html | 243 + .../Gradient.h.func-sort-c.html | 76 + coverage/crystallization/Gradient.h.func.html | 76 + coverage/crystallization/Gradient.h.gcov.html | 135 + .../GradientVessel.cpp.func-sort-c.html | 112 + .../GradientVessel.cpp.func.html | 112 + .../GradientVessel.cpp.gcov.html | 268 + ...nterMolecularTorsions.cpp.func-sort-c.html | 112 + .../InterMolecularTorsions.cpp.func.html | 112 + .../InterMolecularTorsions.cpp.gcov.html | 269 + .../LocalSteinhardt.h.func-sort-c.html | 108 + .../LocalSteinhardt.h.func.html | 108 + .../LocalSteinhardt.h.gcov.html | 138 + .../MoleculeOrientation.cpp.func-sort-c.html | 112 + .../MoleculeOrientation.cpp.func.html | 112 + .../MoleculeOrientation.cpp.gcov.html | 227 + .../MoleculePlane.cpp.func-sort-c.html | 104 + .../MoleculePlane.cpp.func.html | 104 + .../MoleculePlane.cpp.gcov.html | 226 + .../OrientationSphere.cpp.func-sort-c.html | 88 + .../OrientationSphere.cpp.func.html | 88 + .../OrientationSphere.cpp.gcov.html | 207 + .../OrientationSphere.h.func-sort-c.html | 80 + .../OrientationSphere.h.func.html | 80 + .../OrientationSphere.h.gcov.html | 129 + .../PolymerAngles.cpp.func-sort-c.html | 100 + .../PolymerAngles.cpp.func.html | 100 + .../PolymerAngles.cpp.gcov.html | 178 + .../crystallization/Q3.cpp.func-sort-c.html | 108 + coverage/crystallization/Q3.cpp.func.html | 108 + coverage/crystallization/Q3.cpp.gcov.html | 299 + .../crystallization/Q4.cpp.func-sort-c.html | 108 + coverage/crystallization/Q4.cpp.func.html | 108 + coverage/crystallization/Q4.cpp.gcov.html | 291 + .../crystallization/Q6.cpp.func-sort-c.html | 108 + coverage/crystallization/Q6.cpp.func.html | 108 + coverage/crystallization/Q6.cpp.gcov.html | 294 + .../crystallization/SMAC.cpp.func-sort-c.html | 104 + coverage/crystallization/SMAC.cpp.func.html | 104 + coverage/crystallization/SMAC.cpp.gcov.html | 283 + .../SimpleCubic.cpp.func-sort-c.html | 100 + .../crystallization/SimpleCubic.cpp.func.html | 100 + .../crystallization/SimpleCubic.cpp.gcov.html | 192 + .../Steinhardt.cpp.func-sort-c.html | 96 + .../crystallization/Steinhardt.cpp.func.html | 96 + .../crystallization/Steinhardt.cpp.gcov.html | 251 + .../Tetrahedral.cpp.func-sort-c.html | 100 + .../crystallization/Tetrahedral.cpp.func.html | 100 + .../crystallization/Tetrahedral.cpp.gcov.html | 203 + .../VectorMean.cpp.func-sort-c.html | 112 + .../crystallization/VectorMean.cpp.func.html | 112 + .../crystallization/VectorMean.cpp.gcov.html | 189 + .../VectorMultiColvar.cpp.func-sort-c.html | 108 + .../VectorMultiColvar.cpp.func.html | 108 + .../VectorMultiColvar.cpp.gcov.html | 192 + .../VectorMultiColvar.h.func-sort-c.html | 88 + .../VectorMultiColvar.h.func.html | 88 + .../VectorMultiColvar.h.gcov.html | 161 + .../VectorSum.cpp.func-sort-c.html | 112 + .../crystallization/VectorSum.cpp.func.html | 112 + .../crystallization/VectorSum.cpp.gcov.html | 190 + coverage/crystallization/index-sort-f.html | 343 + coverage/crystallization/index-sort-l.html | 343 + coverage/crystallization/index.html | 343 + ...ltiDimensionalScaling.cpp.func-sort-c.html | 100 + ...sicalMultiDimensionalScaling.cpp.func.html | 100 + ...sicalMultiDimensionalScaling.cpp.gcov.html | 286 + ...ionalityReductionBase.cpp.func-sort-c.html | 100 + .../DimensionalityReductionBase.cpp.func.html | 100 + .../DimensionalityReductionBase.cpp.gcov.html | 212 + ...nsionalityReductionBase.h.func-sort-c.html | 80 + .../DimensionalityReductionBase.h.func.html | 80 + .../DimensionalityReductionBase.h.gcov.html | 150 + .../OutputPCAProjections.cpp.func-sort-c.html | 104 + .../dimred/OutputPCAProjections.cpp.func.html | 104 + .../dimred/OutputPCAProjections.cpp.gcov.html | 188 + coverage/dimred/PCA.cpp.func-sort-c.html | 108 + coverage/dimred/PCA.cpp.func.html | 108 + coverage/dimred/PCA.cpp.gcov.html | 354 + coverage/dimred/PCA.h.func-sort-c.html | 84 + coverage/dimred/PCA.h.func.html | 84 + coverage/dimred/PCA.h.gcov.html | 134 + ...jectNonLandmarkPoints.cpp.func-sort-c.html | 120 + .../ProjectNonLandmarkPoints.cpp.func.html | 120 + .../ProjectNonLandmarkPoints.cpp.gcov.html | 213 + coverage/dimred/SMACOF.cpp.func-sort-c.html | 80 + coverage/dimred/SMACOF.cpp.func.html | 80 + coverage/dimred/SMACOF.cpp.gcov.html | 169 + .../dimred/SketchMap.cpp.func-sort-c.html | 96 + coverage/dimred/SketchMap.cpp.func.html | 96 + coverage/dimred/SketchMap.cpp.gcov.html | 181 + .../dimred/SketchMapBase.cpp.func-sort-c.html | 96 + coverage/dimred/SketchMapBase.cpp.func.html | 96 + coverage/dimred/SketchMapBase.cpp.gcov.html | 242 + .../dimred/SketchMapBase.h.func-sort-c.html | 84 + coverage/dimred/SketchMapBase.h.func.html | 84 + coverage/dimred/SketchMapBase.h.gcov.html | 169 + .../SketchMapConjGrad.cpp.func-sort-c.html | 100 + .../dimred/SketchMapConjGrad.cpp.func.html | 100 + .../dimred/SketchMapConjGrad.cpp.gcov.html | 146 + .../SketchMapPointwise.cpp.func-sort-c.html | 100 + .../dimred/SketchMapPointwise.cpp.func.html | 100 + .../dimred/SketchMapPointwise.cpp.gcov.html | 202 + .../dimred/SketchMapRead.cpp.func-sort-c.html | 128 + coverage/dimred/SketchMapRead.cpp.func.html | 128 + coverage/dimred/SketchMapRead.cpp.gcov.html | 273 + .../SketchMapSmacof.cpp.func-sort-c.html | 104 + coverage/dimred/SketchMapSmacof.cpp.func.html | 104 + coverage/dimred/SketchMapSmacof.cpp.gcov.html | 186 + .../dimred/SmacoffMDS.cpp.func-sort-c.html | 100 + coverage/dimred/SmacoffMDS.cpp.func.html | 100 + coverage/dimred/SmacoffMDS.cpp.gcov.html | 158 + coverage/dimred/index-sort-f.html | 243 + coverage/dimred/index-sort-l.html | 243 + coverage/dimred/index.html | 243 + coverage/drr/DRR.cpp.func-sort-c.html | 172 + coverage/drr/DRR.cpp.func.html | 172 + coverage/drr/DRR.cpp.gcov.html | 631 + coverage/drr/DRR.h.func-sort-c.html | 128 + coverage/drr/DRR.h.func.html | 128 + coverage/drr/DRR.h.gcov.html | 434 + ...cReferenceRestraining.cpp.func-sort-c.html | 120 + .../DynamicReferenceRestraining.cpp.func.html | 120 + .../DynamicReferenceRestraining.cpp.gcov.html | 972 + .../drr/colvar_UIestimator.h.func-sort-c.html | 208 + coverage/drr/colvar_UIestimator.h.func.html | 208 + coverage/drr/colvar_UIestimator.h.gcov.html | 931 + coverage/drr/drrtool.cpp.func-sort-c.html | 120 + coverage/drr/drrtool.cpp.func.html | 120 + coverage/drr/drrtool.cpp.gcov.html | 341 + coverage/drr/index-sort-f.html | 133 + coverage/drr/index-sort-l.html | 133 + coverage/drr/index.html | 133 + coverage/eds/EDS.cpp.func-sort-c.html | 164 + coverage/eds/EDS.cpp.func.html | 164 + coverage/eds/EDS.cpp.gcov.html | 1256 + coverage/eds/index-sort-f.html | 93 + coverage/eds/index-sort-l.html | 93 + coverage/eds/index.html | 93 + coverage/emerald.png | Bin 0 -> 141 bytes coverage/fisst/FISST.cpp.func-sort-c.html | 160 + coverage/fisst/FISST.cpp.func.html | 160 + coverage/fisst/FISST.cpp.gcov.html | 738 + coverage/fisst/index-sort-f.html | 103 + coverage/fisst/index-sort-l.html | 103 + coverage/fisst/index.html | 103 + .../legendre_rule_fast.cpp.func-sort-c.html | 100 + .../fisst/legendre_rule_fast.cpp.func.html | 100 + .../fisst/legendre_rule_fast.cpp.gcov.html | 641 + .../function/Combine.cpp.func-sort-c.html | 100 + coverage/function/Combine.cpp.func.html | 100 + coverage/function/Combine.cpp.gcov.html | 232 + coverage/function/Custom.cpp.func-sort-c.html | 112 + coverage/function/Custom.cpp.func.html | 112 + coverage/function/Custom.cpp.gcov.html | 376 + .../function/Ensemble.cpp.func-sort-c.html | 100 + coverage/function/Ensemble.cpp.func.html | 100 + coverage/function/Ensemble.cpp.gcov.html | 342 + .../FuncPathGeneral.cpp.func-sort-c.html | 108 + .../function/FuncPathGeneral.cpp.func.html | 108 + .../function/FuncPathGeneral.cpp.gcov.html | 417 + .../function/FuncPathMSD.cpp.func-sort-c.html | 104 + coverage/function/FuncPathMSD.cpp.func.html | 104 + coverage/function/FuncPathMSD.cpp.gcov.html | 444 + .../FuncSumHills.cpp.func-sort-c.html | 132 + coverage/function/FuncSumHills.cpp.func.html | 132 + coverage/function/FuncSumHills.cpp.gcov.html | 714 + .../function/Function.cpp.func-sort-c.html | 96 + coverage/function/Function.cpp.func.html | 96 + coverage/function/Function.cpp.gcov.html | 178 + coverage/function/Function.h.func-sort-c.html | 84 + coverage/function/Function.h.func.html | 84 + coverage/function/Function.h.gcov.html | 149 + .../LocalEnsemble.cpp.func-sort-c.html | 100 + coverage/function/LocalEnsemble.cpp.func.html | 100 + coverage/function/LocalEnsemble.cpp.gcov.html | 227 + .../function/Piecewise.cpp.func-sort-c.html | 100 + coverage/function/Piecewise.cpp.func.html | 100 + coverage/function/Piecewise.cpp.gcov.html | 234 + coverage/function/Sort.cpp.func-sort-c.html | 100 + coverage/function/Sort.cpp.func.html | 100 + coverage/function/Sort.cpp.gcov.html | 183 + coverage/function/Stats.cpp.func-sort-c.html | 100 + coverage/function/Stats.cpp.func.html | 100 + coverage/function/Stats.cpp.gcov.html | 315 + coverage/function/Target.cpp.func-sort-c.html | 100 + coverage/function/Target.cpp.func.html | 100 + coverage/function/Target.cpp.gcov.html | 237 + coverage/function/index-sort-f.html | 213 + coverage/function/index-sort-l.html | 213 + coverage/function/index.html | 213 + coverage/funnel/FPS.cpp.func-sort-c.html | 100 + coverage/funnel/FPS.cpp.func.html | 100 + coverage/funnel/FPS.cpp.gcov.html | 397 + coverage/funnel/Funnel.cpp.func-sort-c.html | 104 + coverage/funnel/Funnel.cpp.func.html | 104 + coverage/funnel/Funnel.cpp.gcov.html | 528 + coverage/funnel/index-sort-f.html | 103 + coverage/funnel/index-sort-l.html | 103 + coverage/funnel/index.html | 103 + coverage/gcov.css | 519 + coverage/generic/Debug.cpp.func-sort-c.html | 104 + coverage/generic/Debug.cpp.func.html | 104 + coverage/generic/Debug.cpp.gcov.html | 216 + .../generic/DumpAtoms.cpp.func-sort-c.html | 120 + coverage/generic/DumpAtoms.cpp.func.html | 120 + coverage/generic/DumpAtoms.cpp.gcov.html | 390 + .../DumpDerivatives.cpp.func-sort-c.html | 120 + .../generic/DumpDerivatives.cpp.func.html | 120 + .../generic/DumpDerivatives.cpp.gcov.html | 209 + .../generic/DumpForces.cpp.func-sort-c.html | 120 + coverage/generic/DumpForces.cpp.func.html | 120 + coverage/generic/DumpForces.cpp.gcov.html | 195 + .../DumpMassCharge.cpp.func-sort-c.html | 124 + coverage/generic/DumpMassCharge.cpp.func.html | 124 + coverage/generic/DumpMassCharge.cpp.gcov.html | 264 + .../DumpProjections.cpp.func-sort-c.html | 124 + .../generic/DumpProjections.cpp.func.html | 124 + .../generic/DumpProjections.cpp.gcov.html | 196 + .../EffectiveEnergyDrift.cpp.func-sort-c.html | 120 + .../EffectiveEnergyDrift.cpp.func.html | 120 + .../EffectiveEnergyDrift.cpp.gcov.html | 411 + .../generic/EndPlumed.cpp.func-sort-c.html | 100 + coverage/generic/EndPlumed.cpp.func.html | 100 + coverage/generic/EndPlumed.cpp.gcov.html | 156 + .../FitToTemplate.cpp.func-sort-c.html | 108 + coverage/generic/FitToTemplate.cpp.func.html | 108 + coverage/generic/FitToTemplate.cpp.gcov.html | 450 + coverage/generic/Flush.cpp.func-sort-c.html | 104 + coverage/generic/Flush.cpp.func.html | 104 + coverage/generic/Flush.cpp.gcov.html | 167 + coverage/generic/Group.cpp.func-sort-c.html | 116 + coverage/generic/Group.cpp.func.html | 116 + coverage/generic/Group.cpp.gcov.html | 322 + coverage/generic/Include.cpp.func-sort-c.html | 104 + coverage/generic/Include.cpp.func.html | 104 + coverage/generic/Include.cpp.gcov.html | 255 + coverage/generic/MolInfo.cpp.func-sort-c.html | 84 + coverage/generic/MolInfo.cpp.func.html | 84 + coverage/generic/MolInfo.cpp.gcov.html | 345 + coverage/generic/Plumed.cpp.func-sort-c.html | 128 + coverage/generic/Plumed.cpp.func.html | 128 + coverage/generic/Plumed.cpp.gcov.html | 495 + coverage/generic/Print.cpp.func-sort-c.html | 124 + coverage/generic/Print.cpp.func.html | 124 + coverage/generic/Print.cpp.gcov.html | 256 + .../RandomExchanges.cpp.func-sort-c.html | 100 + .../generic/RandomExchanges.cpp.func.html | 100 + .../generic/RandomExchanges.cpp.gcov.html | 178 + coverage/generic/Read.cpp.func-sort-c.html | 128 + coverage/generic/Read.cpp.func.html | 128 + coverage/generic/Read.cpp.gcov.html | 332 + .../generic/ResetCell.cpp.func-sort-c.html | 104 + coverage/generic/ResetCell.cpp.func.html | 104 + coverage/generic/ResetCell.cpp.gcov.html | 274 + coverage/generic/Time.cpp.func-sort-c.html | 108 + coverage/generic/Time.cpp.func.html | 108 + coverage/generic/Time.cpp.gcov.html | 155 + .../generic/UpdateIf.cpp.func-sort-c.html | 124 + coverage/generic/UpdateIf.cpp.func.html | 124 + coverage/generic/UpdateIf.cpp.gcov.html | 234 + .../WholeMolecules.cpp.func-sort-c.html | 104 + coverage/generic/WholeMolecules.cpp.func.html | 104 + coverage/generic/WholeMolecules.cpp.gcov.html | 319 + .../generic/WrapAround.cpp.func-sort-c.html | 104 + coverage/generic/WrapAround.cpp.func.html | 104 + coverage/generic/WrapAround.cpp.gcov.html | 327 + coverage/generic/index-sort-f.html | 303 + coverage/generic/index-sort-l.html | 303 + coverage/generic/index.html | 303 + coverage/glass.png | Bin 0 -> 167 bytes .../ActionWithGrid.cpp.func-sort-c.html | 100 + .../gridtools/ActionWithGrid.cpp.func.html | 100 + .../gridtools/ActionWithGrid.cpp.gcov.html | 186 + .../ActionWithInputGrid.cpp.func-sort-c.html | 96 + .../ActionWithInputGrid.cpp.func.html | 96 + .../ActionWithInputGrid.cpp.gcov.html | 156 + .../ActionWithInputGrid.h.func-sort-c.html | 88 + .../gridtools/ActionWithInputGrid.h.func.html | 88 + .../gridtools/ActionWithInputGrid.h.gcov.html | 145 + .../ActionWithIntegral.cpp.func-sort-c.html | 92 + .../ActionWithIntegral.cpp.func.html | 92 + .../ActionWithIntegral.cpp.gcov.html | 138 + .../ActionWithIntegral.h.func-sort-c.html | 80 + .../gridtools/ActionWithIntegral.h.func.html | 80 + .../gridtools/ActionWithIntegral.h.gcov.html | 136 + .../AverageOnGrid.cpp.func-sort-c.html | 88 + .../gridtools/AverageOnGrid.cpp.func.html | 88 + .../gridtools/AverageOnGrid.cpp.gcov.html | 145 + .../AverageOnGrid.h.func-sort-c.html | 84 + coverage/gridtools/AverageOnGrid.h.func.html | 84 + coverage/gridtools/AverageOnGrid.h.gcov.html | 125 + .../ContourFindingBase.cpp.func-sort-c.html | 84 + .../ContourFindingBase.cpp.func.html | 84 + .../ContourFindingBase.cpp.gcov.html | 120 + .../ContourFindingBase.h.func-sort-c.html | 84 + .../gridtools/ContourFindingBase.h.func.html | 84 + .../gridtools/ContourFindingBase.h.gcov.html | 139 + .../ConvertToFES.cpp.func-sort-c.html | 132 + coverage/gridtools/ConvertToFES.cpp.func.html | 132 + coverage/gridtools/ConvertToFES.cpp.gcov.html | 223 + .../gridtools/DumpCube.cpp.func-sort-c.html | 100 + coverage/gridtools/DumpCube.cpp.func.html | 100 + coverage/gridtools/DumpCube.cpp.gcov.html | 201 + .../gridtools/DumpGrid.cpp.func-sort-c.html | 100 + coverage/gridtools/DumpGrid.cpp.func.html | 100 + coverage/gridtools/DumpGrid.cpp.gcov.html | 272 + .../FindContour.cpp.func-sort-c.html | 120 + coverage/gridtools/FindContour.cpp.func.html | 120 + coverage/gridtools/FindContour.cpp.gcov.html | 323 + .../FindContourSurface.cpp.func-sort-c.html | 120 + .../FindContourSurface.cpp.func.html | 120 + .../FindContourSurface.cpp.gcov.html | 339 + .../FindSphericalContour.cpp.func-sort-c.html | 104 + .../FindSphericalContour.cpp.func.html | 104 + .../FindSphericalContour.cpp.gcov.html | 260 + .../FourierTransform.cpp.func-sort-c.html | 112 + .../gridtools/FourierTransform.cpp.func.html | 112 + .../gridtools/FourierTransform.cpp.gcov.html | 328 + .../GridPrintingBase.cpp.func-sort-c.html | 92 + .../gridtools/GridPrintingBase.cpp.func.html | 92 + .../gridtools/GridPrintingBase.cpp.gcov.html | 181 + .../GridPrintingBase.h.func-sort-c.html | 80 + .../gridtools/GridPrintingBase.h.func.html | 80 + .../gridtools/GridPrintingBase.h.gcov.html | 126 + .../gridtools/GridSearch.h.func-sort-c.html | 80 + coverage/gridtools/GridSearch.h.func.html | 80 + coverage/gridtools/GridSearch.h.gcov.html | 186 + .../gridtools/GridToXYZ.cpp.func-sort-c.html | 100 + coverage/gridtools/GridToXYZ.cpp.func.html | 100 + coverage/gridtools/GridToXYZ.cpp.gcov.html | 186 + .../gridtools/GridVessel.cpp.func-sort-c.html | 228 + coverage/gridtools/GridVessel.cpp.func.html | 228 + coverage/gridtools/GridVessel.cpp.gcov.html | 602 + .../gridtools/GridVessel.h.func-sort-c.html | 104 + coverage/gridtools/GridVessel.h.func.html | 104 + coverage/gridtools/GridVessel.h.gcov.html | 363 + .../HistogramOnGrid.cpp.func-sort-c.html | 120 + .../gridtools/HistogramOnGrid.cpp.func.html | 120 + .../gridtools/HistogramOnGrid.cpp.gcov.html | 291 + .../HistogramOnGrid.h.func-sort-c.html | 76 + .../gridtools/HistogramOnGrid.h.func.html | 76 + .../gridtools/HistogramOnGrid.h.gcov.html | 147 + .../IntegrateGrid.cpp.func-sort-c.html | 100 + .../gridtools/IntegrateGrid.cpp.func.html | 100 + .../gridtools/IntegrateGrid.cpp.gcov.html | 138 + .../InterpolateGrid.cpp.func-sort-c.html | 108 + .../gridtools/InterpolateGrid.cpp.func.html | 108 + .../gridtools/InterpolateGrid.cpp.gcov.html | 187 + coverage/gridtools/index-sort-f.html | 343 + coverage/gridtools/index-sort-l.html | 343 + coverage/gridtools/index.html | 343 + coverage/index-sort-f.html | 473 + coverage/index-sort-l.html | 473 + coverage/index.html | 473 + .../isdb/CS2Backbone.cpp.func-sort-c.html | 176 + coverage/isdb/CS2Backbone.cpp.func.html | 176 + coverage/isdb/CS2Backbone.cpp.gcov.html | 1919 + coverage/isdb/Caliber.cpp.func-sort-c.html | 116 + coverage/isdb/Caliber.cpp.func.html | 116 + coverage/isdb/Caliber.cpp.gcov.html | 423 + coverage/isdb/EMMI.cpp.func-sort-c.html | 240 + coverage/isdb/EMMI.cpp.func.html | 240 + coverage/isdb/EMMI.cpp.gcov.html | 1826 + .../isdb/FretEfficiency.cpp.func-sort-c.html | 100 + coverage/isdb/FretEfficiency.cpp.func.html | 100 + coverage/isdb/FretEfficiency.cpp.gcov.html | 231 + coverage/isdb/Jcoupling.cpp.func-sort-c.html | 104 + coverage/isdb/Jcoupling.cpp.func.html | 104 + coverage/isdb/Jcoupling.cpp.gcov.html | 470 + .../isdb/Metainference.cpp.func-sort-c.html | 192 + coverage/isdb/Metainference.cpp.func.html | 192 + coverage/isdb/Metainference.cpp.gcov.html | 1881 + .../MetainferenceBase.cpp.func-sort-c.html | 184 + coverage/isdb/MetainferenceBase.cpp.func.html | 184 + coverage/isdb/MetainferenceBase.cpp.gcov.html | 1639 + .../isdb/MetainferenceBase.h.func-sort-c.html | 112 + coverage/isdb/MetainferenceBase.h.func.html | 112 + coverage/isdb/MetainferenceBase.h.gcov.html | 461 + coverage/isdb/NOE.cpp.func-sort-c.html | 104 + coverage/isdb/NOE.cpp.func.html | 104 + coverage/isdb/NOE.cpp.gcov.html | 350 + coverage/isdb/PRE.cpp.func-sort-c.html | 104 + coverage/isdb/PRE.cpp.func.html | 104 + coverage/isdb/PRE.cpp.gcov.html | 416 + coverage/isdb/RDC.cpp.func-sort-c.html | 120 + coverage/isdb/RDC.cpp.func.html | 120 + coverage/isdb/RDC.cpp.gcov.html | 597 + coverage/isdb/Rescale.cpp.func-sort-c.html | 132 + coverage/isdb/Rescale.cpp.func.html | 132 + coverage/isdb/Rescale.cpp.gcov.html | 592 + coverage/isdb/SAXS.cpp.func-sort-c.html | 168 + coverage/isdb/SAXS.cpp.func.html | 168 + coverage/isdb/SAXS.cpp.gcov.html | 7532 ++++ coverage/isdb/Select.cpp.func-sort-c.html | 100 + coverage/isdb/Select.cpp.func.html | 100 + coverage/isdb/Select.cpp.gcov.html | 194 + coverage/isdb/Selector.cpp.func-sort-c.html | 100 + coverage/isdb/Selector.cpp.func.html | 100 + coverage/isdb/Selector.cpp.gcov.html | 168 + coverage/isdb/index-sort-f.html | 233 + coverage/isdb/index-sort-l.html | 233 + coverage/isdb/index.html | 233 + coverage/logmfd/LogMFD.cpp.func-sort-c.html | 136 + coverage/logmfd/LogMFD.cpp.func.html | 136 + coverage/logmfd/LogMFD.cpp.gcov.html | 1324 + coverage/logmfd/index-sort-f.html | 93 + coverage/logmfd/index-sort-l.html | 93 + coverage/logmfd/index.html | 93 + coverage/main/index-sort-f.html | 93 + coverage/main/index-sort-l.html | 93 + coverage/main/index.html | 93 + coverage/main/main.cpp.func-sort-c.html | 76 + coverage/main/main.cpp.func.html | 76 + coverage/main/main.cpp.gcov.html | 147 + .../LWalls.cpp.func-sort-c.html | 100 + coverage/manyrestraints/LWalls.cpp.func.html | 100 + coverage/manyrestraints/LWalls.cpp.gcov.html | 184 + .../ManyRestraintsBase.cpp.func-sort-c.html | 96 + .../ManyRestraintsBase.cpp.func.html | 96 + .../ManyRestraintsBase.cpp.gcov.html | 172 + .../ManyRestraintsBase.h.func-sort-c.html | 96 + .../ManyRestraintsBase.h.func.html | 96 + .../ManyRestraintsBase.h.gcov.html | 152 + .../UWalls.cpp.func-sort-c.html | 100 + coverage/manyrestraints/UWalls.cpp.func.html | 100 + coverage/manyrestraints/UWalls.cpp.gcov.html | 188 + coverage/manyrestraints/index-sort-f.html | 123 + coverage/manyrestraints/index-sort-l.html | 123 + coverage/manyrestraints/index.html | 123 + .../mapping/AdaptivePath.cpp.func-sort-c.html | 116 + coverage/mapping/AdaptivePath.cpp.func.html | 116 + coverage/mapping/AdaptivePath.cpp.gcov.html | 335 + coverage/mapping/Mapping.cpp.func-sort-c.html | 120 + coverage/mapping/Mapping.cpp.func.html | 120 + coverage/mapping/Mapping.cpp.gcov.html | 289 + coverage/mapping/Mapping.h.func-sort-c.html | 92 + coverage/mapping/Mapping.h.func.html | 92 + coverage/mapping/Mapping.h.gcov.html | 223 + coverage/mapping/PCAVars.cpp.func-sort-c.html | 124 + coverage/mapping/PCAVars.cpp.func.html | 124 + coverage/mapping/PCAVars.cpp.gcov.html | 535 + coverage/mapping/Path.cpp.func-sort-c.html | 96 + coverage/mapping/Path.cpp.func.html | 96 + coverage/mapping/Path.cpp.gcov.html | 241 + .../mapping/PathBase.cpp.func-sort-c.html | 100 + coverage/mapping/PathBase.cpp.func.html | 100 + coverage/mapping/PathBase.cpp.gcov.html | 161 + ...athReparameterization.cpp.func-sort-c.html | 92 + .../PathReparameterization.cpp.func.html | 92 + .../PathReparameterization.cpp.gcov.html | 222 + .../mapping/PathTools.cpp.func-sort-c.html | 100 + coverage/mapping/PathTools.cpp.func.html | 100 + coverage/mapping/PathTools.cpp.gcov.html | 387 + .../mapping/PropertyMap.cpp.func-sort-c.html | 96 + coverage/mapping/PropertyMap.cpp.func.html | 96 + coverage/mapping/PropertyMap.cpp.gcov.html | 205 + .../mapping/SpathVessel.cpp.func-sort-c.html | 108 + coverage/mapping/SpathVessel.cpp.func.html | 108 + coverage/mapping/SpathVessel.cpp.gcov.html | 163 + ...igonometricPathVessel.cpp.func-sort-c.html | 112 + .../TrigonometricPathVessel.cpp.func.html | 112 + .../TrigonometricPathVessel.cpp.gcov.html | 305 + .../mapping/ZpathVessel.cpp.func-sort-c.html | 108 + coverage/mapping/ZpathVessel.cpp.func.html | 108 + coverage/mapping/ZpathVessel.cpp.gcov.html | 150 + coverage/mapping/index-sort-f.html | 203 + coverage/mapping/index-sort-l.html | 203 + coverage/mapping/index.html | 203 + coverage/maze/Loss.cpp.func-sort-c.html | 100 + coverage/maze/Loss.cpp.func.html | 100 + coverage/maze/Loss.cpp.gcov.html | 189 + coverage/maze/Loss.h.func-sort-c.html | 84 + coverage/maze/Loss.h.func.html | 84 + coverage/maze/Loss.h.gcov.html | 162 + coverage/maze/Member.h.func-sort-c.html | 80 + coverage/maze/Member.h.func.html | 80 + coverage/maze/Member.h.gcov.html | 142 + coverage/maze/Memetic.cpp.func-sort-c.html | 100 + coverage/maze/Memetic.cpp.func.html | 100 + coverage/maze/Memetic.cpp.gcov.html | 358 + coverage/maze/Memetic.h.func-sort-c.html | 152 + coverage/maze/Memetic.h.func.html | 152 + coverage/maze/Memetic.h.gcov.html | 882 + coverage/maze/Optimizer.cpp.func-sort-c.html | 112 + coverage/maze/Optimizer.cpp.func.html | 112 + coverage/maze/Optimizer.cpp.gcov.html | 586 + coverage/maze/Optimizer.h.func-sort-c.html | 76 + coverage/maze/Optimizer.h.func.html | 76 + coverage/maze/Optimizer.h.gcov.html | 432 + .../maze/Optimizer_Bias.cpp.func-sort-c.html | 108 + coverage/maze/Optimizer_Bias.cpp.func.html | 108 + coverage/maze/Optimizer_Bias.cpp.gcov.html | 510 + ...andom_Acceleration_MD.cpp.func-sort-c.html | 100 + .../maze/Random_Acceleration_MD.cpp.func.html | 100 + .../maze/Random_Acceleration_MD.cpp.gcov.html | 279 + coverage/maze/Random_MT.cpp.func-sort-c.html | 96 + coverage/maze/Random_MT.cpp.func.html | 96 + coverage/maze/Random_MT.cpp.gcov.html | 157 + coverage/maze/Random_MT.h.func-sort-c.html | 88 + coverage/maze/Random_MT.h.func.html | 88 + coverage/maze/Random_MT.h.gcov.html | 232 + .../maze/Random_Walk.cpp.func-sort-c.html | 100 + coverage/maze/Random_Walk.cpp.func.html | 100 + coverage/maze/Random_Walk.cpp.gcov.html | 200 + .../Simulated_Annealing.cpp.func-sort-c.html | 104 + .../maze/Simulated_Annealing.cpp.func.html | 104 + .../maze/Simulated_Annealing.cpp.gcov.html | 351 + coverage/maze/Steered_MD.cpp.func-sort-c.html | 100 + coverage/maze/Steered_MD.cpp.func.html | 100 + coverage/maze/Steered_MD.cpp.gcov.html | 252 + coverage/maze/Tools.h.func-sort-c.html | 88 + coverage/maze/Tools.h.func.html | 88 + coverage/maze/Tools.h.gcov.html | 256 + coverage/maze/index-sort-f.html | 233 + coverage/maze/index-sort-l.html | 233 + coverage/maze/index.html | 233 + .../FusionPoreExpansionP.cpp.func-sort-c.html | 100 + .../FusionPoreExpansionP.cpp.func.html | 100 + .../FusionPoreExpansionP.cpp.gcov.html | 681 + ...FusionPoreNucleationP.cpp.func-sort-c.html | 100 + .../FusionPoreNucleationP.cpp.func.html | 100 + .../FusionPoreNucleationP.cpp.gcov.html | 883 + .../MemFusionP.cpp.func-sort-c.html | 100 + .../membranefusion/MemFusionP.cpp.func.html | 100 + .../membranefusion/MemFusionP.cpp.gcov.html | 684 + coverage/membranefusion/index-sort-f.html | 113 + coverage/membranefusion/index-sort-l.html | 113 + coverage/membranefusion/index.html | 113 + .../ActionVolume.cpp.func-sort-c.html | 92 + .../multicolvar/ActionVolume.cpp.func.html | 92 + .../multicolvar/ActionVolume.cpp.gcov.html | 160 + .../ActionVolume.h.func-sort-c.html | 76 + coverage/multicolvar/ActionVolume.h.func.html | 76 + coverage/multicolvar/ActionVolume.h.gcov.html | 163 + .../AlphaBeta.cpp.func-sort-c.html | 104 + coverage/multicolvar/AlphaBeta.cpp.func.html | 104 + coverage/multicolvar/AlphaBeta.cpp.gcov.html | 280 + .../multicolvar/Angles.cpp.func-sort-c.html | 108 + coverage/multicolvar/Angles.cpp.func.html | 108 + coverage/multicolvar/Angles.cpp.gcov.html | 296 + .../AtomValuePack.cpp.func-sort-c.html | 88 + .../multicolvar/AtomValuePack.cpp.func.html | 88 + .../multicolvar/AtomValuePack.cpp.gcov.html | 176 + .../AtomValuePack.h.func-sort-c.html | 100 + .../multicolvar/AtomValuePack.h.func.html | 100 + .../multicolvar/AtomValuePack.h.gcov.html | 291 + .../multicolvar/Bridge.cpp.func-sort-c.html | 104 + coverage/multicolvar/Bridge.cpp.func.html | 104 + coverage/multicolvar/Bridge.cpp.gcov.html | 231 + ...edMultiColvarFunction.cpp.func-sort-c.html | 116 + .../BridgedMultiColvarFunction.cpp.func.html | 116 + .../BridgedMultiColvarFunction.cpp.gcov.html | 200 + ...dgedMultiColvarFunction.h.func-sort-c.html | 120 + .../BridgedMultiColvarFunction.h.func.html | 120 + .../BridgedMultiColvarFunction.h.gcov.html | 223 + .../CatomPack.cpp.func-sort-c.html | 76 + coverage/multicolvar/CatomPack.cpp.func.html | 76 + coverage/multicolvar/CatomPack.cpp.gcov.html | 108 + .../multicolvar/CatomPack.h.func-sort-c.html | 80 + coverage/multicolvar/CatomPack.h.func.html | 80 + coverage/multicolvar/CatomPack.h.gcov.html | 154 + .../CenterOfMultiColvar.cpp.func-sort-c.html | 100 + .../CenterOfMultiColvar.cpp.func.html | 100 + .../CenterOfMultiColvar.cpp.gcov.html | 297 + .../CoordinationNumbers.cpp.func-sort-c.html | 104 + .../CoordinationNumbers.cpp.func.html | 104 + .../CoordinationNumbers.cpp.gcov.html | 260 + .../multicolvar/Density.cpp.func-sort-c.html | 120 + coverage/multicolvar/Density.cpp.func.html | 120 + coverage/multicolvar/Density.cpp.gcov.html | 181 + .../DihedralCorrelation.cpp.func-sort-c.html | 104 + .../DihedralCorrelation.cpp.func.html | 104 + .../DihedralCorrelation.cpp.gcov.html | 250 + .../DistanceFromContour.cpp.func-sort-c.html | 124 + .../DistanceFromContour.cpp.func.html | 124 + .../DistanceFromContour.cpp.gcov.html | 418 + .../Distances.cpp.func-sort-c.html | 104 + coverage/multicolvar/Distances.cpp.func.html | 104 + coverage/multicolvar/Distances.cpp.gcov.html | 287 + .../DumpMultiColvar.cpp.func-sort-c.html | 124 + .../multicolvar/DumpMultiColvar.cpp.func.html | 124 + .../multicolvar/DumpMultiColvar.cpp.gcov.html | 259 + .../FilterBetween.cpp.func-sort-c.html | 112 + .../multicolvar/FilterBetween.cpp.func.html | 112 + .../multicolvar/FilterBetween.cpp.gcov.html | 270 + .../FilterLessThan.cpp.func-sort-c.html | 112 + .../multicolvar/FilterLessThan.cpp.func.html | 112 + .../multicolvar/FilterLessThan.cpp.gcov.html | 238 + .../FilterMoreThan.cpp.func-sort-c.html | 112 + .../multicolvar/FilterMoreThan.cpp.func.html | 112 + .../multicolvar/FilterMoreThan.cpp.gcov.html | 255 + .../InPlaneDistances.cpp.func-sort-c.html | 104 + .../InPlaneDistances.cpp.func.html | 104 + .../InPlaneDistances.cpp.gcov.html | 223 + .../LocalAverage.cpp.func-sort-c.html | 112 + .../multicolvar/LocalAverage.cpp.func.html | 112 + .../multicolvar/LocalAverage.cpp.gcov.html | 406 + .../MultiColvarBase.cpp.func-sort-c.html | 236 + .../multicolvar/MultiColvarBase.cpp.func.html | 236 + .../multicolvar/MultiColvarBase.cpp.gcov.html | 1164 + .../MultiColvarBase.h.func-sort-c.html | 112 + .../multicolvar/MultiColvarBase.h.func.html | 112 + .../multicolvar/MultiColvarBase.h.gcov.html | 350 + .../MultiColvarCombine.cpp.func-sort-c.html | 104 + .../MultiColvarCombine.cpp.func.html | 104 + .../MultiColvarCombine.cpp.gcov.html | 171 + .../MultiColvarDensity.cpp.func-sort-c.html | 120 + .../MultiColvarDensity.cpp.func.html | 120 + .../MultiColvarDensity.cpp.gcov.html | 374 + .../MultiColvarFilter.cpp.func-sort-c.html | 96 + .../MultiColvarFilter.cpp.func.html | 96 + .../MultiColvarFilter.cpp.gcov.html | 170 + .../MultiColvarFilter.h.func-sort-c.html | 76 + .../multicolvar/MultiColvarFilter.h.func.html | 76 + .../multicolvar/MultiColvarFilter.h.gcov.html | 139 + .../MultiColvarProduct.cpp.func-sort-c.html | 104 + .../MultiColvarProduct.cpp.func.html | 104 + .../MultiColvarProduct.cpp.gcov.html | 165 + .../NumberOfLinks.cpp.func-sort-c.html | 108 + .../multicolvar/NumberOfLinks.cpp.func.html | 108 + .../multicolvar/NumberOfLinks.cpp.gcov.html | 251 + .../multicolvar/Torsions.cpp.func-sort-c.html | 108 + coverage/multicolvar/Torsions.cpp.func.html | 108 + coverage/multicolvar/Torsions.cpp.gcov.html | 211 + .../VolumeAround.cpp.func-sort-c.html | 104 + .../multicolvar/VolumeAround.cpp.func.html | 104 + .../multicolvar/VolumeAround.cpp.gcov.html | 230 + ...VolumeBetweenContours.cpp.func-sort-c.html | 104 + .../VolumeBetweenContours.cpp.func.html | 104 + .../VolumeBetweenContours.cpp.gcov.html | 222 + .../VolumeCavity.cpp.func-sort-c.html | 120 + .../multicolvar/VolumeCavity.cpp.func.html | 120 + .../multicolvar/VolumeCavity.cpp.gcov.html | 488 + .../VolumeGradientBase.cpp.func-sort-c.html | 104 + .../VolumeGradientBase.cpp.func.html | 104 + .../VolumeGradientBase.cpp.gcov.html | 229 + .../VolumeGradientBase.h.func-sort-c.html | 76 + .../VolumeGradientBase.h.func.html | 76 + .../VolumeGradientBase.h.gcov.html | 170 + .../VolumeInCylinder.cpp.func-sort-c.html | 104 + .../VolumeInCylinder.cpp.func.html | 104 + .../VolumeInCylinder.cpp.gcov.html | 236 + .../VolumeInSphere.cpp.func-sort-c.html | 104 + .../multicolvar/VolumeInSphere.cpp.func.html | 104 + .../multicolvar/VolumeInSphere.cpp.gcov.html | 199 + .../VolumeTetrapore.cpp.func-sort-c.html | 120 + .../multicolvar/VolumeTetrapore.cpp.func.html | 120 + .../multicolvar/VolumeTetrapore.cpp.gcov.html | 523 + .../multicolvar/XAngle.cpp.func-sort-c.html | 132 + coverage/multicolvar/XAngle.cpp.func.html | 132 + coverage/multicolvar/XAngle.cpp.gcov.html | 253 + .../XDistances.cpp.func-sort-c.html | 128 + coverage/multicolvar/XDistances.cpp.func.html | 128 + coverage/multicolvar/XDistances.cpp.gcov.html | 317 + .../XYDistances.cpp.func-sort-c.html | 128 + .../multicolvar/XYDistances.cpp.func.html | 128 + .../multicolvar/XYDistances.cpp.gcov.html | 245 + .../XYTorsion.cpp.func-sort-c.html | 172 + coverage/multicolvar/XYTorsion.cpp.func.html | 172 + coverage/multicolvar/XYTorsion.cpp.gcov.html | 310 + coverage/multicolvar/index-sort-f.html | 523 + coverage/multicolvar/index-sort-l.html | 523 + coverage/multicolvar/index.html | 523 + coverage/opes/ECVcustom.cpp.func-sort-c.html | 128 + coverage/opes/ECVcustom.cpp.func.html | 128 + coverage/opes/ECVcustom.cpp.gcov.html | 314 + coverage/opes/ECVlinear.cpp.func-sort-c.html | 124 + coverage/opes/ECVlinear.cpp.func.html | 124 + coverage/opes/ECVlinear.cpp.gcov.html | 344 + .../opes/ECVmultiThermal.cpp.func-sort-c.html | 124 + coverage/opes/ECVmultiThermal.cpp.func.html | 124 + coverage/opes/ECVmultiThermal.cpp.gcov.html | 346 + .../ECVmultiThermalBaric.cpp.func-sort-c.html | 132 + .../opes/ECVmultiThermalBaric.cpp.func.html | 132 + .../opes/ECVmultiThermalBaric.cpp.gcov.html | 608 + .../ECVumbrellasFile.cpp.func-sort-c.html | 124 + coverage/opes/ECVumbrellasFile.cpp.func.html | 124 + coverage/opes/ECVumbrellasFile.cpp.gcov.html | 371 + .../ECVumbrellasLine.cpp.func-sort-c.html | 124 + coverage/opes/ECVumbrellasLine.cpp.func.html | 124 + coverage/opes/ECVumbrellasLine.cpp.gcov.html | 377 + .../opes/ExpansionCVs.cpp.func-sort-c.html | 112 + coverage/opes/ExpansionCVs.cpp.func.html | 112 + coverage/opes/ExpansionCVs.cpp.gcov.html | 309 + coverage/opes/ExpansionCVs.h.func-sort-c.html | 84 + coverage/opes/ExpansionCVs.h.func.html | 84 + coverage/opes/ExpansionCVs.h.gcov.html | 148 + .../opes/OPESexpanded.cpp.func-sort-c.html | 136 + coverage/opes/OPESexpanded.cpp.func.html | 136 + coverage/opes/OPESexpanded.cpp.gcov.html | 1020 + coverage/opes/OPESmetad.cpp.func-sort-c.html | 208 + coverage/opes/OPESmetad.cpp.func.html | 208 + coverage/opes/OPESmetad.cpp.gcov.html | 1838 + coverage/opes/index-sort-f.html | 183 + coverage/opes/index-sort-l.html | 183 + coverage/opes/index.html | 183 + .../pamm/HBPammHydrogens.cpp.func-sort-c.html | 104 + coverage/pamm/HBPammHydrogens.cpp.func.html | 104 + coverage/pamm/HBPammHydrogens.cpp.gcov.html | 267 + .../pamm/HBPammMatrix.cpp.func-sort-c.html | 104 + coverage/pamm/HBPammMatrix.cpp.func.html | 104 + coverage/pamm/HBPammMatrix.cpp.gcov.html | 224 + .../pamm/HBPammObject.cpp.func-sort-c.html | 84 + coverage/pamm/HBPammObject.cpp.func.html | 84 + coverage/pamm/HBPammObject.cpp.gcov.html | 152 + coverage/pamm/HBPammObject.h.func-sort-c.html | 72 + coverage/pamm/HBPammObject.h.func.html | 72 + coverage/pamm/HBPammObject.h.gcov.html | 127 + coverage/pamm/PAMM.cpp.func-sort-c.html | 116 + coverage/pamm/PAMM.cpp.func.html | 116 + coverage/pamm/PAMM.cpp.gcov.html | 328 + coverage/pamm/PammObject.cpp.func-sort-c.html | 88 + coverage/pamm/PammObject.cpp.func.html | 88 + coverage/pamm/PammObject.cpp.gcov.html | 179 + coverage/pamm/PammObject.h.func-sort-c.html | 72 + coverage/pamm/PammObject.h.func.html | 72 + coverage/pamm/PammObject.h.gcov.html | 158 + coverage/pamm/index-sort-f.html | 153 + coverage/pamm/index-sort-l.html | 153 + coverage/pamm/index.html | 153 + coverage/piv/PIV.cpp.func-sort-c.html | 104 + coverage/piv/PIV.cpp.func.html | 104 + coverage/piv/PIV.cpp.gcov.html | 1338 + coverage/piv/index-sort-f.html | 93 + coverage/piv/index-sort-l.html | 93 + coverage/piv/index.html | 93 + .../pytorch/PytorchModel.cpp.func-sort-c.html | 104 + coverage/pytorch/PytorchModel.cpp.func.html | 104 + coverage/pytorch/PytorchModel.cpp.gcov.html | 279 + coverage/pytorch/index-sort-f.html | 93 + coverage/pytorch/index-sort-l.html | 93 + coverage/pytorch/index.html | 93 + .../ArgumentOnlyDistance.cpp.func-sort-c.html | 92 + .../ArgumentOnlyDistance.cpp.func.html | 92 + .../ArgumentOnlyDistance.cpp.gcov.html | 129 + .../ArgumentOnlyDistance.h.func-sort-c.html | 80 + .../ArgumentOnlyDistance.h.func.html | 80 + .../ArgumentOnlyDistance.h.gcov.html | 121 + coverage/reference/DRMSD.cpp.func-sort-c.html | 116 + coverage/reference/DRMSD.cpp.func.html | 116 + coverage/reference/DRMSD.cpp.gcov.html | 193 + .../reference/Direction.cpp.func-sort-c.html | 120 + coverage/reference/Direction.cpp.func.html | 120 + coverage/reference/Direction.cpp.gcov.html | 150 + .../reference/Direction.h.func-sort-c.html | 76 + coverage/reference/Direction.h.func.html | 76 + coverage/reference/Direction.h.gcov.html | 127 + .../DotProductDistance.cpp.func-sort-c.html | 100 + .../DotProductDistance.cpp.func.html | 100 + .../DotProductDistance.cpp.gcov.html | 134 + .../EuclideanDistance.cpp.func-sort-c.html | 92 + .../reference/EuclideanDistance.cpp.func.html | 92 + .../reference/EuclideanDistance.cpp.gcov.html | 116 + .../IntermolecularDRMSD.cpp.func-sort-c.html | 100 + .../IntermolecularDRMSD.cpp.func.html | 100 + .../IntermolecularDRMSD.cpp.gcov.html | 144 + .../IntramolecularDRMSD.cpp.func-sort-c.html | 100 + .../IntramolecularDRMSD.cpp.func.html | 100 + .../IntramolecularDRMSD.cpp.gcov.html | 142 + .../MahalanobisDistance.cpp.func-sort-c.html | 92 + .../MahalanobisDistance.cpp.func.html | 92 + .../MahalanobisDistance.cpp.gcov.html | 117 + .../MetricRegister.cpp.func-sort-c.html | 92 + .../reference/MetricRegister.cpp.func.html | 92 + .../reference/MetricRegister.cpp.gcov.html | 134 + .../MetricRegister.h.func-sort-c.html | 112 + coverage/reference/MetricRegister.h.func.html | 112 + coverage/reference/MetricRegister.h.gcov.html | 189 + .../MultiDomainRMSD.cpp.func-sort-c.html | 124 + .../reference/MultiDomainRMSD.cpp.func.html | 124 + .../reference/MultiDomainRMSD.cpp.gcov.html | 285 + ...izedEuclideanDistance.cpp.func-sort-c.html | 92 + .../NormalizedEuclideanDistance.cpp.func.html | 92 + .../NormalizedEuclideanDistance.cpp.gcov.html | 117 + .../OptimalRMSD.cpp.func-sort-c.html | 120 + coverage/reference/OptimalRMSD.cpp.func.html | 120 + coverage/reference/OptimalRMSD.cpp.gcov.html | 194 + .../reference/RMSDBase.cpp.func-sort-c.html | 88 + coverage/reference/RMSDBase.cpp.func.html | 88 + coverage/reference/RMSDBase.cpp.gcov.html | 118 + .../ReferenceArguments.cpp.func-sort-c.html | 116 + .../ReferenceArguments.cpp.func.html | 116 + .../ReferenceArguments.cpp.gcov.html | 280 + .../ReferenceArguments.h.func-sort-c.html | 88 + .../reference/ReferenceArguments.h.func.html | 88 + .../reference/ReferenceArguments.h.gcov.html | 196 + .../ReferenceAtoms.cpp.func-sort-c.html | 96 + .../reference/ReferenceAtoms.cpp.func.html | 96 + .../reference/ReferenceAtoms.cpp.gcov.html | 201 + .../ReferenceAtoms.h.func-sort-c.html | 92 + coverage/reference/ReferenceAtoms.h.func.html | 92 + coverage/reference/ReferenceAtoms.h.gcov.html | 239 + ...eferenceConfiguration.cpp.func-sort-c.html | 124 + .../ReferenceConfiguration.cpp.func.html | 124 + .../ReferenceConfiguration.cpp.gcov.html | 207 + .../ReferenceConfiguration.h.func-sort-c.html | 120 + .../ReferenceConfiguration.h.func.html | 120 + .../ReferenceConfiguration.h.gcov.html | 249 + .../ReferenceValuePack.cpp.func-sort-c.html | 100 + .../ReferenceValuePack.cpp.func.html | 100 + .../ReferenceValuePack.cpp.gcov.html | 171 + .../ReferenceValuePack.h.func-sort-c.html | 92 + .../reference/ReferenceValuePack.h.func.html | 92 + .../reference/ReferenceValuePack.h.gcov.html | 304 + .../reference/SimpleRMSD.cpp.func-sort-c.html | 116 + coverage/reference/SimpleRMSD.cpp.func.html | 116 + coverage/reference/SimpleRMSD.cpp.gcov.html | 162 + .../SingleDomainRMSD.cpp.func-sort-c.html | 96 + .../reference/SingleDomainRMSD.cpp.func.html | 96 + .../reference/SingleDomainRMSD.cpp.gcov.html | 178 + .../SingleDomainRMSD.h.func-sort-c.html | 80 + .../reference/SingleDomainRMSD.h.func.html | 80 + .../reference/SingleDomainRMSD.h.gcov.html | 127 + coverage/reference/index-sort-f.html | 353 + coverage/reference/index-sort-l.html | 353 + coverage/reference/index.html | 353 + coverage/ruby.png | Bin 0 -> 141 bytes .../s2cm/S2ContactModel.cpp.func-sort-c.html | 116 + coverage/s2cm/S2ContactModel.cpp.func.html | 116 + coverage/s2cm/S2ContactModel.cpp.gcov.html | 401 + coverage/s2cm/index-sort-f.html | 93 + coverage/s2cm/index-sort-l.html | 93 + coverage/s2cm/index.html | 93 + coverage/sasa/index-sort-f.html | 103 + coverage/sasa/index-sort-l.html | 103 + coverage/sasa/index.html | 103 + coverage/sasa/sasa_HASEL.cpp.func-sort-c.html | 136 + coverage/sasa/sasa_HASEL.cpp.func.html | 136 + coverage/sasa/sasa_HASEL.cpp.gcov.html | 1088 + coverage/sasa/sasa_LCPO.cpp.func-sort-c.html | 136 + coverage/sasa/sasa_LCPO.cpp.func.html | 136 + coverage/sasa/sasa_LCPO.cpp.gcov.html | 1156 + .../AlphaRMSD.cpp.func-sort-c.html | 96 + .../AlphaRMSD.cpp.func.html | 96 + .../AlphaRMSD.cpp.gcov.html | 234 + .../AntibetaRMSD.cpp.func-sort-c.html | 96 + .../AntibetaRMSD.cpp.func.html | 96 + .../AntibetaRMSD.cpp.gcov.html | 286 + .../ParabetaRMSD.cpp.func-sort-c.html | 96 + .../ParabetaRMSD.cpp.func.html | 96 + .../ParabetaRMSD.cpp.gcov.html | 320 + ...econdaryStructureRMSD.cpp.func-sort-c.html | 128 + .../SecondaryStructureRMSD.cpp.func.html | 128 + .../SecondaryStructureRMSD.cpp.gcov.html | 344 + .../SecondaryStructureRMSD.h.func-sort-c.html | 84 + .../SecondaryStructureRMSD.h.func.html | 84 + .../SecondaryStructureRMSD.h.gcov.html | 186 + coverage/secondarystructure/index-sort-f.html | 133 + coverage/secondarystructure/index-sort-l.html | 133 + coverage/secondarystructure/index.html | 133 + coverage/setup/Load.cpp.func-sort-c.html | 96 + coverage/setup/Load.cpp.func.html | 96 + coverage/setup/Load.cpp.gcov.html | 199 + coverage/setup/Restart.cpp.func-sort-c.html | 96 + coverage/setup/Restart.cpp.func.html | 96 + coverage/setup/Restart.cpp.gcov.html | 201 + coverage/setup/Units.cpp.func-sort-c.html | 96 + coverage/setup/Units.cpp.func.html | 96 + coverage/setup/Units.cpp.gcov.html | 277 + coverage/setup/index-sort-f.html | 113 + coverage/setup/index-sort-l.html | 113 + coverage/setup/index.html | 113 + coverage/snow.png | Bin 0 -> 141 bytes coverage/tools/Angle.cpp.func-sort-c.html | 80 + coverage/tools/Angle.cpp.func.html | 80 + coverage/tools/Angle.cpp.gcov.html | 144 + coverage/tools/AtomNumber.h.func-sort-c.html | 80 + coverage/tools/AtomNumber.h.func.html | 80 + coverage/tools/AtomNumber.h.gcov.html | 228 + .../BiasRepresentation.cpp.func-sort-c.html | 148 + .../tools/BiasRepresentation.cpp.func.html | 148 + .../tools/BiasRepresentation.cpp.gcov.html | 363 + .../Brent1DRootSearch.h.func-sort-c.html | 108 + coverage/tools/Brent1DRootSearch.h.func.html | 108 + coverage/tools/Brent1DRootSearch.h.gcov.html | 196 + coverage/tools/Citations.cpp.func-sort-c.html | 88 + coverage/tools/Citations.cpp.func.html | 88 + coverage/tools/Citations.cpp.gcov.html | 132 + coverage/tools/Citations.h.func-sort-c.html | 72 + coverage/tools/Citations.h.func.html | 72 + coverage/tools/Citations.h.gcov.html | 150 + .../tools/Communicator.cpp.func-sort-c.html | 216 + coverage/tools/Communicator.cpp.func.html | 216 + coverage/tools/Communicator.cpp.gcov.html | 394 + .../tools/Communicator.h.func-sort-c.html | 320 + coverage/tools/Communicator.h.func.html | 320 + coverage/tools/Communicator.h.gcov.html | 328 + .../ConjugateGradient.h.func-sort-c.html | 84 + coverage/tools/ConjugateGradient.h.func.html | 84 + coverage/tools/ConjugateGradient.h.gcov.html | 142 + coverage/tools/DLLoader.cpp.func-sort-c.html | 92 + coverage/tools/DLLoader.cpp.func.html | 92 + coverage/tools/DLLoader.cpp.gcov.html | 155 + coverage/tools/DynamicList.h.func-sort-c.html | 124 + coverage/tools/DynamicList.h.func.html | 124 + coverage/tools/DynamicList.h.gcov.html | 455 + coverage/tools/ERMSD.cpp.func-sort-c.html | 92 + coverage/tools/ERMSD.cpp.func.html | 92 + coverage/tools/ERMSD.cpp.gcov.html | 379 + coverage/tools/ERMSD.h.func-sort-c.html | 72 + coverage/tools/ERMSD.h.func.html | 72 + coverage/tools/ERMSD.h.gcov.html | 149 + coverage/tools/Exception.cpp.func-sort-c.html | 96 + coverage/tools/Exception.cpp.func.html | 96 + coverage/tools/Exception.cpp.gcov.html | 232 + coverage/tools/Exception.h.func-sort-c.html | 612 + coverage/tools/Exception.h.func.html | 612 + coverage/tools/Exception.h.gcov.html | 478 + coverage/tools/FileBase.cpp.func-sort-c.html | 132 + coverage/tools/FileBase.cpp.func.html | 132 + coverage/tools/FileBase.cpp.gcov.html | 251 + coverage/tools/FileBase.h.func-sort-c.html | 72 + coverage/tools/FileBase.h.func.html | 72 + coverage/tools/FileBase.h.gcov.html | 228 + coverage/tools/ForwardDecl.h.func-sort-c.html | 124 + coverage/tools/ForwardDecl.h.func.html | 124 + coverage/tools/ForwardDecl.h.gcov.html | 131 + coverage/tools/Grid.cpp.func-sort-c.html | 380 + coverage/tools/Grid.cpp.func.html | 380 + coverage/tools/Grid.cpp.gcov.html | 1204 + coverage/tools/Grid.h.func-sort-c.html | 108 + coverage/tools/Grid.h.func.html | 108 + coverage/tools/Grid.h.gcov.html | 431 + .../tools/HistogramBead.cpp.func-sort-c.html | 116 + coverage/tools/HistogramBead.cpp.func.html | 116 + coverage/tools/HistogramBead.cpp.gcov.html | 341 + .../tools/HistogramBead.h.func-sort-c.html | 80 + coverage/tools/HistogramBead.h.func.html | 80 + coverage/tools/HistogramBead.h.gcov.html | 190 + coverage/tools/IFile.cpp.func-sort-c.html | 172 + coverage/tools/IFile.cpp.func.html | 172 + coverage/tools/IFile.cpp.gcov.html | 371 + coverage/tools/IFile.h.func-sort-c.html | 72 + coverage/tools/IFile.h.func.html | 72 + coverage/tools/IFile.h.gcov.html | 193 + .../KernelFunctions.cpp.func-sort-c.html | 112 + coverage/tools/KernelFunctions.cpp.func.html | 112 + coverage/tools/KernelFunctions.cpp.gcov.html | 531 + .../tools/KernelFunctions.h.func-sort-c.html | 76 + coverage/tools/KernelFunctions.h.func.html | 76 + coverage/tools/KernelFunctions.h.gcov.html | 173 + coverage/tools/Keywords.cpp.func-sort-c.html | 236 + coverage/tools/Keywords.cpp.func.html | 236 + coverage/tools/Keywords.cpp.gcov.html | 739 + coverage/tools/Keywords.h.func-sort-c.html | 80 + coverage/tools/Keywords.h.func.html | 80 + coverage/tools/Keywords.h.gcov.html | 260 + .../LatticeReduction.cpp.func-sort-c.html | 112 + coverage/tools/LatticeReduction.cpp.func.html | 112 + coverage/tools/LatticeReduction.cpp.gcov.html | 291 + coverage/tools/LinkCells.cpp.func-sort-c.html | 112 + coverage/tools/LinkCells.cpp.func.html | 112 + coverage/tools/LinkCells.cpp.gcov.html | 252 + coverage/tools/LinkCells.h.func-sort-c.html | 72 + coverage/tools/LinkCells.h.func.html | 72 + coverage/tools/LinkCells.h.gcov.html | 175 + .../tools/LoopUnroller.h.func-sort-c.html | 280 + coverage/tools/LoopUnroller.h.func.html | 280 + coverage/tools/LoopUnroller.h.gcov.html | 236 + coverage/tools/Matrix.h.func-sort-c.html | 116 + coverage/tools/Matrix.h.func.html | 116 + coverage/tools/Matrix.h.gcov.html | 490 + ...rixSquareBracketsAccess.h.func-sort-c.html | 144 + .../MatrixSquareBracketsAccess.h.func.html | 144 + .../MatrixSquareBracketsAccess.h.gcov.html | 214 + .../tools/Minimise1DBrent.h.func-sort-c.html | 120 + coverage/tools/Minimise1DBrent.h.func.html | 120 + coverage/tools/Minimise1DBrent.h.gcov.html | 271 + .../tools/MinimiseBase.h.func-sort-c.html | 144 + coverage/tools/MinimiseBase.h.func.html | 144 + coverage/tools/MinimiseBase.h.gcov.html | 191 + .../tools/MolDataClass.cpp.func-sort-c.html | 92 + coverage/tools/MolDataClass.cpp.func.html | 92 + coverage/tools/MolDataClass.cpp.gcov.html | 663 + .../tools/MultiValue.cpp.func-sort-c.html | 108 + coverage/tools/MultiValue.cpp.func.html | 108 + coverage/tools/MultiValue.cpp.gcov.html | 196 + coverage/tools/MultiValue.h.func-sort-c.html | 88 + coverage/tools/MultiValue.h.func.html | 88 + coverage/tools/MultiValue.h.gcov.html | 317 + .../tools/NeighborList.cpp.func-sort-c.html | 132 + coverage/tools/NeighborList.cpp.func.html | 132 + coverage/tools/NeighborList.cpp.gcov.html | 301 + .../tools/NeighborList.h.func-sort-c.html | 76 + coverage/tools/NeighborList.h.func.html | 76 + coverage/tools/NeighborList.h.gcov.html | 170 + coverage/tools/OFile.cpp.func-sort-c.html | 192 + coverage/tools/OFile.cpp.func.html | 192 + coverage/tools/OFile.cpp.gcov.html | 512 + coverage/tools/OFile.h.func-sort-c.html | 500 + coverage/tools/OFile.h.func.html | 500 + coverage/tools/OFile.h.gcov.html | 362 + coverage/tools/OpenMP.cpp.func-sort-c.html | 92 + coverage/tools/OpenMP.cpp.func.html | 92 + coverage/tools/OpenMP.cpp.gcov.html | 154 + coverage/tools/OpenMP.h.func-sort-c.html | 88 + coverage/tools/OpenMP.h.func.html | 88 + coverage/tools/OpenMP.h.gcov.html | 154 + coverage/tools/PDB.cpp.func-sort-c.html | 248 + coverage/tools/PDB.cpp.func.html | 248 + coverage/tools/PDB.cpp.gcov.html | 826 + coverage/tools/Pbc.cpp.func-sort-c.html | 120 + coverage/tools/Pbc.cpp.func.html | 120 + coverage/tools/Pbc.cpp.gcov.html | 323 + coverage/tools/Pbc.h.func-sort-c.html | 72 + coverage/tools/Pbc.h.func.html | 72 + coverage/tools/Pbc.h.gcov.html | 188 + .../tools/PlumedHandle.cpp.func-sort-c.html | 104 + coverage/tools/PlumedHandle.cpp.func.html | 104 + coverage/tools/PlumedHandle.cpp.gcov.html | 182 + coverage/tools/RMSD.cpp.func-sort-c.html | 392 + coverage/tools/RMSD.cpp.func.html | 392 + coverage/tools/RMSD.cpp.gcov.html | 1548 + coverage/tools/RMSD.h.func-sort-c.html | 108 + coverage/tools/RMSD.h.func.html | 108 + coverage/tools/RMSD.h.gcov.html | 450 + coverage/tools/Random.cpp.func-sort-c.html | 116 + coverage/tools/Random.cpp.func.html | 116 + coverage/tools/Random.cpp.gcov.html | 245 + coverage/tools/Random.h.func-sort-c.html | 72 + coverage/tools/Random.h.func.html | 72 + coverage/tools/Random.h.gcov.html | 148 + .../tools/RootFindingBase.h.func-sort-c.html | 96 + coverage/tools/RootFindingBase.h.func.html | 96 + coverage/tools/RootFindingBase.h.gcov.html | 153 + coverage/tools/Stopwatch.cpp.func-sort-c.html | 84 + coverage/tools/Stopwatch.cpp.func.html | 84 + coverage/tools/Stopwatch.cpp.gcov.html | 154 + coverage/tools/Stopwatch.h.func-sort-c.html | 112 + coverage/tools/Stopwatch.h.func.html | 112 + coverage/tools/Stopwatch.h.gcov.html | 485 + .../tools/Subprocess.cpp.func-sort-c.html | 136 + coverage/tools/Subprocess.cpp.func.html | 136 + coverage/tools/Subprocess.cpp.gcov.html | 265 + coverage/tools/Subprocess.h.func-sort-c.html | 80 + coverage/tools/Subprocess.h.func.html | 80 + coverage/tools/Subprocess.h.gcov.html | 218 + .../SwitchingFunction.cpp.func-sort-c.html | 116 + .../tools/SwitchingFunction.cpp.func.html | 116 + .../tools/SwitchingFunction.cpp.gcov.html | 629 + coverage/tools/Tensor.cpp.func-sort-c.html | 76 + coverage/tools/Tensor.cpp.func.html | 76 + coverage/tools/Tensor.cpp.gcov.html | 115 + coverage/tools/Tensor.h.func-sort-c.html | 344 + coverage/tools/Tensor.h.func.html | 344 + coverage/tools/Tensor.h.gcov.html | 650 + coverage/tools/Tools.cpp.func-sort-c.html | 292 + coverage/tools/Tools.cpp.func.html | 292 + coverage/tools/Tools.cpp.gcov.html | 596 + coverage/tools/Tools.h.func-sort-c.html | 1808 + coverage/tools/Tools.h.func.html | 1808 + coverage/tools/Tools.h.gcov.html | 542 + coverage/tools/Torsion.cpp.func-sort-c.html | 80 + coverage/tools/Torsion.cpp.func.html | 80 + coverage/tools/Torsion.cpp.gcov.html | 156 + coverage/tools/Tree.cpp.func-sort-c.html | 84 + coverage/tools/Tree.cpp.func.html | 84 + coverage/tools/Tree.cpp.gcov.html | 193 + coverage/tools/Tree.h.func-sort-c.html | 72 + coverage/tools/Tree.h.func.html | 72 + coverage/tools/Tree.h.gcov.html | 128 + .../tools/TypesafePtr.cpp.func-sort-c.html | 84 + coverage/tools/TypesafePtr.cpp.func.html | 84 + coverage/tools/TypesafePtr.cpp.gcov.html | 133 + coverage/tools/TypesafePtr.h.func-sort-c.html | 292 + coverage/tools/TypesafePtr.h.func.html | 292 + coverage/tools/TypesafePtr.h.gcov.html | 475 + coverage/tools/Units.cpp.func-sort-c.html | 116 + coverage/tools/Units.cpp.func.html | 116 + coverage/tools/Units.cpp.gcov.html | 234 + coverage/tools/Units.h.func-sort-c.html | 72 + coverage/tools/Units.h.func.html | 72 + coverage/tools/Units.h.gcov.html | 243 + coverage/tools/Vector.h.func-sort-c.html | 288 + coverage/tools/Vector.h.func.html | 288 + coverage/tools/Vector.h.gcov.html | 419 + coverage/tools/h36.cpp.func-sort-c.html | 120 + coverage/tools/h36.cpp.func.html | 120 + coverage/tools/h36.cpp.gcov.html | 411 + coverage/tools/index-sort-f.html | 803 + coverage/tools/index-sort-l.html | 803 + coverage/tools/index.html | 803 + coverage/updown.png | Bin 0 -> 117 bytes coverage/vatom/Center.cpp.func-sort-c.html | 112 + coverage/vatom/Center.cpp.func.html | 112 + coverage/vatom/Center.cpp.gcov.html | 398 + coverage/vatom/FixedAtom.cpp.func-sort-c.html | 100 + coverage/vatom/FixedAtom.cpp.func.html | 100 + coverage/vatom/FixedAtom.cpp.gcov.html | 225 + coverage/vatom/Ghost.cpp.func-sort-c.html | 100 + coverage/vatom/Ghost.cpp.func.html | 100 + coverage/vatom/Ghost.cpp.gcov.html | 260 + coverage/vatom/index-sort-f.html | 113 + coverage/vatom/index-sort-l.html | 113 + coverage/vatom/index.html | 113 + .../ves/BF_Chebyshev.cpp.func-sort-c.html | 100 + coverage/ves/BF_Chebyshev.cpp.func.html | 100 + coverage/ves/BF_Chebyshev.cpp.gcov.html | 232 + coverage/ves/BF_Combined.cpp.func-sort-c.html | 104 + coverage/ves/BF_Combined.cpp.func.html | 104 + coverage/ves/BF_Combined.cpp.gcov.html | 278 + coverage/ves/BF_Cosine.cpp.func-sort-c.html | 104 + coverage/ves/BF_Cosine.cpp.func.html | 104 + coverage/ves/BF_Cosine.cpp.gcov.html | 228 + .../ves/BF_CubicBsplines.cpp.func-sort-c.html | 100 + coverage/ves/BF_CubicBsplines.cpp.func.html | 100 + coverage/ves/BF_CubicBsplines.cpp.gcov.html | 277 + coverage/ves/BF_Custom.cpp.func-sort-c.html | 104 + coverage/ves/BF_Custom.cpp.func.html | 104 + coverage/ves/BF_Custom.cpp.gcov.html | 445 + coverage/ves/BF_Fourier.cpp.func-sort-c.html | 104 + coverage/ves/BF_Fourier.cpp.func.html | 104 + coverage/ves/BF_Fourier.cpp.gcov.html | 232 + .../ves/BF_Gaussians.cpp.func-sort-c.html | 100 + coverage/ves/BF_Gaussians.cpp.func.html | 100 + coverage/ves/BF_Gaussians.cpp.gcov.html | 265 + coverage/ves/BF_Legendre.cpp.func-sort-c.html | 100 + coverage/ves/BF_Legendre.cpp.func.html | 100 + coverage/ves/BF_Legendre.cpp.gcov.html | 248 + coverage/ves/BF_Powers.cpp.func-sort-c.html | 100 + coverage/ves/BF_Powers.cpp.func.html | 100 + coverage/ves/BF_Powers.cpp.gcov.html | 221 + coverage/ves/BF_Sine.cpp.func-sort-c.html | 104 + coverage/ves/BF_Sine.cpp.func.html | 104 + coverage/ves/BF_Sine.cpp.gcov.html | 227 + coverage/ves/BF_Wavelets.cpp.func-sort-c.html | 104 + coverage/ves/BF_Wavelets.cpp.func.html | 104 + coverage/ves/BF_Wavelets.cpp.gcov.html | 494 + .../ves/BasisFunctions.cpp.func-sort-c.html | 156 + coverage/ves/BasisFunctions.cpp.func.html | 156 + coverage/ves/BasisFunctions.cpp.gcov.html | 481 + .../ves/BasisFunctions.h.func-sort-c.html | 104 + coverage/ves/BasisFunctions.h.func.html | 104 + coverage/ves/BasisFunctions.h.gcov.html | 393 + coverage/ves/CoeffsBase.cpp.func-sort-c.html | 200 + coverage/ves/CoeffsBase.cpp.func.html | 200 + coverage/ves/CoeffsBase.cpp.gcov.html | 593 + coverage/ves/CoeffsBase.h.func-sort-c.html | 80 + coverage/ves/CoeffsBase.h.func.html | 80 + coverage/ves/CoeffsBase.h.gcov.html | 335 + .../ves/CoeffsMatrix.cpp.func-sort-c.html | 388 + coverage/ves/CoeffsMatrix.cpp.func.html | 388 + coverage/ves/CoeffsMatrix.cpp.gcov.html | 791 + coverage/ves/CoeffsMatrix.h.func-sort-c.html | 72 + coverage/ves/CoeffsMatrix.h.func.html | 72 + coverage/ves/CoeffsMatrix.h.gcov.html | 287 + .../ves/CoeffsVector.cpp.func-sort-c.html | 468 + coverage/ves/CoeffsVector.cpp.func.html | 468 + coverage/ves/CoeffsVector.cpp.gcov.html | 971 + coverage/ves/CoeffsVector.h.func-sort-c.html | 72 + coverage/ves/CoeffsVector.h.func.html | 72 + coverage/ves/CoeffsVector.h.gcov.html | 316 + ...ermiSwitchingFunction.cpp.func-sort-c.html | 108 + .../ves/FermiSwitchingFunction.cpp.func.html | 108 + .../ves/FermiSwitchingFunction.cpp.gcov.html | 218 + ...ridIntegrationWeights.cpp.func-sort-c.html | 84 + .../ves/GridIntegrationWeights.cpp.func.html | 84 + .../ves/GridIntegrationWeights.cpp.gcov.html | 184 + ...idLinearInterpolation.cpp.func-sort-c.html | 108 + .../ves/GridLinearInterpolation.cpp.func.html | 108 + .../ves/GridLinearInterpolation.cpp.gcov.html | 311 + ...GridLinearInterpolation.h.func-sort-c.html | 76 + .../ves/GridLinearInterpolation.h.func.html | 76 + .../ves/GridLinearInterpolation.h.gcov.html | 158 + .../ves/GridProjWeights.h.func-sort-c.html | 88 + coverage/ves/GridProjWeights.h.func.html | 88 + coverage/ves/GridProjWeights.h.gcov.html | 126 + ...nearBasisSetExpansion.cpp.func-sort-c.html | 216 + .../ves/LinearBasisSetExpansion.cpp.func.html | 216 + .../ves/LinearBasisSetExpansion.cpp.gcov.html | 693 + ...LinearBasisSetExpansion.h.func-sort-c.html | 84 + .../ves/LinearBasisSetExpansion.h.func.html | 84 + .../ves/LinearBasisSetExpansion.h.gcov.html | 326 + ...MD_LinearExpansionPES.cpp.func-sort-c.html | 108 + .../ves/MD_LinearExpansionPES.cpp.func.html | 108 + .../ves/MD_LinearExpansionPES.cpp.gcov.html | 757 + coverage/ves/Opt_Adam.cpp.func-sort-c.html | 100 + coverage/ves/Opt_Adam.cpp.func.html | 100 + coverage/ves/Opt_Adam.cpp.gcov.html | 272 + .../Opt_BachAveragedSGD.cpp.func-sort-c.html | 100 + .../ves/Opt_BachAveragedSGD.cpp.func.html | 100 + .../ves/Opt_BachAveragedSGD.cpp.gcov.html | 378 + coverage/ves/Opt_Dummy.cpp.func-sort-c.html | 100 + coverage/ves/Opt_Dummy.cpp.func.html | 100 + coverage/ves/Opt_Dummy.cpp.gcov.html | 197 + .../Opt_RobbinsMonroSGD.cpp.func-sort-c.html | 100 + .../ves/Opt_RobbinsMonroSGD.cpp.func.html | 100 + .../ves/Opt_RobbinsMonroSGD.cpp.gcov.html | 172 + coverage/ves/Optimizer.cpp.func-sort-c.html | 200 + coverage/ves/Optimizer.cpp.func.html | 200 + coverage/ves/Optimizer.cpp.gcov.html | 1337 + coverage/ves/Optimizer.h.func-sort-c.html | 112 + coverage/ves/Optimizer.h.func.html | 112 + coverage/ves/Optimizer.h.gcov.html | 430 + .../OutputBasisFunctions.cpp.func-sort-c.html | 100 + .../ves/OutputBasisFunctions.cpp.func.html | 100 + .../ves/OutputBasisFunctions.cpp.gcov.html | 312 + .../ves/OutputFesBias.cpp.func-sort-c.html | 104 + coverage/ves/OutputFesBias.cpp.func.html | 104 + coverage/ves/OutputFesBias.cpp.gcov.html | 306 + ...putTargetDistribution.cpp.func-sort-c.html | 100 + .../OutputTargetDistribution.cpp.func.html | 100 + .../OutputTargetDistribution.cpp.gcov.html | 302 + coverage/ves/TD_Chi.cpp.func-sort-c.html | 96 + coverage/ves/TD_Chi.cpp.func.html | 96 + coverage/ves/TD_Chi.cpp.gcov.html | 229 + .../ves/TD_ChiSquared.cpp.func-sort-c.html | 96 + coverage/ves/TD_ChiSquared.cpp.func.html | 96 + coverage/ves/TD_ChiSquared.cpp.gcov.html | 228 + coverage/ves/TD_Custom.cpp.func-sort-c.html | 112 + coverage/ves/TD_Custom.cpp.func.html | 112 + coverage/ves/TD_Custom.cpp.gcov.html | 371 + .../ves/TD_Exponential.cpp.func-sort-c.html | 96 + coverage/ves/TD_Exponential.cpp.func.html | 96 + coverage/ves/TD_Exponential.cpp.gcov.html | 205 + ...iallyModifiedGaussian.cpp.func-sort-c.html | 100 + ...xponentiallyModifiedGaussian.cpp.func.html | 100 + ...xponentiallyModifiedGaussian.cpp.gcov.html | 300 + coverage/ves/TD_Gaussian.cpp.func-sort-c.html | 104 + coverage/ves/TD_Gaussian.cpp.func.html | 104 + coverage/ves/TD_Gaussian.cpp.gcov.html | 391 + ...neralizedExtremeValue.cpp.func-sort-c.html | 100 + .../TD_GeneralizedExtremeValue.cpp.func.html | 100 + .../TD_GeneralizedExtremeValue.cpp.gcov.html | 253 + .../TD_GeneralizedNormal.cpp.func-sort-c.html | 100 + .../ves/TD_GeneralizedNormal.cpp.func.html | 100 + .../ves/TD_GeneralizedNormal.cpp.gcov.html | 303 + coverage/ves/TD_Grid.cpp.func-sort-c.html | 96 + coverage/ves/TD_Grid.cpp.func.html | 96 + coverage/ves/TD_Grid.cpp.gcov.html | 294 + .../TD_LinearCombination.cpp.func-sort-c.html | 124 + .../ves/TD_LinearCombination.cpp.func.html | 124 + .../ves/TD_LinearCombination.cpp.gcov.html | 353 + .../TD_Multicanonical.cpp.func-sort-c.html | 108 + coverage/ves/TD_Multicanonical.cpp.func.html | 108 + coverage/ves/TD_Multicanonical.cpp.gcov.html | 551 + ...ultithermalMultibaric.cpp.func-sort-c.html | 108 + .../TD_MultithermalMultibaric.cpp.func.html | 108 + .../TD_MultithermalMultibaric.cpp.gcov.html | 534 + ...TD_ProductCombination.cpp.func-sort-c.html | 124 + .../ves/TD_ProductCombination.cpp.func.html | 124 + .../ves/TD_ProductCombination.cpp.gcov.html | 340 + ...D_ProductDistribution.cpp.func-sort-c.html | 124 + .../ves/TD_ProductDistribution.cpp.func.html | 124 + .../ves/TD_ProductDistribution.cpp.gcov.html | 301 + coverage/ves/TD_Uniform.cpp.func-sort-c.html | 100 + coverage/ves/TD_Uniform.cpp.func.html | 100 + coverage/ves/TD_Uniform.cpp.gcov.html | 381 + coverage/ves/TD_VonMises.cpp.func-sort-c.html | 104 + coverage/ves/TD_VonMises.cpp.func.html | 104 + coverage/ves/TD_VonMises.cpp.gcov.html | 315 + .../ves/TD_WellTempered.cpp.func-sort-c.html | 108 + coverage/ves/TD_WellTempered.cpp.func.html | 108 + coverage/ves/TD_WellTempered.cpp.gcov.html | 240 + .../ves/TargetDistModifer.h.func-sort-c.html | 76 + coverage/ves/TargetDistModifer.h.func.html | 76 + coverage/ves/TargetDistModifer.h.gcov.html | 129 + .../TargetDistribution.cpp.func-sort-c.html | 176 + coverage/ves/TargetDistribution.cpp.func.html | 176 + coverage/ves/TargetDistribution.cpp.gcov.html | 464 + .../ves/TargetDistribution.h.func-sort-c.html | 96 + coverage/ves/TargetDistribution.h.func.html | 96 + coverage/ves/TargetDistribution.h.gcov.html | 285 + coverage/ves/VesBias.cpp.func-sort-c.html | 252 + coverage/ves/VesBias.cpp.func.html | 252 + coverage/ves/VesBias.cpp.gcov.html | 837 + coverage/ves/VesBias.h.func-sort-c.html | 172 + coverage/ves/VesBias.h.func.html | 172 + coverage/ves/VesBias.h.gcov.html | 491 + coverage/ves/VesDeltaF.cpp.func-sort-c.html | 116 + coverage/ves/VesDeltaF.cpp.func.html | 116 + coverage/ves/VesDeltaF.cpp.gcov.html | 797 + .../VesLinearExpansion.cpp.func-sort-c.html | 168 + coverage/ves/VesLinearExpansion.cpp.func.html | 168 + coverage/ves/VesLinearExpansion.cpp.gcov.html | 633 + coverage/ves/VesTools.cpp.func-sort-c.html | 80 + coverage/ves/VesTools.cpp.func.html | 80 + coverage/ves/VesTools.cpp.gcov.html | 170 + coverage/ves/VesTools.h.func-sort-c.html | 92 + coverage/ves/VesTools.h.func.html | 92 + coverage/ves/VesTools.h.gcov.html | 216 + .../ves/WaveletCoeffs.cpp.func-sort-c.html | 76 + coverage/ves/WaveletCoeffs.cpp.func.html | 76 + coverage/ves/WaveletCoeffs.cpp.gcov.html | 1058 + coverage/ves/WaveletGrid.cpp.func-sort-c.html | 104 + coverage/ves/WaveletGrid.cpp.func.html | 104 + coverage/ves/WaveletGrid.cpp.gcov.html | 330 + coverage/ves/index-sort-f.html | 723 + coverage/ves/index-sort-l.html | 723 + coverage/ves/index.html | 723 + .../ActionWithAveraging.cpp.func-sort-c.html | 128 + .../ActionWithAveraging.cpp.func.html | 128 + .../ActionWithAveraging.cpp.gcov.html | 277 + .../ActionWithAveraging.h.func-sort-c.html | 100 + .../ActionWithAveraging.h.func.html | 100 + .../ActionWithAveraging.h.gcov.html | 212 + ...ActionWithInputVessel.cpp.func-sort-c.html | 96 + .../ActionWithInputVessel.cpp.func.html | 96 + .../ActionWithInputVessel.cpp.gcov.html | 164 + .../ActionWithInputVessel.h.func-sort-c.html | 76 + .../ActionWithInputVessel.h.func.html | 76 + .../ActionWithInputVessel.h.gcov.html | 146 + .../ActionWithVessel.cpp.func-sort-c.html | 176 + .../vesselbase/ActionWithVessel.cpp.func.html | 176 + .../vesselbase/ActionWithVessel.cpp.gcov.html | 471 + .../ActionWithVessel.h.func-sort-c.html | 96 + .../vesselbase/ActionWithVessel.h.func.html | 96 + .../vesselbase/ActionWithVessel.h.gcov.html | 367 + .../vesselbase/AltMin.cpp.func-sort-c.html | 108 + coverage/vesselbase/AltMin.cpp.func.html | 108 + coverage/vesselbase/AltMin.cpp.gcov.html | 153 + .../AveragingVessel.cpp.func-sort-c.html | 100 + .../vesselbase/AveragingVessel.cpp.func.html | 100 + .../vesselbase/AveragingVessel.cpp.gcov.html | 140 + .../AveragingVessel.h.func-sort-c.html | 80 + .../vesselbase/AveragingVessel.h.func.html | 80 + .../vesselbase/AveragingVessel.h.gcov.html | 177 + .../vesselbase/Between.cpp.func-sort-c.html | 108 + coverage/vesselbase/Between.cpp.func.html | 108 + coverage/vesselbase/Between.cpp.gcov.html | 155 + .../BridgeVessel.cpp.func-sort-c.html | 124 + .../vesselbase/BridgeVessel.cpp.func.html | 124 + .../vesselbase/BridgeVessel.cpp.gcov.html | 269 + .../BridgeVessel.h.func-sort-c.html | 72 + coverage/vesselbase/BridgeVessel.h.func.html | 72 + coverage/vesselbase/BridgeVessel.h.gcov.html | 167 + .../FunctionVessel.cpp.func-sort-c.html | 100 + .../vesselbase/FunctionVessel.cpp.func.html | 100 + .../vesselbase/FunctionVessel.cpp.gcov.html | 180 + .../FunctionVessel.h.func-sort-c.html | 72 + .../vesselbase/FunctionVessel.h.func.html | 72 + .../vesselbase/FunctionVessel.h.gcov.html | 142 + .../vesselbase/Highest.cpp.func-sort-c.html | 104 + coverage/vesselbase/Highest.cpp.func.html | 104 + coverage/vesselbase/Highest.cpp.gcov.html | 138 + .../vesselbase/Histogram.cpp.func-sort-c.html | 96 + coverage/vesselbase/Histogram.cpp.func.html | 96 + coverage/vesselbase/Histogram.cpp.gcov.html | 139 + .../vesselbase/LessThan.cpp.func-sort-c.html | 108 + coverage/vesselbase/LessThan.cpp.func.html | 108 + coverage/vesselbase/LessThan.cpp.gcov.html | 142 + .../vesselbase/Lowest.cpp.func-sort-c.html | 104 + coverage/vesselbase/Lowest.cpp.func.html | 104 + coverage/vesselbase/Lowest.cpp.gcov.html | 138 + coverage/vesselbase/Max.cpp.func-sort-c.html | 108 + coverage/vesselbase/Max.cpp.func.html | 108 + coverage/vesselbase/Max.cpp.gcov.html | 158 + coverage/vesselbase/Mean.cpp.func-sort-c.html | 104 + coverage/vesselbase/Mean.cpp.func.html | 104 + coverage/vesselbase/Mean.cpp.gcov.html | 142 + coverage/vesselbase/Min.cpp.func-sort-c.html | 108 + coverage/vesselbase/Min.cpp.func.html | 108 + coverage/vesselbase/Min.cpp.gcov.html | 158 + .../vesselbase/Moments.cpp.func-sort-c.html | 116 + coverage/vesselbase/Moments.cpp.func.html | 116 + coverage/vesselbase/Moments.cpp.gcov.html | 267 + .../vesselbase/MoreThan.cpp.func-sort-c.html | 104 + coverage/vesselbase/MoreThan.cpp.func.html | 104 + coverage/vesselbase/MoreThan.cpp.gcov.html | 152 + .../OrderingVessel.cpp.func-sort-c.html | 88 + .../vesselbase/OrderingVessel.cpp.func.html | 88 + .../vesselbase/OrderingVessel.cpp.gcov.html | 147 + .../OrderingVessel.h.func-sort-c.html | 76 + .../vesselbase/OrderingVessel.h.func.html | 76 + .../vesselbase/OrderingVessel.h.gcov.html | 126 + .../ShortcutVessel.cpp.func-sort-c.html | 84 + .../vesselbase/ShortcutVessel.cpp.func.html | 84 + .../vesselbase/ShortcutVessel.cpp.gcov.html | 123 + .../ShortcutVessel.h.func-sort-c.html | 92 + .../vesselbase/ShortcutVessel.h.func.html | 92 + .../vesselbase/ShortcutVessel.h.gcov.html | 126 + .../StoreDataVessel.cpp.func-sort-c.html | 132 + .../vesselbase/StoreDataVessel.cpp.func.html | 132 + .../vesselbase/StoreDataVessel.cpp.gcov.html | 255 + .../StoreDataVessel.h.func-sort-c.html | 100 + .../vesselbase/StoreDataVessel.h.func.html | 100 + .../vesselbase/StoreDataVessel.h.gcov.html | 286 + coverage/vesselbase/Sum.cpp.func-sort-c.html | 104 + coverage/vesselbase/Sum.cpp.func.html | 104 + coverage/vesselbase/Sum.cpp.gcov.html | 138 + .../ValueVessel.cpp.func-sort-c.html | 88 + coverage/vesselbase/ValueVessel.cpp.func.html | 88 + coverage/vesselbase/ValueVessel.cpp.gcov.html | 148 + .../vesselbase/ValueVessel.h.func-sort-c.html | 72 + coverage/vesselbase/ValueVessel.h.func.html | 72 + coverage/vesselbase/ValueVessel.h.gcov.html | 150 + .../vesselbase/Vessel.cpp.func-sort-c.html | 116 + coverage/vesselbase/Vessel.cpp.func.html | 116 + coverage/vesselbase/Vessel.cpp.gcov.html | 226 + coverage/vesselbase/Vessel.h.func-sort-c.html | 112 + coverage/vesselbase/Vessel.h.func.html | 112 + coverage/vesselbase/Vessel.h.gcov.html | 321 + .../VesselRegister.cpp.func-sort-c.html | 100 + .../vesselbase/VesselRegister.cpp.func.html | 100 + .../vesselbase/VesselRegister.cpp.gcov.html | 156 + coverage/vesselbase/index-sort-f.html | 433 + coverage/vesselbase/index-sort-l.html | 433 + coverage/vesselbase/index.html | 433 + coverage/wrapper/Plumed.h.func-sort-c.html | 1080 + coverage/wrapper/Plumed.h.func.html | 1080 + coverage/wrapper/Plumed.h.gcov.html | 4315 +++ coverage/wrapper/index-sort-f.html | 93 + coverage/wrapper/index-sort-l.html | 93 + coverage/wrapper/index.html | 93 + index.html | 14 + 2195 files changed, 500467 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/GenJson.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenJson.cpp.func.html create mode 100644 coverage/cltools/GenJson.cpp.gcov.html create mode 100644 coverage/cltools/GenTemplate.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenTemplate.cpp.func.html create mode 100644 coverage/cltools/GenTemplate.cpp.gcov.html create mode 100644 coverage/cltools/Info.cpp.func-sort-c.html create mode 100644 coverage/cltools/Info.cpp.func.html create mode 100644 coverage/cltools/Info.cpp.gcov.html create mode 100644 coverage/cltools/Manual.cpp.func-sort-c.html create mode 100644 coverage/cltools/Manual.cpp.func.html create mode 100644 coverage/cltools/Manual.cpp.gcov.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func-sort-c.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func.html create mode 100644 coverage/cltools/PdbRenumber.cpp.gcov.html create mode 100644 coverage/cltools/SimpleMD.cpp.func-sort-c.html create mode 100644 coverage/cltools/SimpleMD.cpp.func.html create mode 100644 coverage/cltools/SimpleMD.cpp.gcov.html create mode 100644 coverage/cltools/SumHills.cpp.func-sort-c.html create mode 100644 coverage/cltools/SumHills.cpp.func.html create mode 100644 coverage/cltools/SumHills.cpp.gcov.html create mode 100644 coverage/cltools/index-sort-f.html create mode 100644 coverage/cltools/index-sort-l.html create mode 100644 coverage/cltools/index.html create mode 100644 coverage/cltools/kT.cpp.func-sort-c.html create mode 100644 coverage/cltools/kT.cpp.func.html create mode 100644 coverage/cltools/kT.cpp.gcov.html create mode 100644 coverage/cltools/pesmd.cpp.func-sort-c.html create mode 100644 coverage/cltools/pesmd.cpp.func.html create mode 100644 coverage/cltools/pesmd.cpp.gcov.html create mode 100644 coverage/colvar/Angle.cpp.func-sort-c.html create mode 100644 coverage/colvar/Angle.cpp.func.html create mode 100644 coverage/colvar/Angle.cpp.gcov.html create mode 100644 coverage/colvar/Cell.cpp.func-sort-c.html create mode 100644 coverage/colvar/Cell.cpp.func.html create mode 100644 coverage/colvar/Cell.cpp.gcov.html create mode 100644 coverage/colvar/Constant.cpp.func-sort-c.html create mode 100644 coverage/colvar/Constant.cpp.func.html create mode 100644 coverage/colvar/Constant.cpp.gcov.html create mode 100644 coverage/colvar/ContactMap.cpp.func-sort-c.html create mode 100644 coverage/colvar/ContactMap.cpp.func.html create mode 100644 coverage/colvar/ContactMap.cpp.gcov.html create mode 100644 coverage/colvar/Coordination.cpp.func-sort-c.html create mode 100644 coverage/colvar/Coordination.cpp.func.html create mode 100644 coverage/colvar/Coordination.cpp.gcov.html create mode 100644 coverage/colvar/CoordinationBase.cpp.func-sort-c.html create mode 100644 coverage/colvar/CoordinationBase.cpp.func.html create mode 100644 coverage/colvar/CoordinationBase.cpp.gcov.html create mode 100644 coverage/colvar/DHEnergy.cpp.func-sort-c.html create mode 100644 coverage/colvar/DHEnergy.cpp.func.html create mode 100644 coverage/colvar/DHEnergy.cpp.gcov.html create mode 100644 coverage/colvar/DRMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/DRMSD.cpp.func.html create mode 100644 coverage/colvar/DRMSD.cpp.gcov.html create mode 100644 coverage/colvar/Dimer.cpp.func-sort-c.html create mode 100644 coverage/colvar/Dimer.cpp.func.html create mode 100644 coverage/colvar/Dimer.cpp.gcov.html create mode 100644 coverage/colvar/Dipole.cpp.func-sort-c.html create mode 100644 coverage/colvar/Dipole.cpp.func.html create mode 100644 coverage/colvar/Dipole.cpp.gcov.html create mode 100644 coverage/colvar/Distance.cpp.func-sort-c.html create mode 100644 coverage/colvar/Distance.cpp.func.html create mode 100644 coverage/colvar/Distance.cpp.gcov.html create mode 100644 coverage/colvar/EEFSolv.cpp.func-sort-c.html create mode 100644 coverage/colvar/EEFSolv.cpp.func.html create mode 100644 coverage/colvar/EEFSolv.cpp.gcov.html create mode 100644 coverage/colvar/ERMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/ERMSD.cpp.func.html create mode 100644 coverage/colvar/ERMSD.cpp.gcov.html create mode 100644 coverage/colvar/Energy.cpp.func-sort-c.html create mode 100644 coverage/colvar/Energy.cpp.func.html create mode 100644 coverage/colvar/Energy.cpp.gcov.html create mode 100644 coverage/colvar/ExtraCV.cpp.func-sort-c.html create mode 100644 coverage/colvar/ExtraCV.cpp.func.html create mode 100644 coverage/colvar/ExtraCV.cpp.gcov.html create mode 100644 coverage/colvar/Fake.cpp.func-sort-c.html create mode 100644 coverage/colvar/Fake.cpp.func.html create mode 100644 coverage/colvar/Fake.cpp.gcov.html create mode 100644 coverage/colvar/GHBFIX.cpp.func-sort-c.html create mode 100644 coverage/colvar/GHBFIX.cpp.func.html create mode 100644 coverage/colvar/GHBFIX.cpp.gcov.html create mode 100644 coverage/colvar/Gyration.cpp.func-sort-c.html create mode 100644 coverage/colvar/Gyration.cpp.func.html create mode 100644 coverage/colvar/Gyration.cpp.gcov.html create mode 100644 coverage/colvar/MultiRMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/MultiRMSD.cpp.func.html create mode 100644 coverage/colvar/MultiRMSD.cpp.gcov.html create mode 100644 coverage/colvar/PCARMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/PCARMSD.cpp.func.html create mode 100644 coverage/colvar/PCARMSD.cpp.gcov.html create mode 100644 coverage/colvar/PathMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/PathMSD.cpp.func.html create mode 100644 coverage/colvar/PathMSD.cpp.gcov.html create mode 100644 coverage/colvar/PathMSDBase.cpp.func-sort-c.html create mode 100644 coverage/colvar/PathMSDBase.cpp.func.html create mode 100644 coverage/colvar/PathMSDBase.cpp.gcov.html create mode 100644 coverage/colvar/PathMSDBase.h.func-sort-c.html create mode 100644 coverage/colvar/PathMSDBase.h.func.html create mode 100644 coverage/colvar/PathMSDBase.h.gcov.html create mode 100644 coverage/colvar/Position.cpp.func-sort-c.html create mode 100644 coverage/colvar/Position.cpp.func.html create mode 100644 coverage/colvar/Position.cpp.gcov.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.func.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.gcov.html create mode 100644 coverage/colvar/PropertyMap.cpp.func-sort-c.html create mode 100644 coverage/colvar/PropertyMap.cpp.func.html create mode 100644 coverage/colvar/PropertyMap.cpp.gcov.html create mode 100644 coverage/colvar/Puckering.cpp.func-sort-c.html create mode 100644 coverage/colvar/Puckering.cpp.func.html create mode 100644 coverage/colvar/Puckering.cpp.gcov.html create mode 100644 coverage/colvar/RMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/RMSD.cpp.func.html create mode 100644 coverage/colvar/RMSD.cpp.gcov.html create mode 100644 coverage/colvar/Template.cpp.func-sort-c.html create mode 100644 coverage/colvar/Template.cpp.func.html create mode 100644 coverage/colvar/Template.cpp.gcov.html create mode 100644 coverage/colvar/Torsion.cpp.func-sort-c.html create mode 100644 coverage/colvar/Torsion.cpp.func.html create mode 100644 coverage/colvar/Torsion.cpp.gcov.html create mode 100644 coverage/colvar/Volume.cpp.func-sort-c.html create mode 100644 coverage/colvar/Volume.cpp.func.html create mode 100644 coverage/colvar/Volume.cpp.gcov.html create mode 100644 coverage/colvar/index-sort-f.html create mode 100644 coverage/colvar/index-sort-l.html create mode 100644 coverage/colvar/index.html create mode 100644 coverage/config/Config.inc.func-sort-c.html create mode 100644 coverage/config/Config.inc.func.html create mode 100644 coverage/config/Config.inc.gcov.html create mode 100644 coverage/config/ConfigInstall.inc.func-sort-c.html create mode 100644 coverage/config/ConfigInstall.inc.func.html create mode 100644 coverage/config/ConfigInstall.inc.gcov.html create mode 100644 coverage/config/index-sort-f.html create mode 100644 coverage/config/index-sort-l.html create mode 100644 coverage/config/index.html create mode 100644 coverage/core/Action.cpp.func-sort-c.html create mode 100644 coverage/core/Action.cpp.func.html create mode 100644 coverage/core/Action.cpp.gcov.html create mode 100644 coverage/core/Action.h.func-sort-c.html create mode 100644 coverage/core/Action.h.func.html create mode 100644 coverage/core/Action.h.gcov.html create mode 100644 coverage/core/ActionAnyorder.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.cpp.func.html create mode 100644 coverage/core/ActionAnyorder.cpp.gcov.html create mode 100644 coverage/core/ActionAnyorder.h.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.h.func.html create mode 100644 coverage/core/ActionAnyorder.h.gcov.html create mode 100644 coverage/core/ActionAtomistic.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.cpp.func.html create mode 100644 coverage/core/ActionAtomistic.cpp.gcov.html create mode 100644 coverage/core/ActionAtomistic.h.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.h.func.html create mode 100644 coverage/core/ActionAtomistic.h.gcov.html create mode 100644 coverage/core/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/ModuleMap.cpp.func-sort-c.html create mode 100644 coverage/core/ModuleMap.cpp.func.html create mode 100644 coverage/core/ModuleMap.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/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/FusionPoreExpansionP.cpp.func.html create mode 100644 coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.func.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.func.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.gcov.html create mode 100644 coverage/membranefusion/index-sort-f.html create mode 100644 coverage/membranefusion/index-sort-l.html create mode 100644 coverage/membranefusion/index.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.func.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.gcov.html create mode 100644 coverage/multicolvar/ActionVolume.h.func-sort-c.html create mode 100644 coverage/multicolvar/ActionVolume.h.func.html create mode 100644 coverage/multicolvar/ActionVolume.h.gcov.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.gcov.html create mode 100644 coverage/multicolvar/Angles.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Angles.cpp.func.html create mode 100644 coverage/multicolvar/Angles.cpp.gcov.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.func.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.gcov.html create mode 100644 coverage/multicolvar/AtomValuePack.h.func-sort-c.html create mode 100644 coverage/multicolvar/AtomValuePack.h.func.html create mode 100644 coverage/multicolvar/AtomValuePack.h.gcov.html create mode 100644 coverage/multicolvar/Bridge.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Bridge.cpp.func.html create mode 100644 coverage/multicolvar/Bridge.cpp.gcov.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.func.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html create mode 100644 coverage/multicolvar/CatomPack.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CatomPack.cpp.func.html create mode 100644 coverage/multicolvar/CatomPack.cpp.gcov.html create mode 100644 coverage/multicolvar/CatomPack.h.func-sort-c.html create mode 100644 coverage/multicolvar/CatomPack.h.func.html create mode 100644 coverage/multicolvar/CatomPack.h.gcov.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.func.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.func.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.gcov.html create mode 100644 coverage/multicolvar/Density.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Density.cpp.func.html create mode 100644 coverage/multicolvar/Density.cpp.gcov.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.func.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.gcov.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.func.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.gcov.html create mode 100644 coverage/multicolvar/Distances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Distances.cpp.func.html create mode 100644 coverage/multicolvar/Distances.cpp.gcov.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.func.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.func.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.func.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.func.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.gcov.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.func.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.func.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.func.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.gcov.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.func.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.gcov.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.gcov.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.func.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.gcov.html create mode 100644 coverage/multicolvar/Torsions.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Torsions.cpp.func.html create mode 100644 coverage/multicolvar/Torsions.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.func.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.func.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.func.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.func.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.func.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.gcov.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.func.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.func.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.func.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.gcov.html create mode 100644 coverage/multicolvar/XAngle.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XAngle.cpp.func.html create mode 100644 coverage/multicolvar/XAngle.cpp.gcov.html create mode 100644 coverage/multicolvar/XDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XDistances.cpp.func.html create mode 100644 coverage/multicolvar/XDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/XYDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XYDistances.cpp.func.html create mode 100644 coverage/multicolvar/XYDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.func.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.gcov.html create mode 100644 coverage/multicolvar/index-sort-f.html create mode 100644 coverage/multicolvar/index-sort-l.html create mode 100644 coverage/multicolvar/index.html create mode 100644 coverage/opes/ECVcustom.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVcustom.cpp.func.html create mode 100644 coverage/opes/ECVcustom.cpp.gcov.html create mode 100644 coverage/opes/ECVlinear.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVlinear.cpp.func.html create mode 100644 coverage/opes/ECVlinear.cpp.gcov.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.func.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.gcov.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.func.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.gcov.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.func.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.gcov.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.func.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.gcov.html create mode 100644 coverage/opes/ExpansionCVs.cpp.func-sort-c.html create mode 100644 coverage/opes/ExpansionCVs.cpp.func.html create mode 100644 coverage/opes/ExpansionCVs.cpp.gcov.html create mode 100644 coverage/opes/ExpansionCVs.h.func-sort-c.html create mode 100644 coverage/opes/ExpansionCVs.h.func.html create mode 100644 coverage/opes/ExpansionCVs.h.gcov.html create mode 100644 coverage/opes/OPESexpanded.cpp.func-sort-c.html create mode 100644 coverage/opes/OPESexpanded.cpp.func.html create mode 100644 coverage/opes/OPESexpanded.cpp.gcov.html create mode 100644 coverage/opes/OPESmetad.cpp.func-sort-c.html create mode 100644 coverage/opes/OPESmetad.cpp.func.html create mode 100644 coverage/opes/OPESmetad.cpp.gcov.html create mode 100644 coverage/opes/index-sort-f.html create mode 100644 coverage/opes/index-sort-l.html create mode 100644 coverage/opes/index.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.func.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.gcov.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.func.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.gcov.html create mode 100644 coverage/pamm/HBPammObject.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammObject.cpp.func.html create mode 100644 coverage/pamm/HBPammObject.cpp.gcov.html create mode 100644 coverage/pamm/HBPammObject.h.func-sort-c.html create mode 100644 coverage/pamm/HBPammObject.h.func.html create mode 100644 coverage/pamm/HBPammObject.h.gcov.html create mode 100644 coverage/pamm/PAMM.cpp.func-sort-c.html create mode 100644 coverage/pamm/PAMM.cpp.func.html create mode 100644 coverage/pamm/PAMM.cpp.gcov.html create mode 100644 coverage/pamm/PammObject.cpp.func-sort-c.html create mode 100644 coverage/pamm/PammObject.cpp.func.html create mode 100644 coverage/pamm/PammObject.cpp.gcov.html create mode 100644 coverage/pamm/PammObject.h.func-sort-c.html create mode 100644 coverage/pamm/PammObject.h.func.html create mode 100644 coverage/pamm/PammObject.h.gcov.html create mode 100644 coverage/pamm/index-sort-f.html create mode 100644 coverage/pamm/index-sort-l.html create mode 100644 coverage/pamm/index.html create mode 100644 coverage/piv/PIV.cpp.func-sort-c.html create mode 100644 coverage/piv/PIV.cpp.func.html create mode 100644 coverage/piv/PIV.cpp.gcov.html create mode 100644 coverage/piv/index-sort-f.html create mode 100644 coverage/piv/index-sort-l.html create mode 100644 coverage/piv/index.html create mode 100644 coverage/pytorch/PytorchModel.cpp.func-sort-c.html create mode 100644 coverage/pytorch/PytorchModel.cpp.func.html create mode 100644 coverage/pytorch/PytorchModel.cpp.gcov.html create mode 100644 coverage/pytorch/index-sort-f.html create mode 100644 coverage/pytorch/index-sort-l.html create mode 100644 coverage/pytorch/index.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.func.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.gcov.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.func.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.gcov.html create mode 100644 coverage/reference/DRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/DRMSD.cpp.func.html create mode 100644 coverage/reference/DRMSD.cpp.gcov.html create mode 100644 coverage/reference/Direction.cpp.func-sort-c.html create mode 100644 coverage/reference/Direction.cpp.func.html create mode 100644 coverage/reference/Direction.cpp.gcov.html create mode 100644 coverage/reference/Direction.h.func-sort-c.html create mode 100644 coverage/reference/Direction.h.func.html create mode 100644 coverage/reference/Direction.h.gcov.html create mode 100644 coverage/reference/DotProductDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/DotProductDistance.cpp.func.html create mode 100644 coverage/reference/DotProductDistance.cpp.gcov.html create mode 100644 coverage/reference/EuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/EuclideanDistance.cpp.func.html create mode 100644 coverage/reference/EuclideanDistance.cpp.gcov.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.func.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.gcov.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.func.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.gcov.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.func.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.gcov.html create mode 100644 coverage/reference/MetricRegister.cpp.func-sort-c.html create mode 100644 coverage/reference/MetricRegister.cpp.func.html create mode 100644 coverage/reference/MetricRegister.cpp.gcov.html create mode 100644 coverage/reference/MetricRegister.h.func-sort-c.html create mode 100644 coverage/reference/MetricRegister.h.func.html create mode 100644 coverage/reference/MetricRegister.h.gcov.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.func.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.gcov.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.func.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html create mode 100644 coverage/reference/OptimalRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/OptimalRMSD.cpp.func.html create mode 100644 coverage/reference/OptimalRMSD.cpp.gcov.html create mode 100644 coverage/reference/RMSDBase.cpp.func-sort-c.html create mode 100644 coverage/reference/RMSDBase.cpp.func.html create mode 100644 coverage/reference/RMSDBase.cpp.gcov.html create mode 100644 coverage/reference/ReferenceArguments.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceArguments.cpp.func.html create mode 100644 coverage/reference/ReferenceArguments.cpp.gcov.html create mode 100644 coverage/reference/ReferenceArguments.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceArguments.h.func.html create mode 100644 coverage/reference/ReferenceArguments.h.gcov.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.func.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.gcov.html create mode 100644 coverage/reference/ReferenceAtoms.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceAtoms.h.func.html create mode 100644 coverage/reference/ReferenceAtoms.h.gcov.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.func.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.gcov.html create mode 100644 coverage/reference/ReferenceConfiguration.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceConfiguration.h.func.html create mode 100644 coverage/reference/ReferenceConfiguration.h.gcov.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.func.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.gcov.html create mode 100644 coverage/reference/ReferenceValuePack.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceValuePack.h.func.html create mode 100644 coverage/reference/ReferenceValuePack.h.gcov.html create mode 100644 coverage/reference/SimpleRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/SimpleRMSD.cpp.func.html create mode 100644 coverage/reference/SimpleRMSD.cpp.gcov.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.func.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.gcov.html create mode 100644 coverage/reference/SingleDomainRMSD.h.func-sort-c.html create mode 100644 coverage/reference/SingleDomainRMSD.h.func.html create mode 100644 coverage/reference/SingleDomainRMSD.h.gcov.html create mode 100644 coverage/reference/index-sort-f.html create mode 100644 coverage/reference/index-sort-l.html create mode 100644 coverage/reference/index.html create mode 100644 coverage/ruby.png create mode 100644 coverage/s2cm/S2ContactModel.cpp.func-sort-c.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.func.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.gcov.html create mode 100644 coverage/s2cm/index-sort-f.html create mode 100644 coverage/s2cm/index-sort-l.html create mode 100644 coverage/s2cm/index.html create mode 100644 coverage/sasa/index-sort-f.html create mode 100644 coverage/sasa/index-sort-l.html create mode 100644 coverage/sasa/index.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.gcov.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.gcov.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html create mode 100644 coverage/secondarystructure/index-sort-f.html create mode 100644 coverage/secondarystructure/index-sort-l.html create mode 100644 coverage/secondarystructure/index.html create mode 100644 coverage/setup/Load.cpp.func-sort-c.html create mode 100644 coverage/setup/Load.cpp.func.html create mode 100644 coverage/setup/Load.cpp.gcov.html create mode 100644 coverage/setup/Restart.cpp.func-sort-c.html create mode 100644 coverage/setup/Restart.cpp.func.html create mode 100644 coverage/setup/Restart.cpp.gcov.html create mode 100644 coverage/setup/Units.cpp.func-sort-c.html create mode 100644 coverage/setup/Units.cpp.func.html create mode 100644 coverage/setup/Units.cpp.gcov.html create mode 100644 coverage/setup/index-sort-f.html create mode 100644 coverage/setup/index-sort-l.html create mode 100644 coverage/setup/index.html create mode 100644 coverage/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..ebe4c07831 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Coverage scan for PLUMED v2.9 +----------------------------- + +This repository hosts the coverage scan for [PLUMED](http://www.plumed.org) v2.9, +git revision [eabfee2](https://github.com/plumed/plumed2/commit/eabfee2). + +Coverage scan done on [GiHub actions](http://github.com/plumed/plumed2/actions) on Mon May 27 13:05:17 UTC 2024. + +To browse the scan you should go [here](http://plumed.github.io/coverage-v2.9). + +You can also download a full copy of the scan for offline access +at [this link](http://github.com/plumed/coverage-v2.9/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-05-27 13:05:16Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj70
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.func.html b/coverage-libs/asmjit/arch.cpp.func.html new file mode 100644 index 0000000000..e8f9d63009 --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj70
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.gcov.html b/coverage-libs/asmjit/arch.cpp.gcov.html new file mode 100644 index 0000000000..bf6db2d728 --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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-05-27 13:05:16Functions:22100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.func.html b/coverage-libs/asmjit/arch.h.func.html new file mode 100644 index 0000000000..067b4c8844 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.gcov.html b/coverage-libs/asmjit/arch.h.gcov.html new file mode 100644 index 0000000000..a13f9ba075 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.gcov.html @@ -0,0 +1,304 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9Assembler10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit9Assembler11_emitFailedEjjjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit9AssemblerC2Ev1948
_ZN4PLMD6asmjit9AssemblerD2Ev1948
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3896
_ZN4PLMD6asmjit9Assembler4syncEv3896
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em48362
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func.html b/coverage-libs/asmjit/assembler.cpp.func.html new file mode 100644 index 0000000000..f503603178 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05:16Functions:61833.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9Assembler10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit9Assembler11_emitFailedEjjjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em48362
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3896
_ZN4PLMD6asmjit9Assembler4syncEv3896
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerC2Ev1948
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9AssemblerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.gcov.html b/coverage-libs/asmjit/assembler.cpp.gcov.html new file mode 100644 index 0000000000..83b16599c2 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.gcov.html @@ -0,0 +1,549 @@ + + + + + + + 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-05-27 13:05:16Functions:61833.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.func.html b/coverage-libs/asmjit/assembler.h.func.html new file mode 100644 index 0000000000..b0e7278957 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.gcov.html b/coverage-libs/asmjit/assembler.h.gcov.html new file mode 100644 index 0000000000..aac2b79bba --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.gcov.html @@ -0,0 +1,259 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeBuilder10deletePassEPNS0_6CBPassE0
_ZN4PLMD6asmjit11CodeBuilder10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder10getCBLabelEPPNS0_7CBLabelEj0
_ZN4PLMD6asmjit11CodeBuilder10removeNodeEPNS0_6CBNodeE0
_ZN4PLMD6asmjit11CodeBuilder11newDataNodeEPKvj0
_ZN4PLMD6asmjit11CodeBuilder11removeNodesEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder12newAlignNodeEjj0
_ZN4PLMD6asmjit11CodeBuilder12newConstPoolEv0
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1948
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1948
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1948
_ZN4PLMD6asmjit11CodeBuilderC2Ev1948
_ZN4PLMD6asmjit11CodeBuilderD2Ev1948
_ZN4PLMD6asmjit6CBPassC2EPKc1948
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3896
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3896
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56154
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func.html b/coverage-libs/asmjit/codebuilder.cpp.func.html new file mode 100644 index 0000000000..cadf3ebba5 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func.html @@ -0,0 +1,204 @@ + + + + + + + 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-05-27 13:05:16Functions:103330.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeBuilder10deletePassEPNS0_6CBPassE0
_ZN4PLMD6asmjit11CodeBuilder10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder10getCBLabelEPPNS0_7CBLabelEj0
_ZN4PLMD6asmjit11CodeBuilder10removeNodeEPNS0_6CBNodeE0
_ZN4PLMD6asmjit11CodeBuilder11newDataNodeEPKvj0
_ZN4PLMD6asmjit11CodeBuilder11removeNodesEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder12newAlignNodeEjj0
_ZN4PLMD6asmjit11CodeBuilder12newConstPoolEv0
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1948
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3896
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56154
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1948
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1948
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3896
_ZN4PLMD6asmjit11CodeBuilderC2Ev1948
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit11CodeBuilderD2Ev1948
_ZN4PLMD6asmjit6CBPassC2EPKc1948
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.gcov.html b/coverage-libs/asmjit/codebuilder.cpp.gcov.html new file mode 100644 index 0000000000..dd675d08f1 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.gcov.html @@ -0,0 +1,686 @@ + + + + + + + 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-05-27 13:05:16Functions:103330.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.func.html b/coverage-libs/asmjit/codebuilder.h.func.html new file mode 100644 index 0000000000..fa2afd75fe --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.gcov.html b/coverage-libs/asmjit/codebuilder.h.gcov.html new file mode 100644 index 0000000000..fd1499956e --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.gcov.html @@ -0,0 +1,1020 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12CodeCompiler11newHintNodeERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler11setPriorityERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler14setSaveOnUnuseERNS0_3RegEb0
_ZN4PLMD6asmjit12CodeCompiler4saveERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5_hintERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegERKS2_0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler5spillERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5unuseERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E1648
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1870
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1948
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12CodeCompilerC2Ev1948
_ZN4PLMD6asmjit12CodeCompilerD2Ev1948
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23788
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func.html b/coverage-libs/asmjit/codecompiler.cpp.func.html new file mode 100644 index 0000000000..29c0d6a864 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + 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-05-27 13:05:16Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1870
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E1648
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23788
_ZN4PLMD6asmjit12CodeCompiler11newHintNodeERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler11setPriorityERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler14setSaveOnUnuseERNS0_3RegEb0
_ZN4PLMD6asmjit12CodeCompiler4saveERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5_hintERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegERKS2_0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler5spillERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5unuseERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23788
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1948
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerC2Ev1948
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZN4PLMD6asmjit12CodeCompilerD2Ev1948
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.gcov.html b/coverage-libs/asmjit/codecompiler.cpp.gcov.html new file mode 100644 index 0000000000..70e6056739 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.gcov.html @@ -0,0 +1,675 @@ + + + + + + + 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-05-27 13:05:16Functions:153641.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.func.html b/coverage-libs/asmjit/codecompiler.h.func.html new file mode 100644 index 0000000000..0214190d4e --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.gcov.html b/coverage-libs/asmjit/codecompiler.h.gcov.html new file mode 100644 index 0000000000..73a878a671 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.gcov.html @@ -0,0 +1,843 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_120
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_Ei932
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El932
_ZN4PLMD6asmjit11CodeEmitter4emitEj1948
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2240
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE3896
_ZN4PLMD6asmjit11CodeEmitterC2Ej3896
_ZN4PLMD6asmjit11CodeEmitterD2Ev3896
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40542
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func.html b/coverage-libs/asmjit/codeemitter.cpp.func.html new file mode 100644 index 0000000000..6603720da2 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func.html @@ -0,0 +1,196 @@ + + + + + + + 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-05-27 13:05:16Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEj1948
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2240
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40542
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_120
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_Ei932
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El932
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE3896
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterC2Ej3896
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZN4PLMD6asmjit11CodeEmitterD2Ev3896
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.gcov.html b/coverage-libs/asmjit/codeemitter.cpp.gcov.html new file mode 100644 index 0000000000..959001f4e0 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.gcov.html @@ -0,0 +1,338 @@ + + + + + + + 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-05-27 13:05:16Functions:93129.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.func.html b/coverage-libs/asmjit/codeemitter.h.func.html new file mode 100644 index 0000000000..10ddffc80c --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.gcov.html b/coverage-libs/asmjit/codeemitter.h.gcov.html new file mode 100644 index 0000000000..0a0cf9959b --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.gcov.html @@ -0,0 +1,604 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1948
_ZN4PLMD6asmjit10CodeHolderC2Ev1948
_ZN4PLMD6asmjit10CodeHolderD2Ev1948
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1948
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1948
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1948
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3896
_ZN4PLMD6asmjit10CodeHolder4syncEv3896
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3896
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func.html b/coverage-libs/asmjit/codeholder.cpp.func.html new file mode 100644 index 0000000000..24c05a9ee7 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05:16Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3896
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1948
_ZN4PLMD6asmjit10CodeHolder4syncEv3896
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit10CodeHolderC2Ev1948
_ZN4PLMD6asmjit10CodeHolderD2Ev1948
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1948
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3896
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.gcov.html b/coverage-libs/asmjit/codeholder.cpp.gcov.html new file mode 100644 index 0000000000..ece06ad946 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.gcov.html @@ -0,0 +1,799 @@ + + + + + + + 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-05-27 13:05:16Functions:122548.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.func.html b/coverage-libs/asmjit/codeholder.h.func.html new file mode 100644 index 0000000000..f1fbc8b3d7 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.gcov.html b/coverage-libs/asmjit/codeholder.h.gcov.html new file mode 100644 index 0000000000..1cd36e7d11 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.gcov.html @@ -0,0 +1,853 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9ConstPool3addEPKvmRm0
_ZN4PLMD6asmjit9ConstPool4Tree3getEPKv0
_ZN4PLMD6asmjit9ConstPool4Tree3putEPNS1_4NodeE0
_ZN4PLMD6asmjit9ConstPool5resetEPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolC2EPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolD2Ev0
_ZN4PLMD6asmjitL16ConstPool_addGapEPNS0_9ConstPoolEmm0
_ZNK4PLMD6asmjit9ConstPool4fillEPv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.func.html b/coverage-libs/asmjit/constpool.cpp.func.html new file mode 100644 index 0000000000..0d3570f51c --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:16Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9ConstPool3addEPKvmRm0
_ZN4PLMD6asmjit9ConstPool4Tree3getEPKv0
_ZN4PLMD6asmjit9ConstPool4Tree3putEPNS1_4NodeE0
_ZN4PLMD6asmjit9ConstPool5resetEPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolC2EPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolD2Ev0
_ZN4PLMD6asmjitL16ConstPool_addGapEPNS0_9ConstPoolEmm0
_ZNK4PLMD6asmjit9ConstPool4fillEPv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.gcov.html b/coverage-libs/asmjit/constpool.cpp.gcov.html new file mode 100644 index 0000000000..9f4d278dfd --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.gcov.html @@ -0,0 +1,613 @@ + + + + + + + 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-05-27 13:05:16Functions:080.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.func.html b/coverage-libs/asmjit/constpool.h.func.html new file mode 100644 index 0000000000..03cda89836 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.gcov.html b/coverage-libs/asmjit/constpool.h.gcov.html new file mode 100644 index 0000000000..acc7d974b5 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.gcov.html @@ -0,0 +1,362 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv70
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE70
_ZN4PLMD6asmjit7CpuInfo7getHostEv1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.func.html b/coverage-libs/asmjit/cpuinfo.cpp.func.html new file mode 100644 index 0000000000..dc9765b01a --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:16Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv70
_ZN4PLMD6asmjit7CpuInfo7getHostEv1976
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE70
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.gcov.html b/coverage-libs/asmjit/cpuinfo.cpp.gcov.html new file mode 100644 index 0000000000..633aa25b3a --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.gcov.html @@ -0,0 +1,776 @@ + + + + + + + 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-05-27 13:05:16Functions:33100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.func.html b/coverage-libs/asmjit/cpuinfo.h.func.html new file mode 100644 index 0000000000..dd2ddabe2b --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.gcov.html b/coverage-libs/asmjit/cpuinfo.h.gcov.html new file mode 100644 index 0000000000..d2fc772805 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.gcov.html @@ -0,0 +1,478 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3596
_ZN4PLMD6asmjit8CallConv4initEj3596
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func.html b/coverage-libs/asmjit/func.cpp.func.html new file mode 100644 index 0000000000..468768b635 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3596
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit8CallConv4initEj3596
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.gcov.html b/coverage-libs/asmjit/func.cpp.gcov.html new file mode 100644 index 0000000000..c48eb45111 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.gcov.html @@ -0,0 +1,288 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.func.html b/coverage-libs/asmjit/func.h.func.html new file mode 100644 index 0000000000..b2ea7c7ed1 --- /dev/null +++ b/coverage-libs/asmjit/func.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.gcov.html b/coverage-libs/asmjit/func.h.gcov.html new file mode 100644 index 0000000000..ddc087d5ae --- /dev/null +++ b/coverage-libs/asmjit/func.h.gcov.html @@ -0,0 +1,1403 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.func.html b/coverage-libs/asmjit/globals.cpp.func.html new file mode 100644 index 0000000000..753c262e8b --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:16Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.gcov.html b/coverage-libs/asmjit/globals.cpp.gcov.html new file mode 100644 index 0000000000..57335f7457 --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + 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-05-27 13:05:16Functions:030.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.func.html b/coverage-libs/asmjit/globals.h.func.html new file mode 100644 index 0000000000..cac3530c03 --- /dev/null +++ b/coverage-libs/asmjit/globals.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.gcov.html b/coverage-libs/asmjit/globals.h.gcov.html new file mode 100644 index 0000000000..91be7e3d4d --- /dev/null +++ b/coverage-libs/asmjit/globals.h.gcov.html @@ -0,0 +1,446 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit4Inst13checkFeaturesEjRKNS1_6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit4Inst8validateEjRKNS1_6DetailEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.func.html b/coverage-libs/asmjit/inst.cpp.func.html new file mode 100644 index 0000000000..74b7f53037 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit4Inst13checkFeaturesEjRKNS1_6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit4Inst8validateEjRKNS1_6DetailEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.gcov.html b/coverage-libs/asmjit/inst.cpp.gcov.html new file mode 100644 index 0000000000..1b3c1ee9e9 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.func.html b/coverage-libs/asmjit/inst.h.func.html new file mode 100644 index 0000000000..78cbd44681 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.gcov.html b/coverage-libs/asmjit/inst.h.gcov.html new file mode 100644 index 0000000000..f217203d57 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.gcov.html @@ -0,0 +1,213 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FileLogger4_logEPKcm0
_ZN4PLMD6asmjit10FileLoggerC2EP8_IO_FILE0
_ZN4PLMD6asmjit10FileLoggerD0Ev0
_ZN4PLMD6asmjit10FileLoggerD2Ev0
_ZN4PLMD6asmjit12StringLogger4_logEPKcm0
_ZN4PLMD6asmjit12StringLoggerC2Ev0
_ZN4PLMD6asmjit12StringLoggerD0Ev0
_ZN4PLMD6asmjit12StringLoggerD2Ev0
_ZN4PLMD6asmjit6Logger14setIndentationEPKc0
_ZN4PLMD6asmjit6Logger4logfEPKcz0
_ZN4PLMD6asmjit6Logger4logvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit6Logger9logBinaryEPKvm0
_ZN4PLMD6asmjit6LoggerC2Ev0
_ZN4PLMD6asmjit6LoggerD0Ev0
_ZN4PLMD6asmjit6LoggerD2Ev0
_ZN4PLMD6asmjit7Logging10formatLineERNS0_13StringBuilderEPKhmmmPKc0
_ZN4PLMD6asmjit7Logging10formatNodeERNS0_13StringBuilderEjPKNS0_11CodeBuilderEPKNS0_6CBNodeE0
_ZN4PLMD6asmjit7Logging11formatLabelERNS0_13StringBuilderEjPKNS0_11CodeEmitterEj0
_ZN4PLMD6asmjit7Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit7Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit7Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL12formatTypeIdERNS0_13StringBuilderEj0
_ZN4PLMD6asmjitL14formatFuncArgsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL14formatFuncRetsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL21formatFuncDetailValueERNS0_13StringBuilderEjPKNS0_11CodeEmitterENS0_10FuncDetail5ValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.func.html b/coverage-libs/asmjit/logging.cpp.func.html new file mode 100644 index 0000000000..0e466a1252 --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05:16Functions:0250.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FileLogger4_logEPKcm0
_ZN4PLMD6asmjit10FileLoggerC2EP8_IO_FILE0
_ZN4PLMD6asmjit10FileLoggerD0Ev0
_ZN4PLMD6asmjit10FileLoggerD2Ev0
_ZN4PLMD6asmjit12StringLogger4_logEPKcm0
_ZN4PLMD6asmjit12StringLoggerC2Ev0
_ZN4PLMD6asmjit12StringLoggerD0Ev0
_ZN4PLMD6asmjit12StringLoggerD2Ev0
_ZN4PLMD6asmjit6Logger14setIndentationEPKc0
_ZN4PLMD6asmjit6Logger4logfEPKcz0
_ZN4PLMD6asmjit6Logger4logvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit6Logger9logBinaryEPKvm0
_ZN4PLMD6asmjit6LoggerC2Ev0
_ZN4PLMD6asmjit6LoggerD0Ev0
_ZN4PLMD6asmjit6LoggerD2Ev0
_ZN4PLMD6asmjit7Logging10formatLineERNS0_13StringBuilderEPKhmmmPKc0
_ZN4PLMD6asmjit7Logging10formatNodeERNS0_13StringBuilderEjPKNS0_11CodeBuilderEPKNS0_6CBNodeE0
_ZN4PLMD6asmjit7Logging11formatLabelERNS0_13StringBuilderEjPKNS0_11CodeEmitterEj0
_ZN4PLMD6asmjit7Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit7Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit7Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL12formatTypeIdERNS0_13StringBuilderEj0
_ZN4PLMD6asmjitL14formatFuncArgsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL14formatFuncRetsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL21formatFuncDetailValueERNS0_13StringBuilderEjPKNS0_11CodeEmitterENS0_10FuncDetail5ValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.gcov.html b/coverage-libs/asmjit/logging.cpp.gcov.html new file mode 100644 index 0000000000..559e58a8c6 --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.gcov.html @@ -0,0 +1,600 @@ + + + + + + + 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-05-27 13:05:16Functions:0250.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.func.html b/coverage-libs/asmjit/logging.h.func.html new file mode 100644 index 0000000000..8b112204af --- /dev/null +++ b/coverage-libs/asmjit/logging.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.gcov.html b/coverage-libs/asmjit/logging.h.gcov.html new file mode 100644 index 0000000000..66feb52aba --- /dev/null +++ b/coverage-libs/asmjit/logging.h.gcov.html @@ -0,0 +1,393 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.func.html b/coverage-libs/asmjit/moved_string.h.func.html new file mode 100644 index 0000000000..54bb18d0af --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.gcov.html b/coverage-libs/asmjit/moved_string.h.gcov.html new file mode 100644 index 0000000000..565f1cee03 --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.gcov.html @@ -0,0 +1,394 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.func.html b/coverage-libs/asmjit/operand.h.func.html new file mode 100644 index 0000000000..53315b70b4 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.gcov.html b/coverage-libs/asmjit/operand.h.gcov.html new file mode 100644 index 0000000000..850c6e4e86 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.gcov.html @@ -0,0 +1,1675 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1948
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1948
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1976
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func.html b/coverage-libs/asmjit/osutils.cpp.func.html new file mode 100644 index 0000000000..47aa717546 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:16Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1948
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1976
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1948
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.gcov.html b/coverage-libs/asmjit/osutils.cpp.gcov.html new file mode 100644 index 0000000000..1eb8b058b2 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.gcov.html @@ -0,0 +1,330 @@ + + + + + + + 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-05-27 13:05:16Functions:4580.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.func.html b/coverage-libs/asmjit/osutils.h.func.html new file mode 100644 index 0000000000..048f855352 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.gcov.html b/coverage-libs/asmjit/osutils.h.gcov.html new file mode 100644 index 0000000000..2ec9a25b39 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.gcov.html @@ -0,0 +1,283 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1948
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1948
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1948
_ZN4PLMD6asmjit6RAPass7cleanupEv1948
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit6RAPassC2Ev1948
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func.html b/coverage-libs/asmjit/regalloc.cpp.func.html new file mode 100644 index 0000000000..f378eb60d0 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:16Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1948
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1948
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1948
_ZN4PLMD6asmjit6RAPass7cleanupEv1948
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit6RAPassC2Ev1948
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.gcov.html b/coverage-libs/asmjit/regalloc.cpp.gcov.html new file mode 100644 index 0000000000..085ab002d8 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.gcov.html @@ -0,0 +1,696 @@ + + + + + + + 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-05-27 13:05:16Functions:91369.2 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.func.html b/coverage-libs/asmjit/regalloc_p.h.func.html new file mode 100644 index 0000000000..0da2e2fa69 --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.gcov.html b/coverage-libs/asmjit/regalloc_p.h.gcov.html new file mode 100644 index 0000000000..d76355450e --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.gcov.html @@ -0,0 +1,673 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1948
_ZN4PLMD6asmjit10JitRuntimeC2Ev1976
_ZN4PLMD6asmjit10JitRuntimeD0Ev1976
_ZN4PLMD6asmjit10JitRuntimeD2Ev1976
_ZN4PLMD6asmjit11HostRuntimeC2Ev1976
_ZN4PLMD6asmjit11HostRuntimeD2Ev1976
_ZN4PLMD6asmjit7RuntimeC2Ev1976
_ZN4PLMD6asmjit7RuntimeD2Ev1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func.html b/coverage-libs/asmjit/runtime.cpp.func.html new file mode 100644 index 0000000000..e5a888fe8a --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:16Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit10JitRuntimeC2Ev1976
_ZN4PLMD6asmjit10JitRuntimeD0Ev1976
_ZN4PLMD6asmjit10JitRuntimeD2Ev1976
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1948
_ZN4PLMD6asmjit11HostRuntimeC2Ev1976
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit11HostRuntimeD2Ev1976
_ZN4PLMD6asmjit7RuntimeC2Ev1976
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD2Ev1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.gcov.html b/coverage-libs/asmjit/runtime.cpp.gcov.html new file mode 100644 index 0000000000..2f213f975c --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.gcov.html @@ -0,0 +1,249 @@ + + + + + + + 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-05-27 13:05:16Functions:91275.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.func.html b/coverage-libs/asmjit/runtime.h.func.html new file mode 100644 index 0000000000..f11b449e8d --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.gcov.html b/coverage-libs/asmjit/runtime.h.gcov.html new file mode 100644 index 0000000000..c237d1fa50 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.gcov.html @@ -0,0 +1,303 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit13StringBuilder10_opVFormatEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit13StringBuilder12appendFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilder5clearEv0
_ZN4PLMD6asmjit13StringBuilder6_opHexEjPKvm0
_ZN4PLMD6asmjit13StringBuilder7_opCharEjc0
_ZN4PLMD6asmjit13StringBuilder7prepareEjm0
_ZN4PLMD6asmjit13StringBuilder7reserveEm0
_ZN4PLMD6asmjit13StringBuilder8_opCharsEjcm0
_ZN4PLMD6asmjit13StringBuilder9_opNumberEjmjmj0
_ZN4PLMD6asmjit13StringBuilder9_opStringEjPKcm0
_ZN4PLMD6asmjit13StringBuilder9setFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilderC2Ev0
_ZN4PLMD6asmjit13StringBuilderD2Ev0
_ZNK4PLMD6asmjit13StringBuilder2eqEPKcm0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.func.html b/coverage-libs/asmjit/string.cpp.func.html new file mode 100644 index 0000000000..c4ba3c3a36 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:16Functions:0140.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit13StringBuilder10_opVFormatEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit13StringBuilder12appendFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilder5clearEv0
_ZN4PLMD6asmjit13StringBuilder6_opHexEjPKvm0
_ZN4PLMD6asmjit13StringBuilder7_opCharEjc0
_ZN4PLMD6asmjit13StringBuilder7prepareEjm0
_ZN4PLMD6asmjit13StringBuilder7reserveEm0
_ZN4PLMD6asmjit13StringBuilder8_opCharsEjcm0
_ZN4PLMD6asmjit13StringBuilder9_opNumberEjmjmj0
_ZN4PLMD6asmjit13StringBuilder9_opStringEjPKcm0
_ZN4PLMD6asmjit13StringBuilder9setFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilderC2Ev0
_ZN4PLMD6asmjit13StringBuilderD2Ev0
_ZNK4PLMD6asmjit13StringBuilder2eqEPKcm0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.gcov.html b/coverage-libs/asmjit/string.cpp.gcov.html new file mode 100644 index 0000000000..a66b2365fa --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.gcov.html @@ -0,0 +1,455 @@ + + + + + + + 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-05-27 13:05:16Functions:0140.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.func.html b/coverage-libs/asmjit/utils.h.func.html new file mode 100644 index 0000000000..2db32605b4 --- /dev/null +++ b/coverage-libs/asmjit/utils.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.gcov.html b/coverage-libs/asmjit/utils.h.gcov.html new file mode 100644 index 0000000000..c7a202d8dd --- /dev/null +++ b/coverage-libs/asmjit/utils.h.gcov.html @@ -0,0 +1,1463 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjit7VMemMgr5allocEmj1948
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1948
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1948
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1948
_ZN4PLMD6asmjit7VMemMgrC2Ev1976
_ZN4PLMD6asmjit7VMemMgrD2Ev1976
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1976
_ZN4PLMD6asmjitL8_SetBitsEPmmm3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func.html b/coverage-libs/asmjit/vmem.cpp.func.html new file mode 100644 index 0000000000..f9264efc4f --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:16Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5allocEmj1948
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjit7VMemMgrC2Ev1976
_ZN4PLMD6asmjit7VMemMgrD2Ev1976
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1976
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1948
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1948
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1948
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjitL8_SetBitsEPmmm3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.gcov.html b/coverage-libs/asmjit/vmem.cpp.gcov.html new file mode 100644 index 0000000000..38c64c6654 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.gcov.html @@ -0,0 +1,1179 @@ + + + + + + + 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-05-27 13:05:16Functions:81457.1 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerD2Ev1948
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48362
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func.html b/coverage-libs/asmjit/x86assembler.cpp.func.html new file mode 100644 index 0000000000..d598b7181d --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:16Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48362
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86AssemblerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.gcov.html b/coverage-libs/asmjit/x86assembler.cpp.gcov.html new file mode 100644 index 0000000000..05d0006e06 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.gcov.html @@ -0,0 +1,4721 @@ + + + + + + + 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-05-27 13:05:16Functions:4757.1 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.func.html b/coverage-libs/asmjit/x86assembler.h.func.html new file mode 100644 index 0000000000..3588705502 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.gcov.html b/coverage-libs/asmjit/x86assembler.h.gcov.html new file mode 100644 index 0000000000..7fa362f4e5 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Builder5_emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit10X86Builder8onAttachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderC2EPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderD0Ev0
_ZN4PLMD6asmjit10X86BuilderD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.func.html b/coverage-libs/asmjit/x86builder.cpp.func.html new file mode 100644 index 0000000000..d9d8b8bdc8 --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:16Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Builder5_emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit10X86Builder8onAttachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderC2EPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderD0Ev0
_ZN4PLMD6asmjit10X86BuilderD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.gcov.html b/coverage-libs/asmjit/x86builder.cpp.gcov.html new file mode 100644 index 0000000000..b531e5fe0f --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + 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-05-27 13:05:16Functions:050.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1948
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerD2Ev1948
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46714
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.func.html b/coverage-libs/asmjit/x86compiler.cpp.func.html new file mode 100644 index 0000000000..969a6daf08 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46714
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1948
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86CompilerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.gcov.html b/coverage-libs/asmjit/x86compiler.cpp.gcov.html new file mode 100644 index 0000000000..e507164d27 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.gcov.html @@ -0,0 +1,478 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.func.html b/coverage-libs/asmjit/x86compiler.h.func.html new file mode 100644 index 0000000000..d31ca036a2 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.gcov.html b/coverage-libs/asmjit/x86compiler.h.gcov.html new file mode 100644 index 0000000000..f4b5ed8313 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.gcov.html @@ -0,0 +1,398 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.func.html b/coverage-libs/asmjit/x86emitter.h.func.html new file mode 100644 index 0000000000..1487d02ade --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.gcov.html b/coverage-libs/asmjit/x86emitter.h.gcov.html new file mode 100644 index 0000000000..210ecb2b80 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.gcov.html @@ -0,0 +1,5225 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86emitter_h
+      21             : #define __PLUMED_asmjit_x86emitter_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86EMITTER_H
+      33             : #define _ASMJIT_X86_X86EMITTER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./codeemitter.h"
+      37             : #include "./x86inst.h"
+      38             : #include "./x86operand.h"
+      39             : 
+      40             : // [Api-Begin]
+      41             : #include "./asmjit_apibegin.h"
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace asmjit {
+      45             : 
+      46             : //! \addtogroup asmjit_x86
+      47             : //! \{
+      48             : 
+      49             : // ============================================================================
+      50             : // [asmjit::X86EmitterExplicitT]
+      51             : // ============================================================================
+      52             : 
+      53             : #define ASMJIT_EMIT static_cast<This*>(this)->emit
+      54             : 
+      55             : #define ASMJIT_INST_0x(NAME, ID) \
+      56             :   ASMJIT_INLINE Error NAME() { return ASMJIT_EMIT(X86Inst::kId##ID); }
+      57             : 
+      58             : #define ASMJIT_INST_1x(NAME, ID, T0) \
+      59             :   ASMJIT_INLINE Error NAME(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID, o0); }
+      60             : 
+      61             : #define ASMJIT_INST_1i(NAME, ID, T0) \
+      62             :   ASMJIT_INLINE Error NAME(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID, o0); } \
+      63             :   ASMJIT_INLINE Error NAME(int o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      64             :   ASMJIT_INLINE Error NAME(unsigned int o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      65             :   ASMJIT_INLINE Error NAME(int64_t o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      66             :   ASMJIT_INLINE Error NAME(uint64_t o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); }
+      67             : 
+      68             : #define ASMJIT_INST_1c(NAME, ID, CONV, T0) \
+      69             :   ASMJIT_INLINE Error NAME(uint32_t cc, const T0& o0) { return ASMJIT_EMIT(CONV(cc), o0); } \
+      70             :   ASMJIT_INLINE Error NAME##a(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##a, o0); } \
+      71             :   ASMJIT_INLINE Error NAME##ae(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ae, o0); } \
+      72             :   ASMJIT_INLINE Error NAME##b(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##b, o0); } \
+      73             :   ASMJIT_INLINE Error NAME##be(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##be, o0); } \
+      74             :   ASMJIT_INLINE Error NAME##c(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##c, o0); } \
+      75             :   ASMJIT_INLINE Error NAME##e(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##e, o0); } \
+      76             :   ASMJIT_INLINE Error NAME##g(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##g, o0); } \
+      77             :   ASMJIT_INLINE Error NAME##ge(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ge, o0); } \
+      78             :   ASMJIT_INLINE Error NAME##l(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##l, o0); } \
+      79             :   ASMJIT_INLINE Error NAME##le(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##le, o0); } \
+      80             :   ASMJIT_INLINE Error NAME##na(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##na, o0); } \
+      81             :   ASMJIT_INLINE Error NAME##nae(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nae, o0); } \
+      82             :   ASMJIT_INLINE Error NAME##nb(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nb, o0); } \
+      83             :   ASMJIT_INLINE Error NAME##nbe(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nbe, o0); } \
+      84             :   ASMJIT_INLINE Error NAME##nc(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nc, o0); } \
+      85             :   ASMJIT_INLINE Error NAME##ne(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ne, o0); } \
+      86             :   ASMJIT_INLINE Error NAME##ng(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ng, o0); } \
+      87             :   ASMJIT_INLINE Error NAME##nge(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nge, o0); } \
+      88             :   ASMJIT_INLINE Error NAME##nl(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nl, o0); } \
+      89             :   ASMJIT_INLINE Error NAME##nle(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nle, o0); } \
+      90             :   ASMJIT_INLINE Error NAME##no(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##no, o0); } \
+      91             :   ASMJIT_INLINE Error NAME##np(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##np, o0); } \
+      92             :   ASMJIT_INLINE Error NAME##ns(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ns, o0); } \
+      93             :   ASMJIT_INLINE Error NAME##nz(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nz, o0); } \
+      94             :   ASMJIT_INLINE Error NAME##o(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##o, o0); } \
+      95             :   ASMJIT_INLINE Error NAME##p(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##p, o0); } \
+      96             :   ASMJIT_INLINE Error NAME##pe(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##pe, o0); } \
+      97             :   ASMJIT_INLINE Error NAME##po(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##po, o0); } \
+      98             :   ASMJIT_INLINE Error NAME##s(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##s, o0); } \
+      99             :   ASMJIT_INLINE Error NAME##z(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##z, o0); }
+     100             : 
+     101             : #define ASMJIT_INST_2x(NAME, ID, T0, T1) \
+     102             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1) { \
+     103             :     return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1); \
+     104             :   }
+     105             : 
+     106             : #define ASMJIT_INST_2i(NAME, ID, T0, T1) \
+     107             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1); } \
+     108             :   ASMJIT_INLINE Error NAME(const T0& o0, int o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     109             :   ASMJIT_INLINE Error NAME(const T0& o0, unsigned int o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     110             :   ASMJIT_INLINE Error NAME(const T0& o0, int64_t o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     111             :   ASMJIT_INLINE Error NAME(const T0& o0, uint64_t o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); }
+     112             : 
+     113             : #define ASMJIT_INST_2c(NAME, ID, CONV, T0, T1) \
+     114             :   ASMJIT_INLINE Error NAME(uint32_t cc, const T0& o0, const T1& o1) { return ASMJIT_EMIT(CONV(cc), o0, o1); } \
+     115             :   ASMJIT_INLINE Error NAME##a(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##a, o0, o1); } \
+     116             :   ASMJIT_INLINE Error NAME##ae(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ae, o0, o1); } \
+     117             :   ASMJIT_INLINE Error NAME##b(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##b, o0, o1); } \
+     118             :   ASMJIT_INLINE Error NAME##be(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##be, o0, o1); } \
+     119             :   ASMJIT_INLINE Error NAME##c(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##c, o0, o1); } \
+     120             :   ASMJIT_INLINE Error NAME##e(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##e, o0, o1); } \
+     121             :   ASMJIT_INLINE Error NAME##g(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##g, o0, o1); } \
+     122             :   ASMJIT_INLINE Error NAME##ge(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ge, o0, o1); } \
+     123             :   ASMJIT_INLINE Error NAME##l(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##l, o0, o1); } \
+     124             :   ASMJIT_INLINE Error NAME##le(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##le, o0, o1); } \
+     125             :   ASMJIT_INLINE Error NAME##na(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##na, o0, o1); } \
+     126             :   ASMJIT_INLINE Error NAME##nae(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nae, o0, o1); } \
+     127             :   ASMJIT_INLINE Error NAME##nb(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nb, o0, o1); } \
+     128             :   ASMJIT_INLINE Error NAME##nbe(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nbe, o0, o1); } \
+     129             :   ASMJIT_INLINE Error NAME##nc(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nc, o0, o1); } \
+     130             :   ASMJIT_INLINE Error NAME##ne(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ne, o0, o1); } \
+     131             :   ASMJIT_INLINE Error NAME##ng(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ng, o0, o1); } \
+     132             :   ASMJIT_INLINE Error NAME##nge(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nge, o0, o1); } \
+     133             :   ASMJIT_INLINE Error NAME##nl(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nl, o0, o1); } \
+     134             :   ASMJIT_INLINE Error NAME##nle(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nle, o0, o1); } \
+     135             :   ASMJIT_INLINE Error NAME##no(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##no, o0, o1); } \
+     136             :   ASMJIT_INLINE Error NAME##np(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##np, o0, o1); } \
+     137             :   ASMJIT_INLINE Error NAME##ns(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ns, o0, o1); } \
+     138             :   ASMJIT_INLINE Error NAME##nz(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nz, o0, o1); } \
+     139             :   ASMJIT_INLINE Error NAME##o(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##o, o0, o1); } \
+     140             :   ASMJIT_INLINE Error NAME##p(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##p, o0, o1); } \
+     141             :   ASMJIT_INLINE Error NAME##pe(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##pe, o0, o1); } \
+     142             :   ASMJIT_INLINE Error NAME##po(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##po, o0, o1); } \
+     143             :   ASMJIT_INLINE Error NAME##s(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##s, o0, o1); } \
+     144             :   ASMJIT_INLINE Error NAME##z(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##z, o0, o1); }
+     145             : 
+     146             : #define ASMJIT_INST_3x(NAME, ID, T0, T1, T2) \
+     147             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); }
+     148             : 
+     149             : #define ASMJIT_INST_3i(NAME, ID, T0, T1, T2) \
+     150             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); } \
+     151             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     152             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, unsigned int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     153             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int64_t o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     154             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, uint64_t o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); }
+     155             : 
+     156             : #define ASMJIT_INST_3ii(NAME, ID, T0, T1, T2) \
+     157             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); } \
+     158             :   ASMJIT_INLINE Error NAME(const T0& o0, int o1, int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Imm(o1), Utils::asInt(o2)); }
+     159             : 
+     160             : #define ASMJIT_INST_4x(NAME, ID, T0, T1, T2, T3) \
+     161             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); }
+     162             : 
+     163             : #define ASMJIT_INST_4i(NAME, ID, T0, T1, T2, T3) \
+     164             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); } \
+     165             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     166             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, unsigned int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     167             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, int64_t o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     168             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, uint64_t o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); }
+     169             : 
+     170             : #define ASMJIT_INST_4ii(NAME, ID, T0, T1, T2, T3) \
+     171             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); } \
+     172             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int o2, int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Imm(o2), Utils::asInt(o3)); }
+     173             : 
+     174             : #define ASMJIT_INST_5x(NAME, ID, T0, T1, T2, T3, T4) \
+     175             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4); }
+     176             : 
+     177             : #define ASMJIT_INST_5i(NAME, ID, T0, T1, T2, T3, T4) \
+     178             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4); } \
+     179             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     180             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, unsigned int o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     181             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int64_t o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     182             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, uint64_t o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); }
+     183             : 
+     184             : #define ASMJIT_INST_6x(NAME, ID, T0, T1, T2, T3, T4, T5) \
+     185             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4, const T5& o5) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4, o5); }
+     186             : 
+     187             : template<typename This>
+     188             : struct X86EmitterExplicitT {
+     189             :   // These typedefs are used to describe implicit operands passed explicitly.
+     190             :   typedef X86Gp AL;
+     191             :   typedef X86Gp AH;
+     192             :   typedef X86Gp CL;
+     193             :   typedef X86Gp AX;
+     194             :   typedef X86Gp DX;
+     195             : 
+     196             :   typedef X86Gp EAX;
+     197             :   typedef X86Gp EBX;
+     198             :   typedef X86Gp ECX;
+     199             :   typedef X86Gp EDX;
+     200             : 
+     201             :   typedef X86Gp RAX;
+     202             :   typedef X86Gp RBX;
+     203             :   typedef X86Gp RCX;
+     204             :   typedef X86Gp RDX;
+     205             : 
+     206             :   typedef X86Gp ZAX;
+     207             :   typedef X86Gp ZBX;
+     208             :   typedef X86Gp ZCX;
+     209             :   typedef X86Gp ZDX;
+     210             : 
+     211             :   typedef X86Mem DS_ZAX; // ds:[zax]
+     212             :   typedef X86Mem DS_ZDI; // ds:[zdi]
+     213             :   typedef X86Mem ES_ZDI; // es:[zdi]
+     214             :   typedef X86Mem DS_ZSI; // ds:[zsi]
+     215             : 
+     216             :   typedef X86Xmm XMM0;
+     217             : 
+     218             :   // --------------------------------------------------------------------------
+     219             :   // [Accessors]
+     220             :   // --------------------------------------------------------------------------
+     221             : 
+     222             :   //! Get GPD or GPQ register at index `id` depending on the current architecture.
+     223             :   ASMJIT_INLINE X86Gp gpz(uint32_t id) const noexcept {
+     224             :     return X86Gp(Init, static_cast<const This*>(this)->_nativeGpReg.getSignature(), id);
+     225             :   }
+     226             : 
+     227             :   ASMJIT_INLINE const X86Gp& gpzRef(uint32_t id) const noexcept {
+     228             :     ASMJIT_ASSERT(id < 16);
+     229        5844 :     return static_cast<const X86Gp&>(static_cast<const This*>(this)->_nativeGpArray[id]);
+     230             :   }
+     231             : 
+     232             :   ASMJIT_INLINE const X86Gp& zax() const noexcept { return gpzRef(X86Gp::kIdAx); }
+     233             :   ASMJIT_INLINE const X86Gp& zcx() const noexcept { return gpzRef(X86Gp::kIdCx); }
+     234             :   ASMJIT_INLINE const X86Gp& zdx() const noexcept { return gpzRef(X86Gp::kIdDx); }
+     235             :   ASMJIT_INLINE const X86Gp& zbx() const noexcept { return gpzRef(X86Gp::kIdBx); }
+     236             :   ASMJIT_INLINE const X86Gp& zsp() const noexcept { return gpzRef(X86Gp::kIdSp); }
+     237             :   ASMJIT_INLINE const X86Gp& zbp() const noexcept { return gpzRef(X86Gp::kIdBp); }
+     238             :   ASMJIT_INLINE const X86Gp& zsi() const noexcept { return gpzRef(X86Gp::kIdSi); }
+     239             :   ASMJIT_INLINE const X86Gp& zdi() const noexcept { return gpzRef(X86Gp::kIdDi); }
+     240             : 
+     241             :   //! Create a target dependent pointer of which base register's id is `baseId`.
+     242             :   ASMJIT_INLINE X86Mem ptr_base(uint32_t baseId, int32_t off = 0, uint32_t size = 0) const noexcept {
+     243             :     uint32_t baseType = static_cast<const This*>(this)->_nativeGpReg.getType();
+     244             :     uint32_t flags = 0;
+     245             :     return X86Mem(Init, baseType, baseId, 0, 0, off, size, flags);
+     246             :   }
+     247             : 
+     248             :   ASMJIT_INLINE X86Mem ptr_zax(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdAx, off, size); }
+     249             :   ASMJIT_INLINE X86Mem ptr_zcx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdCx, off, size); }
+     250             :   ASMJIT_INLINE X86Mem ptr_zdx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdDx, off, size); }
+     251             :   ASMJIT_INLINE X86Mem ptr_zbx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdBx, off, size); }
+     252             :   ASMJIT_INLINE X86Mem ptr_zsp(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdSp, off, size); }
+     253             :   ASMJIT_INLINE X86Mem ptr_zbp(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdBp, off, size); }
+     254             :   ASMJIT_INLINE X86Mem ptr_zsi(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdSi, off, size); }
+     255             :   ASMJIT_INLINE X86Mem ptr_zdi(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdDi, off, size); }
+     256             : 
+     257             :   //! Create an `intptr_t` memory operand depending on the current architecture.
+     258             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, int32_t offset = 0) const noexcept {
+     259             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     260             :     return X86Mem(base, offset, nativeGpSize);
+     261             :   }
+     262             :   //! \overload
+     263             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
+     264             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     265             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     266             :   }
+     267             :   //! \overload
+     268             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
+     269             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     270             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     271             :   }
+     272             :   //! \overload
+     273             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, int32_t offset = 0) const noexcept {
+     274             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     275             :     return X86Mem(base, offset, nativeGpSize);
+     276             :   }
+     277             :   //! \overload
+     278             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0) const noexcept {
+     279             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     280             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     281             :   }
+     282             :   //! \overload
+     283             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, const X86Vec& index, uint32_t shift, int32_t offset = 0) const noexcept {
+     284             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     285             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     286             :   }
+     287             :   //! \overload
+     288             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Rip& rip, int32_t offset = 0) const noexcept {
+     289             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     290             :     return X86Mem(rip, offset, nativeGpSize);
+     291             :   }
+     292             :   //! \overload
+     293             :   ASMJIT_INLINE X86Mem intptr_ptr(uint64_t base) const noexcept {
+     294             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     295             :     return X86Mem(base, nativeGpSize);
+     296             :   }
+     297             :   //! \overload
+     298             :   ASMJIT_INLINE X86Mem intptr_ptr(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
+     299             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     300             :     return X86Mem(base, index, shift, nativeGpSize);
+     301             :   }
+     302             :   //! \overload
+     303             :   ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base) const noexcept {
+     304             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     305             :     return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbs);
+     306             :   }
+     307             :   //! \overload
+     308             :   ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
+     309             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     310             :     return X86Mem(base, index, shift, nativeGpSize, Mem::kSignatureMemAbs);
+     311             :   }
+     312             : 
+     313             :   // --------------------------------------------------------------------------
+     314             :   // [Embed]
+     315             :   // --------------------------------------------------------------------------
+     316             : 
+     317             :   //! Add 8-bit integer data to the instruction stream.
+     318             :   ASMJIT_INLINE Error db(uint8_t x) { return static_cast<This*>(this)->embed(&x, 1); }
+     319             :   //! Add 16-bit integer data to the instruction stream.
+     320             :   ASMJIT_INLINE Error dw(uint16_t x) { return static_cast<This*>(this)->embed(&x, 2); }
+     321             :   //! Add 32-bit integer data to the instruction stream.
+     322             :   ASMJIT_INLINE Error dd(uint32_t x) { return static_cast<This*>(this)->embed(&x, 4); }
+     323             :   //! Add 64-bit integer data to the instruction stream.
+     324             :   ASMJIT_INLINE Error dq(uint64_t x) { return static_cast<This*>(this)->embed(&x, 8); }
+     325             : 
+     326             :   //! Add 8-bit integer data to the instruction stream.
+     327             :   ASMJIT_INLINE Error dint8(int8_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int8_t)); }
+     328             :   //! Add 8-bit integer data to the instruction stream.
+     329             :   ASMJIT_INLINE Error duint8(uint8_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint8_t)); }
+     330             : 
+     331             :   //! Add 16-bit integer data to the instruction stream.
+     332             :   ASMJIT_INLINE Error dint16(int16_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int16_t)); }
+     333             :   //! Add 16-bit integer data to the instruction stream.
+     334             :   ASMJIT_INLINE Error duint16(uint16_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint16_t)); }
+     335             : 
+     336             :   //! Add 32-bit integer data to the instruction stream.
+     337             :   ASMJIT_INLINE Error dint32(int32_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int32_t)); }
+     338             :   //! Add 32-bit integer data to the instruction stream.
+     339             :   ASMJIT_INLINE Error duint32(uint32_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint32_t)); }
+     340             : 
+     341             :   //! Add 64-bit integer data to the instruction stream.
+     342             :   ASMJIT_INLINE Error dint64(int64_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int64_t)); }
+     343             :   //! Add 64-bit integer data to the instruction stream.
+     344             :   ASMJIT_INLINE Error duint64(uint64_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint64_t)); }
+     345             : 
+     346             :   //! Add float data to the instruction stream.
+     347             :   ASMJIT_INLINE Error dfloat(float x) { return static_cast<This*>(this)->embed(&x, sizeof(float)); }
+     348             :   //! Add double data to the instruction stream.
+     349             :   ASMJIT_INLINE Error ddouble(double x) { return static_cast<This*>(this)->embed(&x, sizeof(double)); }
+     350             : 
+     351             :   //! Add MMX data to the instruction stream.
+     352             :   ASMJIT_INLINE Error dmm(const Data64& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data64)); }
+     353             :   //! Add XMM data to the instruction stream.
+     354             :   ASMJIT_INLINE Error dxmm(const Data128& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data128)); }
+     355             :   //! Add YMM data to the instruction stream.
+     356             :   ASMJIT_INLINE Error dymm(const Data256& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data256)); }
+     357             : 
+     358             :   //! Add data in a given structure instance to the instruction stream.
+     359             :   template<typename T>
+     360             :   ASMJIT_INLINE Error dstruct(const T& x) { return static_cast<This*>(this)->embed(&x, static_cast<uint32_t>(sizeof(T))); }
+     361             : 
+     362             :   // --------------------------------------------------------------------------
+     363             :   // [Options]
+     364             :   // --------------------------------------------------------------------------
+     365             : 
+     366             : protected:
+     367             :   ASMJIT_INLINE This& _addOptions(uint32_t options) noexcept {
+     368             :     static_cast<This*>(this)->addOptions(options);
+     369             :     return *static_cast<This*>(this);
+     370             :   }
+     371             : 
+     372             : public:
+     373             :   //! Force short form of jmp/jcc instruction.
+     374             :   ASMJIT_INLINE This& short_() noexcept { return _addOptions(X86Inst::kOptionShortForm); }
+     375             :   //! Force long form of jmp/jcc instruction.
+     376             :   ASMJIT_INLINE This& long_() noexcept { return _addOptions(X86Inst::kOptionLongForm); }
+     377             : 
+     378             :   //! Condition is likely to be taken (has only benefit on P4).
+     379             :   ASMJIT_INLINE This& taken() noexcept { return _addOptions(X86Inst::kOptionTaken); }
+     380             :   //! Condition is unlikely to be taken (has only benefit on P4).
+     381             :   ASMJIT_INLINE This& notTaken() noexcept { return _addOptions(X86Inst::kOptionNotTaken); }
+     382             : 
+     383             :   //! Use LOCK prefix.
+     384             :   ASMJIT_INLINE This& lock() noexcept { return _addOptions(X86Inst::kOptionLock); }
+     385             :   //! Use XACQUIRE prefix.
+     386             :   ASMJIT_INLINE This& xacquire() noexcept { return _addOptions(X86Inst::kOptionXAcquire); }
+     387             :   //! Use XRELEASE prefix.
+     388             :   ASMJIT_INLINE This& xrelease() noexcept { return _addOptions(X86Inst::kOptionXRelease); }
+     389             : 
+     390             :   //! Use REP/REPZ prefix.
+     391             :   ASMJIT_INLINE This& rep(const X86Gp& zcx) noexcept {
+     392             :     static_cast<This*>(this)->_extraReg.init(zcx);
+     393             :     return _addOptions(X86Inst::kOptionRep);
+     394             :   }
+     395             :   //! Use REPNZ prefix.
+     396             :   ASMJIT_INLINE This& repnz(const X86Gp& zcx) noexcept {
+     397             :     static_cast<This*>(this)->_extraReg.init(zcx);
+     398             :     return _addOptions(X86Inst::kOptionRepnz);
+     399             :   }
+     400             : 
+     401             :   //! Use REP/REPZ prefix.
+     402             :   ASMJIT_INLINE This& repe(const X86Gp& zcx) noexcept { return rep(zcx); }
+     403             :   //! Use REP/REPZ prefix.
+     404             :   ASMJIT_INLINE This& repz(const X86Gp& zcx) noexcept { return rep(zcx); }
+     405             :   //! Use REPNZ prefix.
+     406             :   ASMJIT_INLINE This& repne(const X86Gp& zcx) noexcept { return repnz(zcx); }
+     407             : 
+     408             :   //! Prefer MOD_MR encoding over MOD_RM (the default) when encoding instruction
+     409             :   //! that allows both. This option is only applicable to legacy instructions
+     410             :   //! where both operands are registers.
+     411             :   ASMJIT_INLINE This& mod_mr() noexcept { return _addOptions(X86Inst::kOptionModMR); }
+     412             : 
+     413             :   //! Force REX prefix to be emitted even when it's not needed (X64).
+     414             :   //!
+     415             :   //! NOTE: Don't use when using high 8-bit registers as REX prefix makes them
+     416             :   //! inaccessible and \ref X86Assembler refuses to encode such instructions.
+     417             :   ASMJIT_INLINE This& rex() noexcept { return _addOptions(X86Inst::kOptionRex);}
+     418             : 
+     419             :   //! Force REX.B prefix (X64) [It exists for special purposes only].
+     420             :   ASMJIT_INLINE This& rex_b() noexcept { return _addOptions(X86Inst::kOptionOpCodeB); }
+     421             :   //! Force REX.X prefix (X64) [It exists for special purposes only].
+     422             :   ASMJIT_INLINE This& rex_x() noexcept { return _addOptions(X86Inst::kOptionOpCodeX); }
+     423             :   //! Force REX.R prefix (X64) [It exists for special purposes only].
+     424             :   ASMJIT_INLINE This& rex_r() noexcept { return _addOptions(X86Inst::kOptionOpCodeR); }
+     425             :   //! Force REX.W prefix (X64) [It exists for special purposes only].
+     426             :   ASMJIT_INLINE This& rex_w() noexcept { return _addOptions(X86Inst::kOptionOpCodeW); }
+     427             : 
+     428             :   //! Force 3-byte VEX prefix (AVX+).
+     429             :   ASMJIT_INLINE This& vex3() noexcept { return _addOptions(X86Inst::kOptionVex3); }
+     430             :   //! Force 4-byte EVEX prefix (AVX512+).
+     431             :   ASMJIT_INLINE This& evex() noexcept { return _addOptions(X86Inst::kOptionEvex); }
+     432             : 
+     433             :   //! Use masking {k} (AVX512+).
+     434             :   ASMJIT_INLINE This& k(const X86KReg& kreg) noexcept {
+     435             :     static_cast<This*>(this)->_extraReg.init(kreg);
+     436             :     return *static_cast<This*>(this);
+     437             :   }
+     438             : 
+     439             :   //! Use zeroing instead of merging (AVX512+).
+     440             :   ASMJIT_INLINE This& z() noexcept { return _addOptions(X86Inst::kOptionZMask); }
+     441             :   //! Broadcast one element to all other elements (AVX512+).
+     442             :   ASMJIT_INLINE This& _1tox() noexcept { return _addOptions(X86Inst::kOption1ToX); }
+     443             : 
+     444             :   //! Suppress all exceptions (AVX512+).
+     445             :   ASMJIT_INLINE This& sae() noexcept { return _addOptions(X86Inst::kOptionSAE); }
+     446             :   //! Static rounding mode {rn} (round-to-nearest even) and {sae} (AVX512+).
+     447             :   ASMJIT_INLINE This& rn_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRN_SAE); }
+     448             :   //! Static rounding mode {rd} (round-down, toward -inf) and {sae} (AVX512+).
+     449             :   ASMJIT_INLINE This& rd_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRD_SAE); }
+     450             :   //! Static rounding mode {ru} (round-up, toward +inf) and {sae} (AVX512+).
+     451             :   ASMJIT_INLINE This& ru_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRU_SAE); }
+     452             :   //! Static rounding mode {rz} (round-toward-zero, truncate) and {sae} (AVX512+).
+     453             :   ASMJIT_INLINE This& rz_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRZ_SAE); }
+     454             : 
+     455             :   // --------------------------------------------------------------------------
+     456             :   // [General Purpose and Non-SIMD Instructions]
+     457             :   // --------------------------------------------------------------------------
+     458             : 
+     459             :   ASMJIT_INST_2x(adc, Adc, X86Gp, X86Gp)                                      // ANY
+     460             :   ASMJIT_INST_2x(adc, Adc, X86Gp, X86Mem)                                     // ANY
+     461             :   ASMJIT_INST_2i(adc, Adc, X86Gp, Imm)                                        // ANY
+     462             :   ASMJIT_INST_2x(adc, Adc, X86Mem, X86Gp)                                     // ANY
+     463             :   ASMJIT_INST_2i(adc, Adc, X86Mem, Imm)                                       // ANY
+     464             :   ASMJIT_INST_2x(adcx, Adcx, X86Gp, X86Gp)                                    // ADX
+     465             :   ASMJIT_INST_2x(adcx, Adcx, X86Gp, X86Mem)                                   // ADX
+     466             :   ASMJIT_INST_2x(add, Add, X86Gp, X86Gp)                                      // ANY
+     467             :   ASMJIT_INST_2x(add, Add, X86Gp, X86Mem)                                     // ANY
+     468         932 :   ASMJIT_INST_2i(add, Add, X86Gp, Imm)                                        // ANY
+     469             :   ASMJIT_INST_2x(add, Add, X86Mem, X86Gp)                                     // ANY
+     470             :   ASMJIT_INST_2i(add, Add, X86Mem, Imm)                                       // ANY
+     471             :   ASMJIT_INST_2x(adox, Adox, X86Gp, X86Gp)                                    // ADX
+     472             :   ASMJIT_INST_2x(adox, Adox, X86Gp, X86Mem)                                   // ADX
+     473             :   ASMJIT_INST_2x(and_, And, X86Gp, X86Gp)                                     // ANY
+     474             :   ASMJIT_INST_2x(and_, And, X86Gp, X86Mem)                                    // ANY
+     475           0 :   ASMJIT_INST_2i(and_, And, X86Gp, Imm)                                       // ANY
+     476             :   ASMJIT_INST_2x(and_, And, X86Mem, X86Gp)                                    // ANY
+     477             :   ASMJIT_INST_2i(and_, And, X86Mem, Imm)                                      // ANY
+     478             :   ASMJIT_INST_3x(andn, Andn, X86Gp, X86Gp, X86Gp)                             // BMI
+     479             :   ASMJIT_INST_3x(andn, Andn, X86Gp, X86Gp, X86Mem)                            // BMI
+     480             :   ASMJIT_INST_2x(arpl, Arpl, X86Gp, X86Gp)                                    // X86
+     481             :   ASMJIT_INST_2x(arpl, Arpl, X86Mem, X86Gp)                                   // X86
+     482             :   ASMJIT_INST_3x(bextr, Bextr, X86Gp, X86Gp, X86Gp)                           // BMI
+     483             :   ASMJIT_INST_3x(bextr, Bextr, X86Gp, X86Mem, X86Gp)                          // BMI
+     484             :   ASMJIT_INST_2x(blcfill, Blcfill, X86Gp, X86Gp)                              // TBM
+     485             :   ASMJIT_INST_2x(blcfill, Blcfill, X86Gp, X86Mem)                             // TBM
+     486             :   ASMJIT_INST_2x(blci, Blci, X86Gp, X86Gp)                                    // TBM
+     487             :   ASMJIT_INST_2x(blci, Blci, X86Gp, X86Mem)                                   // TBM
+     488             :   ASMJIT_INST_2x(blcic, Blcic, X86Gp, X86Gp)                                  // TBM
+     489             :   ASMJIT_INST_2x(blcic, Blcic, X86Gp, X86Mem)                                 // TBM
+     490             :   ASMJIT_INST_2x(blcmsk, Blcmsk, X86Gp, X86Gp)                                // TBM
+     491             :   ASMJIT_INST_2x(blcmsk, Blcmsk, X86Gp, X86Mem)                               // TBM
+     492             :   ASMJIT_INST_2x(blcs, Blcs, X86Gp, X86Gp)                                    // TBM
+     493             :   ASMJIT_INST_2x(blcs, Blcs, X86Gp, X86Mem)                                   // TBM
+     494             :   ASMJIT_INST_2x(blsfill, Blsfill, X86Gp, X86Gp)                              // TBM
+     495             :   ASMJIT_INST_2x(blsfill, Blsfill, X86Gp, X86Mem)                             // TBM
+     496             :   ASMJIT_INST_2x(blsi, Blsi, X86Gp, X86Gp)                                    // BMI
+     497             :   ASMJIT_INST_2x(blsi, Blsi, X86Gp, X86Mem)                                   // BMI
+     498             :   ASMJIT_INST_2x(blsic, Blsic, X86Gp, X86Gp)                                  // TBM
+     499             :   ASMJIT_INST_2x(blsic, Blsic, X86Gp, X86Mem)                                 // TBM
+     500             :   ASMJIT_INST_2x(blsmsk, Blsmsk, X86Gp, X86Gp)                                // BMI
+     501             :   ASMJIT_INST_2x(blsmsk, Blsmsk, X86Gp, X86Mem)                               // BMI
+     502             :   ASMJIT_INST_2x(blsr, Blsr, X86Gp, X86Gp)                                    // BMI
+     503             :   ASMJIT_INST_2x(blsr, Blsr, X86Gp, X86Mem)                                   // BMI
+     504             :   ASMJIT_INST_2x(bndcl, Bndcl, X86Bnd, X86Gp)                                 // MPX
+     505             :   ASMJIT_INST_2x(bndcl, Bndcl, X86Bnd, X86Mem)                                // MPX
+     506             :   ASMJIT_INST_2x(bndcn, Bndcn, X86Bnd, X86Gp)                                 // MPX
+     507             :   ASMJIT_INST_2x(bndcn, Bndcn, X86Bnd, X86Mem)                                // MPX
+     508             :   ASMJIT_INST_2x(bndcu, Bndcu, X86Bnd, X86Gp)                                 // MPX
+     509             :   ASMJIT_INST_2x(bndcu, Bndcu, X86Bnd, X86Mem)                                // MPX
+     510             :   ASMJIT_INST_2x(bndldx, Bndldx, X86Bnd, X86Mem)                              // MPX
+     511             :   ASMJIT_INST_2x(bndmk, Bndmk, X86Bnd, X86Mem)                                // MPX
+     512             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Bnd, X86Bnd)                              // MPX
+     513             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Bnd, X86Mem)                              // MPX
+     514             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Mem, X86Bnd)                              // MPX
+     515             :   ASMJIT_INST_2x(bndstx, Bndstx, X86Mem, X86Bnd)                              // MPX
+     516             :   ASMJIT_INST_2x(bound, Bound, X86Gp, X86Mem)                                 // X86
+     517             :   ASMJIT_INST_2x(bsf, Bsf, X86Gp, X86Gp)                                      // ANY
+     518             :   ASMJIT_INST_2x(bsf, Bsf, X86Gp, X86Mem)                                     // ANY
+     519             :   ASMJIT_INST_2x(bsr, Bsr, X86Gp, X86Gp)                                      // ANY
+     520             :   ASMJIT_INST_2x(bsr, Bsr, X86Gp, X86Mem)                                     // ANY
+     521             :   ASMJIT_INST_1x(bswap, Bswap, X86Gp)                                         // ANY
+     522             :   ASMJIT_INST_2x(bt, Bt, X86Gp, X86Gp)                                        // ANY
+     523             :   ASMJIT_INST_2i(bt, Bt, X86Gp, Imm)                                          // ANY
+     524             :   ASMJIT_INST_2x(bt, Bt, X86Mem, X86Gp)                                       // ANY
+     525             :   ASMJIT_INST_2i(bt, Bt, X86Mem, Imm)                                         // ANY
+     526             :   ASMJIT_INST_2x(btc, Btc, X86Gp, X86Gp)                                      // ANY
+     527             :   ASMJIT_INST_2i(btc, Btc, X86Gp, Imm)                                        // ANY
+     528             :   ASMJIT_INST_2x(btc, Btc, X86Mem, X86Gp)                                     // ANY
+     529             :   ASMJIT_INST_2i(btc, Btc, X86Mem, Imm)                                       // ANY
+     530             :   ASMJIT_INST_2x(btr, Btr, X86Gp, X86Gp)                                      // ANY
+     531             :   ASMJIT_INST_2i(btr, Btr, X86Gp, Imm)                                        // ANY
+     532             :   ASMJIT_INST_2x(btr, Btr, X86Mem, X86Gp)                                     // ANY
+     533             :   ASMJIT_INST_2i(btr, Btr, X86Mem, Imm)                                       // ANY
+     534             :   ASMJIT_INST_2x(bts, Bts, X86Gp, X86Gp)                                      // ANY
+     535             :   ASMJIT_INST_2i(bts, Bts, X86Gp, Imm)                                        // ANY
+     536             :   ASMJIT_INST_2x(bts, Bts, X86Mem, X86Gp)                                     // ANY
+     537             :   ASMJIT_INST_2i(bts, Bts, X86Mem, Imm)                                       // ANY
+     538             :   ASMJIT_INST_3x(bzhi, Bzhi, X86Gp, X86Gp, X86Gp)                             // BMI2
+     539             :   ASMJIT_INST_3x(bzhi, Bzhi, X86Gp, X86Mem, X86Gp)                            // BMI2
+     540             :   ASMJIT_INST_1x(cbw, Cbw, AX)                                                // ANY       [EXPLICIT] AX      <- Sign Extend AL
+     541             :   ASMJIT_INST_2x(cdq, Cdq, EDX, EAX)                                          // ANY       [EXPLICIT] EDX:EAX <- Sign Extend EAX
+     542             :   ASMJIT_INST_1x(cdqe, Cdqe, EAX)                                             // X64       [EXPLICIT] RAX     <- Sign Extend EAX
+     543             :   ASMJIT_INST_2x(cqo, Cqo, RDX, RAX)                                          // X64       [EXPLICIT] RDX:RAX <- Sign Extend RAX
+     544             :   ASMJIT_INST_2x(cwd, Cwd, DX, AX)                                            // ANY       [EXPLICIT] DX:AX   <- Sign Extend AX
+     545             :   ASMJIT_INST_1x(cwde, Cwde, EAX)                                             // ANY       [EXPLICIT] EAX     <- Sign Extend AX
+     546             :   ASMJIT_INST_1x(call, Call, X86Gp)                                           // ANY
+     547             :   ASMJIT_INST_1x(call, Call, X86Mem)                                          // ANY
+     548             :   ASMJIT_INST_1x(call, Call, Label)                                           // ANY
+     549             :   ASMJIT_INST_1i(call, Call, Imm)                                             // ANY
+     550             :   ASMJIT_INST_0x(clac, Clac)                                                  // SMAP
+     551             :   ASMJIT_INST_0x(clc, Clc)                                                    // ANY
+     552             :   ASMJIT_INST_0x(cld, Cld)                                                    // ANY
+     553             :   ASMJIT_INST_1x(clflush, Clflush, X86Mem)                                    // CLFLUSH
+     554             :   ASMJIT_INST_1x(clflushopt, Clflushopt, X86Mem)                              // CLFLUSH_OPT
+     555             :   ASMJIT_INST_0x(cli, Cli)                                                    // ANY
+     556             :   ASMJIT_INST_0x(clts, Clts)                                                  // ANY
+     557             :   ASMJIT_INST_1x(clwb, Clwb, X86Mem)                                          // CLWB
+     558             :   ASMJIT_INST_1x(clzero, Clzero, DS_ZAX)                                      // CLZERO    [EXPLICIT]
+     559             :   ASMJIT_INST_0x(cmc, Cmc)                                                    // ANY
+     560             :   ASMJIT_INST_2c(cmov, Cmov, X86Inst::condToCmovcc, X86Gp, X86Gp)             // CMOV
+     561             :   ASMJIT_INST_2c(cmov, Cmov, X86Inst::condToCmovcc, X86Gp, X86Mem)            // CMOV
+     562             :   ASMJIT_INST_2x(cmp, Cmp, X86Gp, X86Gp)                                      // ANY
+     563             :   ASMJIT_INST_2x(cmp, Cmp, X86Gp, X86Mem)                                     // ANY
+     564             :   ASMJIT_INST_2i(cmp, Cmp, X86Gp, Imm)                                        // ANY
+     565             :   ASMJIT_INST_2x(cmp, Cmp, X86Mem, X86Gp)                                     // ANY
+     566             :   ASMJIT_INST_2i(cmp, Cmp, X86Mem, Imm)                                       // ANY
+     567             :   ASMJIT_INST_2x(cmps, Cmps, DS_ZSI, ES_ZDI)                                  // ANY       [EXPLICIT]
+     568             :   ASMJIT_INST_3x(cmpxchg, Cmpxchg, X86Gp, X86Gp, ZAX)                         // I486      [EXPLICIT]
+     569             :   ASMJIT_INST_3x(cmpxchg, Cmpxchg, X86Mem, X86Gp, ZAX)                        // I486      [EXPLICIT]
+     570             :   ASMJIT_INST_5x(cmpxchg16b, Cmpxchg16b, X86Mem, RDX, RAX, RCX, RBX);         // CMPXCHG16B[EXPLICIT] m == EDX:EAX ? m <- ECX:EBX
+     571             :   ASMJIT_INST_5x(cmpxchg8b, Cmpxchg8b, X86Mem, EDX, EAX, ECX, EBX);           // CMPXCHG8B [EXPLICIT] m == RDX:RAX ? m <- RCX:RBX
+     572             :   ASMJIT_INST_4x(cpuid, Cpuid, EAX, EBX, ECX, EDX)                            // I486      [EXPLICIT] EAX:EBX:ECX:EDX  <- CPUID[EAX:ECX]
+     573             :   ASMJIT_INST_2x(crc32, Crc32, X86Gp, X86Gp)                                  // SSE4_2
+     574             :   ASMJIT_INST_2x(crc32, Crc32, X86Gp, X86Mem)                                 // SSE4_2
+     575             :   ASMJIT_INST_1x(daa, Daa, X86Gp)                                             // X86       [EXPLICIT]
+     576             :   ASMJIT_INST_1x(das, Das, X86Gp)                                             // X86       [EXPLICIT]
+     577             :   ASMJIT_INST_1x(dec, Dec, X86Gp)                                             // ANY
+     578             :   ASMJIT_INST_1x(dec, Dec, X86Mem)                                            // ANY
+     579             :   ASMJIT_INST_2x(div, Div, X86Gp, X86Gp)                                      // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / r8
+     580             :   ASMJIT_INST_2x(div, Div, X86Gp, X86Mem)                                     // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / m8
+     581             :   ASMJIT_INST_3x(div, Div, X86Gp, X86Gp, X86Gp)                               // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / r16|r32|r64
+     582             :   ASMJIT_INST_3x(div, Div, X86Gp, X86Gp, X86Mem)                              // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / m16|m32|m64
+     583           0 :   ASMJIT_INST_0x(emms, Emms)                                                  // MMX
+     584             :   ASMJIT_INST_2x(enter, Enter, Imm, Imm)                                      // ANY
+     585             :   ASMJIT_INST_1x(fxrstor, Fxrstor, X86Mem)                                    // FXSR
+     586             :   ASMJIT_INST_1x(fxrstor64, Fxrstor64, X86Mem)                                // FXSR
+     587             :   ASMJIT_INST_1x(fxsave, Fxsave, X86Mem)                                      // FXSR
+     588             :   ASMJIT_INST_1x(fxsave64, Fxsave64, X86Mem)                                  // FXSR
+     589             :   ASMJIT_INST_0x(hlt, Hlt)                                                    // ANY
+     590             :   ASMJIT_INST_2x(idiv, Idiv, X86Gp, X86Gp)                                    // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / r8
+     591             :   ASMJIT_INST_2x(idiv, Idiv, X86Gp, X86Mem)                                   // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / m8
+     592             :   ASMJIT_INST_3x(idiv, Idiv, X86Gp, X86Gp, X86Gp)                             // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / r16|r32|r64
+     593             :   ASMJIT_INST_3x(idiv, Idiv, X86Gp, X86Gp, X86Mem)                            // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / m16|m32|m64
+     594             :   ASMJIT_INST_2x(imul, Imul, X86Gp, X86Gp)                                    // ANY       [EXPLICIT] AX <- AL * r8 | ra <- ra * rb
+     595             :   ASMJIT_INST_2x(imul, Imul, X86Gp, X86Mem)                                   // ANY       [EXPLICIT] AX <- AL * m8 | ra <- ra * m16|m32|m64
+     596             :   ASMJIT_INST_2i(imul, Imul, X86Gp, Imm)                                      // ANY
+     597             :   ASMJIT_INST_3i(imul, Imul, X86Gp, X86Gp, Imm)                               // ANY
+     598             :   ASMJIT_INST_3i(imul, Imul, X86Gp, X86Mem, Imm)                              // ANY
+     599             :   ASMJIT_INST_3x(imul, Imul, X86Gp, X86Gp, X86Gp)                             // ANY       [EXPLICIT] xDX:xAX <- xAX * r16|r32|r64
+     600             :   ASMJIT_INST_3x(imul, Imul, X86Gp, X86Gp, X86Mem)                            // ANY       [EXPLICIT] xDX:xAX <- xAX * m16|m32|m64
+     601             :   ASMJIT_INST_2i(in, In, ZAX, Imm)                                            // ANY
+     602             :   ASMJIT_INST_2x(in, In, ZAX, DX)                                             // ANY
+     603             :   ASMJIT_INST_1x(inc, Inc, X86Gp)                                             // ANY
+     604             :   ASMJIT_INST_1x(inc, Inc, X86Mem)                                            // ANY
+     605             :   ASMJIT_INST_2x(ins, Ins, ES_ZDI, DX)                                        // ANY
+     606             :   ASMJIT_INST_1i(int_, Int, Imm)                                              // ANY
+     607             :   ASMJIT_INST_0x(int3, Int3)                                                  // ANY
+     608             :   ASMJIT_INST_0x(into, Into)                                                  // ANY
+     609             :   ASMJIT_INST_0x(invd, Invd)                                                  // ANY
+     610             :   ASMJIT_INST_1x(invlpg, Invlpg, X86Mem)                                      // ANY
+     611             :   ASMJIT_INST_2x(invpcid, Invpcid, X86Gp, X86Mem)                             // ANY
+     612             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, Label)                             // ANY
+     613             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, Imm)                               // ANY
+     614             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, uint64_t)                          // ANY
+     615             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, Label)                                  // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     616             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, Imm)                                    // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     617             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, uint64_t)                               // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     618             :   ASMJIT_INST_1x(jmp, Jmp, X86Gp)                                             // ANY
+     619             :   ASMJIT_INST_1x(jmp, Jmp, X86Mem)                                            // ANY
+     620           0 :   ASMJIT_INST_1x(jmp, Jmp, Label)                                             // ANY
+     621             :   ASMJIT_INST_1x(jmp, Jmp, Imm)                                               // ANY
+     622             :   ASMJIT_INST_1x(jmp, Jmp, uint64_t)                                          // ANY
+     623             :   ASMJIT_INST_1x(lahf, Lahf, AH)                                              // LAHFSAHF  [EXPLICIT] AH <- EFL
+     624             :   ASMJIT_INST_2x(lar, Lar, X86Gp, X86Gp)                                      // ANY
+     625             :   ASMJIT_INST_2x(lar, Lar, X86Gp, X86Mem)                                     // ANY
+     626             :   ASMJIT_INST_1x(ldmxcsr, Ldmxcsr, X86Mem)                                    // SSE
+     627             :   ASMJIT_INST_2x(lds, Lds, X86Gp, X86Mem)                                     // X86
+     628           0 :   ASMJIT_INST_2x(lea, Lea, X86Gp, X86Mem)                                     // ANY
+     629             :   ASMJIT_INST_0x(leave, Leave)                                                // ANY
+     630             :   ASMJIT_INST_2x(les, Les, X86Gp, X86Mem)                                     // X86
+     631             :   ASMJIT_INST_0x(lfence, Lfence)                                              // SSE2
+     632             :   ASMJIT_INST_2x(lfs, Lfs, X86Gp, X86Mem)                                     // ANY
+     633             :   ASMJIT_INST_1x(lgdt, Lgdt, X86Mem)                                          // ANY
+     634             :   ASMJIT_INST_2x(lgs, Lgs, X86Gp, X86Mem)                                     // ANY
+     635             :   ASMJIT_INST_1x(lidt, Lidt, X86Mem)                                          // ANY
+     636             :   ASMJIT_INST_1x(lldt, Lldt, X86Gp)                                           // ANY
+     637             :   ASMJIT_INST_1x(lldt, Lldt, X86Mem)                                          // ANY
+     638             :   ASMJIT_INST_1x(lmsw, Lmsw, X86Gp)                                           // ANY
+     639             :   ASMJIT_INST_1x(lmsw, Lmsw, X86Mem)                                          // ANY
+     640             :   ASMJIT_INST_2x(lods, Lods, ZAX, DS_ZSI)                                     // ANY       [EXPLICIT]
+     641             :   ASMJIT_INST_2x(loop, Loop, ZCX, Label)                                      // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     642             :   ASMJIT_INST_2x(loop, Loop, ZCX, Imm)                                        // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     643             :   ASMJIT_INST_2x(loop, Loop, ZCX, uint64_t)                                   // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     644             :   ASMJIT_INST_2x(loope, Loope, ZCX, Label)                                    // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     645             :   ASMJIT_INST_2x(loope, Loope, ZCX, Imm)                                      // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     646             :   ASMJIT_INST_2x(loope, Loope, ZCX, uint64_t)                                 // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     647             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, Label)                                  // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     648             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, Imm)                                    // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     649             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, uint64_t)                               // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     650             :   ASMJIT_INST_2x(lsl, Lsl, X86Gp, X86Gp)                                      // ANY
+     651             :   ASMJIT_INST_2x(lsl, Lsl, X86Gp, X86Mem)                                     // ANY
+     652             :   ASMJIT_INST_2x(lss, Lss, X86Gp, X86Mem)                                     // ANY
+     653             :   ASMJIT_INST_1x(ltr, Ltr, X86Gp)                                             // ANY
+     654             :   ASMJIT_INST_1x(ltr, Ltr, X86Mem)                                            // ANY
+     655             :   ASMJIT_INST_2x(lzcnt, Lzcnt, X86Gp, X86Gp)                                  // LZCNT
+     656             :   ASMJIT_INST_2x(lzcnt, Lzcnt, X86Gp, X86Mem)                                 // LZCNT
+     657             :   ASMJIT_INST_0x(mfence, Mfence)                                              // SSE2
+     658           0 :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Gp)                                      // ANY
+     659           0 :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Mem)                                     // ANY
+     660        7268 :   ASMJIT_INST_2i(mov, Mov, X86Gp, Imm)                                        // ANY
+     661           0 :   ASMJIT_INST_2x(mov, Mov, X86Mem, X86Gp)                                     // ANY
+     662             :   ASMJIT_INST_2i(mov, Mov, X86Mem, Imm)                                       // ANY
+     663             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86CReg)                                    // ANY
+     664             :   ASMJIT_INST_2x(mov, Mov, X86CReg, X86Gp)                                    // ANY
+     665             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86DReg)                                    // ANY
+     666             :   ASMJIT_INST_2x(mov, Mov, X86DReg, X86Gp)                                    // ANY
+     667             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Seg)                                     // ANY
+     668             :   ASMJIT_INST_2x(mov, Mov, X86Mem, X86Seg)                                    // ANY
+     669             :   ASMJIT_INST_2x(mov, Mov, X86Seg, X86Gp)                                     // ANY
+     670             :   ASMJIT_INST_2x(mov, Mov, X86Seg, X86Mem)                                    // ANY
+     671             :   ASMJIT_INST_2x(movbe, Movbe, X86Gp, X86Mem)                                 // MOVBE
+     672             :   ASMJIT_INST_2x(movbe, Movbe, X86Mem, X86Gp)                                 // MOVBE
+     673             :   ASMJIT_INST_2x(movnti, Movnti, X86Mem, X86Gp)                               // SSE2
+     674             :   ASMJIT_INST_2x(movs, Movs, ES_ZDI, DS_ZSI)                                  // ANY       [EXPLICIT]
+     675             :   ASMJIT_INST_2x(movsx, Movsx, X86Gp, X86Gp)                                  // ANY
+     676             :   ASMJIT_INST_2x(movsx, Movsx, X86Gp, X86Mem)                                 // ANY
+     677             :   ASMJIT_INST_2x(movsxd, Movsxd, X86Gp, X86Gp)                                // X64
+     678             :   ASMJIT_INST_2x(movsxd, Movsxd, X86Gp, X86Mem)                               // X64
+     679             :   ASMJIT_INST_2x(movzx, Movzx, X86Gp, X86Gp)                                  // ANY
+     680             :   ASMJIT_INST_2x(movzx, Movzx, X86Gp, X86Mem)                                 // ANY
+     681             :   ASMJIT_INST_2x(mul, Mul, AX, X86Gp)                                         // ANY       [EXPLICIT] AX      <-  AL * r8
+     682             :   ASMJIT_INST_2x(mul, Mul, AX, X86Mem)                                        // ANY       [EXPLICIT] AX      <-  AL * m8
+     683             :   ASMJIT_INST_3x(mul, Mul, ZDX, ZAX, X86Gp)                                   // ANY       [EXPLICIT] xDX:xAX <- xAX * r16|r32|r64
+     684             :   ASMJIT_INST_3x(mul, Mul, ZDX, ZAX, X86Mem)                                  // ANY       [EXPLICIT] xDX:xAX <- xAX * m16|m32|m64
+     685             :   ASMJIT_INST_4x(mulx, Mulx, X86Gp, X86Gp, X86Gp, ZDX)                        // BMI2      [EXPLICIT]
+     686             :   ASMJIT_INST_4x(mulx, Mulx, X86Gp, X86Gp, X86Mem, ZDX)                       // BMI2      [EXPLICIT]
+     687             :   ASMJIT_INST_1x(neg, Neg, X86Gp)                                             // ANY
+     688             :   ASMJIT_INST_1x(neg, Neg, X86Mem)                                            // ANY
+     689             :   ASMJIT_INST_0x(nop, Nop)                                                    // ANY
+     690             :   ASMJIT_INST_1x(not_, Not, X86Gp)                                            // ANY
+     691             :   ASMJIT_INST_1x(not_, Not, X86Mem)                                           // ANY
+     692             :   ASMJIT_INST_2x(or_, Or, X86Gp, X86Gp)                                       // ANY
+     693             :   ASMJIT_INST_2x(or_, Or, X86Gp, X86Mem)                                      // ANY
+     694             :   ASMJIT_INST_2i(or_, Or, X86Gp, Imm)                                         // ANY
+     695             :   ASMJIT_INST_2x(or_, Or, X86Mem, X86Gp)                                      // ANY
+     696             :   ASMJIT_INST_2i(or_, Or, X86Mem, Imm)                                        // ANY
+     697             :   ASMJIT_INST_2x(out, Out, Imm, ZAX)                                          // ANY
+     698             :   ASMJIT_INST_2i(out, Out, DX, ZAX)                                           // ANY
+     699             :   ASMJIT_INST_2i(outs, Outs, DX, DS_ZSI)                                      // ANY
+     700             :   ASMJIT_INST_0x(pause, Pause)                                                // SSE2
+     701             :   ASMJIT_INST_3x(pdep, Pdep, X86Gp, X86Gp, X86Gp)                             // BMI2
+     702             :   ASMJIT_INST_3x(pdep, Pdep, X86Gp, X86Gp, X86Mem)                            // BMI2
+     703             :   ASMJIT_INST_3x(pext, Pext, X86Gp, X86Gp, X86Gp)                             // BMI2
+     704             :   ASMJIT_INST_3x(pext, Pext, X86Gp, X86Gp, X86Mem)                            // BMI2
+     705             :   ASMJIT_INST_0x(pcommit, Pcommit)                                            // PCOMMIT
+     706        1120 :   ASMJIT_INST_1x(pop, Pop, X86Gp)                                             // ANY
+     707             :   ASMJIT_INST_1x(pop, Pop, X86Mem)                                            // ANY
+     708             :   ASMJIT_INST_1x(pop, Pop, X86Seg);                                           // ANY
+     709             :   ASMJIT_INST_0x(popa, Popa)                                                  // X86
+     710             :   ASMJIT_INST_0x(popad, Popad)                                                // X86
+     711             :   ASMJIT_INST_2x(popcnt, Popcnt, X86Gp, X86Gp)                                // POPCNT
+     712             :   ASMJIT_INST_2x(popcnt, Popcnt, X86Gp, X86Mem)                               // POPCNT
+     713             :   ASMJIT_INST_0x(popf, Popf)                                                  // ANY
+     714             :   ASMJIT_INST_0x(popfd, Popfd)                                                // X86
+     715             :   ASMJIT_INST_0x(popfq, Popfq)                                                // X64
+     716             :   ASMJIT_INST_1x(prefetch, Prefetch, X86Mem)                                  // 3DNOW
+     717             :   ASMJIT_INST_1x(prefetchnta, Prefetchnta, X86Mem)                            // SSE
+     718             :   ASMJIT_INST_1x(prefetcht0, Prefetcht0, X86Mem)                              // SSE
+     719             :   ASMJIT_INST_1x(prefetcht1, Prefetcht1, X86Mem)                              // SSE
+     720             :   ASMJIT_INST_1x(prefetcht2, Prefetcht2, X86Mem)                              // SSE
+     721             :   ASMJIT_INST_1x(prefetchw, Prefetchw, X86Mem)                                // PREFETCHW
+     722             :   ASMJIT_INST_1x(prefetchwt1, Prefetchwt1, X86Mem)                            // PREFETCHW1
+     723        1120 :   ASMJIT_INST_1x(push, Push, X86Gp)                                           // ANY
+     724             :   ASMJIT_INST_1x(push, Push, X86Mem)                                          // ANY
+     725             :   ASMJIT_INST_1x(push, Push, X86Seg)                                          // ANY
+     726             :   ASMJIT_INST_1i(push, Push, Imm)                                             // ANY
+     727             :   ASMJIT_INST_0x(pusha, Pusha)                                                // X86
+     728             :   ASMJIT_INST_0x(pushad, Pushad)                                              // X86
+     729             :   ASMJIT_INST_0x(pushf, Pushf)                                                // ANY
+     730             :   ASMJIT_INST_0x(pushfd, Pushfd)                                              // X86
+     731             :   ASMJIT_INST_0x(pushfq, Pushfq)                                              // X64
+     732             :   ASMJIT_INST_2x(rcl, Rcl, X86Gp, CL)                                         // ANY
+     733             :   ASMJIT_INST_2x(rcl, Rcl, X86Mem, CL)                                        // ANY
+     734             :   ASMJIT_INST_2i(rcl, Rcl, X86Gp, Imm)                                        // ANY
+     735             :   ASMJIT_INST_2i(rcl, Rcl, X86Mem, Imm)                                       // ANY
+     736             :   ASMJIT_INST_2x(rcr, Rcr, X86Gp, CL)                                         // ANY
+     737             :   ASMJIT_INST_2x(rcr, Rcr, X86Mem, CL)                                        // ANY
+     738             :   ASMJIT_INST_2i(rcr, Rcr, X86Gp, Imm)                                        // ANY
+     739             :   ASMJIT_INST_2i(rcr, Rcr, X86Mem, Imm)                                       // ANY
+     740             :   ASMJIT_INST_1x(rdfsbase, Rdfsbase, X86Gp)                                   // FSGSBASE
+     741             :   ASMJIT_INST_1x(rdgsbase, Rdgsbase, X86Gp)                                   // FSGSBASE
+     742             :   ASMJIT_INST_1x(rdrand, Rdrand, X86Gp)                                       // RDRAND
+     743             :   ASMJIT_INST_1x(rdseed, Rdseed, X86Gp)                                       // RDSEED
+     744             :   ASMJIT_INST_3x(rdmsr, Rdmsr, EDX, EAX, ECX)                                 // MSR       [EXPLICIT] RDX:EAX     <- MSR[ECX]
+     745             :   ASMJIT_INST_3x(rdpmc, Rdpmc, EDX, EAX, ECX)                                 // ANY       [EXPLICIT] RDX:EAX     <- PMC[ECX]
+     746             :   ASMJIT_INST_2x(rdtsc, Rdtsc, EDX, EAX)                                      // RDTSC     [EXPLICIT] EDX:EAX     <- Counter
+     747             :   ASMJIT_INST_3x(rdtscp, Rdtscp, EDX, EAX, ECX)                               // RDTSCP    [EXPLICIT] EDX:EAX:EXC <- Counter
+     748             :   ASMJIT_INST_2x(rol, Rol, X86Gp, CL)                                         // ANY
+     749             :   ASMJIT_INST_2x(rol, Rol, X86Mem, CL)                                        // ANY
+     750             :   ASMJIT_INST_2i(rol, Rol, X86Gp, Imm)                                        // ANY
+     751             :   ASMJIT_INST_2i(rol, Rol, X86Mem, Imm)                                       // ANY
+     752             :   ASMJIT_INST_2x(ror, Ror, X86Gp, CL)                                         // ANY
+     753             :   ASMJIT_INST_2x(ror, Ror, X86Mem, CL)                                        // ANY
+     754             :   ASMJIT_INST_2i(ror, Ror, X86Gp, Imm)                                        // ANY
+     755             :   ASMJIT_INST_2i(ror, Ror, X86Mem, Imm)                                       // ANY
+     756             :   ASMJIT_INST_3i(rorx, Rorx, X86Gp, X86Gp, Imm)                               // BMI2
+     757             :   ASMJIT_INST_3i(rorx, Rorx, X86Gp, X86Mem, Imm)                              // BMI2
+     758             :   ASMJIT_INST_0x(rsm, Rsm)                                                    // X86
+     759             :   ASMJIT_INST_2x(sbb, Sbb, X86Gp, X86Gp)                                      // ANY
+     760             :   ASMJIT_INST_2x(sbb, Sbb, X86Gp, X86Mem)                                     // ANY
+     761             :   ASMJIT_INST_2i(sbb, Sbb, X86Gp, Imm)                                        // ANY
+     762             :   ASMJIT_INST_2x(sbb, Sbb, X86Mem, X86Gp)                                     // ANY
+     763             :   ASMJIT_INST_2i(sbb, Sbb, X86Mem, Imm)                                       // ANY
+     764             :   ASMJIT_INST_1x(sahf, Sahf, AH)                                              // LAHFSAHF  [EXPLICIT] EFL <- AH
+     765             :   ASMJIT_INST_2x(sal, Sal, X86Gp, CL)                                         // ANY
+     766             :   ASMJIT_INST_2x(sal, Sal, X86Mem, CL)                                        // ANY
+     767             :   ASMJIT_INST_2i(sal, Sal, X86Gp, Imm)                                        // ANY
+     768             :   ASMJIT_INST_2i(sal, Sal, X86Mem, Imm)                                       // ANY
+     769             :   ASMJIT_INST_2x(sar, Sar, X86Gp, CL)                                         // ANY
+     770             :   ASMJIT_INST_2x(sar, Sar, X86Mem, CL)                                        // ANY
+     771             :   ASMJIT_INST_2i(sar, Sar, X86Gp, Imm)                                        // ANY
+     772             :   ASMJIT_INST_2i(sar, Sar, X86Mem, Imm)                                       // ANY
+     773             :   ASMJIT_INST_3x(sarx, Sarx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     774             :   ASMJIT_INST_3x(sarx, Sarx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     775             :   ASMJIT_INST_2x(scas, Scas, ZAX, ES_ZDI)                                     // ANY       [EXPLICIT]
+     776             :   ASMJIT_INST_1c(set, Set, X86Inst::condToSetcc, X86Gp)                       // ANY
+     777             :   ASMJIT_INST_1c(set, Set, X86Inst::condToSetcc, X86Mem)                      // ANY
+     778             :   ASMJIT_INST_0x(sfence, Sfence)                                              // SSE
+     779             :   ASMJIT_INST_1x(sgdt, Sgdt, X86Mem)                                          // ANY
+     780             :   ASMJIT_INST_2x(shl, Shl, X86Gp, CL)                                         // ANY
+     781             :   ASMJIT_INST_2x(shl, Shl, X86Mem, CL)                                        // ANY
+     782             :   ASMJIT_INST_2i(shl, Shl, X86Gp, Imm)                                        // ANY
+     783             :   ASMJIT_INST_2i(shl, Shl, X86Mem, Imm)                                       // ANY
+     784             :   ASMJIT_INST_3x(shlx, Shlx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     785             :   ASMJIT_INST_3x(shlx, Shlx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     786             :   ASMJIT_INST_2x(shr, Shr, X86Gp, CL)                                         // ANY
+     787             :   ASMJIT_INST_2x(shr, Shr, X86Mem, CL)                                        // ANY
+     788             :   ASMJIT_INST_2i(shr, Shr, X86Gp, Imm)                                        // ANY
+     789             :   ASMJIT_INST_2i(shr, Shr, X86Mem, Imm)                                       // ANY
+     790             :   ASMJIT_INST_3x(shrx, Shrx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     791             :   ASMJIT_INST_3x(shrx, Shrx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     792             :   ASMJIT_INST_3x(shld, Shld, X86Gp, X86Gp, CL)                                // ANY
+     793             :   ASMJIT_INST_3x(shld, Shld, X86Mem, X86Gp, CL)                               // ANY
+     794             :   ASMJIT_INST_3i(shld, Shld, X86Gp, X86Gp, Imm)                               // ANY
+     795             :   ASMJIT_INST_3i(shld, Shld, X86Mem, X86Gp, Imm)                              // ANY
+     796             :   ASMJIT_INST_3x(shrd, Shrd, X86Gp, X86Gp, CL)                                // ANY
+     797             :   ASMJIT_INST_3x(shrd, Shrd, X86Mem, X86Gp, CL)                               // ANY
+     798             :   ASMJIT_INST_3i(shrd, Shrd, X86Gp, X86Gp, Imm)                               // ANY
+     799             :   ASMJIT_INST_3i(shrd, Shrd, X86Mem, X86Gp, Imm)                              // ANY
+     800             :   ASMJIT_INST_1x(sidt, Sidt, X86Mem)                                          // ANY
+     801             :   ASMJIT_INST_1x(sldt, Sldt, X86Gp)                                           // ANY
+     802             :   ASMJIT_INST_1x(sldt, Sldt, X86Mem)                                          // ANY
+     803             :   ASMJIT_INST_1x(smsw, Smsw, X86Gp)                                           // ANY
+     804             :   ASMJIT_INST_1x(smsw, Smsw, X86Mem)                                          // ANY
+     805             :   ASMJIT_INST_0x(stac, Stac)                                                  // SMAP
+     806             :   ASMJIT_INST_0x(stc, Stc)                                                    // ANY
+     807             :   ASMJIT_INST_0x(std, Std)                                                    // ANY
+     808             :   ASMJIT_INST_0x(sti, Sti)                                                    // ANY
+     809             :   ASMJIT_INST_1x(stmxcsr, Stmxcsr, X86Mem)                                    // SSE
+     810             :   ASMJIT_INST_2x(stos, Stos, ES_ZDI, ZAX)                                     // ANY       [EXPLICIT]
+     811             :   ASMJIT_INST_1x(str, Str, X86Gp)                                             // ANY
+     812             :   ASMJIT_INST_1x(str, Str, X86Mem)                                            // ANY
+     813             :   ASMJIT_INST_2x(sub, Sub, X86Gp, X86Gp)                                      // ANY
+     814             :   ASMJIT_INST_2x(sub, Sub, X86Gp, X86Mem)                                     // ANY
+     815         932 :   ASMJIT_INST_2i(sub, Sub, X86Gp, Imm)                                        // ANY
+     816             :   ASMJIT_INST_2x(sub, Sub, X86Mem, X86Gp)                                     // ANY
+     817             :   ASMJIT_INST_2i(sub, Sub, X86Mem, Imm)                                       // ANY
+     818             :   ASMJIT_INST_0x(swapgs, Swapgs)                                              // X64
+     819             :   ASMJIT_INST_2x(t1mskc, T1mskc, X86Gp, X86Gp)                                // TBM
+     820             :   ASMJIT_INST_2x(t1mskc, T1mskc, X86Gp, X86Mem)                               // TBM
+     821             :   ASMJIT_INST_2x(test, Test, X86Gp, X86Gp)                                    // ANY
+     822             :   ASMJIT_INST_2i(test, Test, X86Gp, Imm)                                      // ANY
+     823             :   ASMJIT_INST_2x(test, Test, X86Mem, X86Gp)                                   // ANY
+     824             :   ASMJIT_INST_2i(test, Test, X86Mem, Imm)                                     // ANY
+     825             :   ASMJIT_INST_2x(tzcnt, Tzcnt, X86Gp, X86Gp)                                  // BMI
+     826             :   ASMJIT_INST_2x(tzcnt, Tzcnt, X86Gp, X86Mem)                                 // BMI
+     827             :   ASMJIT_INST_2x(tzmsk, Tzmsk, X86Gp, X86Gp)                                  // TBM
+     828             :   ASMJIT_INST_2x(tzmsk, Tzmsk, X86Gp, X86Mem)                                 // TBM
+     829             :   ASMJIT_INST_0x(ud2, Ud2)                                                    // ANY
+     830             :   ASMJIT_INST_1x(verr, Verr, X86Gp)                                           // ANY
+     831             :   ASMJIT_INST_1x(verr, Verr, X86Mem)                                          // ANY
+     832             :   ASMJIT_INST_1x(verw, Verw, X86Gp)                                           // ANY
+     833             :   ASMJIT_INST_1x(verw, Verw, X86Mem)                                          // ANY
+     834             :   ASMJIT_INST_1x(wrfsbase, Wrfsbase, X86Gp)                                   // FSGSBASE
+     835             :   ASMJIT_INST_1x(wrgsbase, Wrgsbase, X86Gp)                                   // FSGSBASE
+     836             :   ASMJIT_INST_3x(wrmsr, Wrmsr, EDX, EAX, ECX)                                 // MSR       [EXPLICIT] RDX:EAX     -> MSR[ECX]
+     837             :   ASMJIT_INST_0x(xabort, Xabort)                                              // RTM
+     838             :   ASMJIT_INST_2x(xadd, Xadd, X86Gp, X86Gp)                                    // ANY
+     839             :   ASMJIT_INST_2x(xadd, Xadd, X86Mem, X86Gp)                                   // ANY
+     840             :   ASMJIT_INST_1x(xbegin, Xbegin, Label)                                       // RTM
+     841             :   ASMJIT_INST_1x(xbegin, Xbegin, Imm)                                         // RTM
+     842             :   ASMJIT_INST_1x(xbegin, Xbegin, uint64_t)                                    // RTM
+     843             :   ASMJIT_INST_2x(xchg, Xchg, X86Gp, X86Gp)                                    // ANY
+     844             :   ASMJIT_INST_2x(xchg, Xchg, X86Mem, X86Gp)                                   // ANY
+     845             :   ASMJIT_INST_2x(xchg, Xchg, X86Gp, X86Mem)                                   // ANY
+     846             :   ASMJIT_INST_0x(xend, Xend)                                                  // RTM
+     847             :   ASMJIT_INST_3x(xgetbv, Xgetbv, EDX, EAX, ECX)                               // XSAVE     [EXPLICIT] EDX:EAX <- XCR[ECX]
+     848             :   ASMJIT_INST_2x(xor_, Xor, X86Gp, X86Gp)                                     // ANY
+     849             :   ASMJIT_INST_2x(xor_, Xor, X86Gp, X86Mem)                                    // ANY
+     850             :   ASMJIT_INST_2i(xor_, Xor, X86Gp, Imm)                                       // ANY
+     851             :   ASMJIT_INST_2x(xor_, Xor, X86Mem, X86Gp)                                    // ANY
+     852             :   ASMJIT_INST_2i(xor_, Xor, X86Mem, Imm)                                      // ANY
+     853             :   ASMJIT_INST_3x(xsetbv, Xsetbv, EDX, EAX, ECX)                               // XSAVE     [EXPLICIT] XCR[ECX] <- EDX:EAX
+     854             :   ASMJIT_INST_0x(xtest, Xtest)                                                // TSX
+     855             : 
+     856             :   // --------------------------------------------------------------------------
+     857             :   // [FPU Instructions]
+     858             :   // --------------------------------------------------------------------------
+     859             : 
+     860             :   ASMJIT_INST_0x(f2xm1, F2xm1)                                                // FPU
+     861             :   ASMJIT_INST_0x(fabs, Fabs)                                                  // FPU
+     862             :   ASMJIT_INST_2x(fadd, Fadd, X86Fp, X86Fp)                                    // FPU
+     863             :   ASMJIT_INST_1x(fadd, Fadd, X86Mem)                                          // FPU
+     864             :   ASMJIT_INST_1x(faddp, Faddp, X86Fp)                                         // FPU
+     865             :   ASMJIT_INST_0x(faddp, Faddp)                                                // FPU
+     866             :   ASMJIT_INST_1x(fbld, Fbld, X86Mem)                                          // FPU
+     867             :   ASMJIT_INST_1x(fbstp, Fbstp, X86Mem)                                        // FPU
+     868             :   ASMJIT_INST_0x(fchs, Fchs)                                                  // FPU
+     869             :   ASMJIT_INST_0x(fclex, Fclex)                                                // FPU
+     870             :   ASMJIT_INST_1x(fcmovb, Fcmovb, X86Fp)                                       // FPU
+     871             :   ASMJIT_INST_1x(fcmovbe, Fcmovbe, X86Fp)                                     // FPU
+     872             :   ASMJIT_INST_1x(fcmove, Fcmove, X86Fp)                                       // FPU
+     873             :   ASMJIT_INST_1x(fcmovnb, Fcmovnb, X86Fp)                                     // FPU
+     874             :   ASMJIT_INST_1x(fcmovnbe, Fcmovnbe, X86Fp)                                   // FPU
+     875             :   ASMJIT_INST_1x(fcmovne, Fcmovne, X86Fp)                                     // FPU
+     876             :   ASMJIT_INST_1x(fcmovnu, Fcmovnu, X86Fp)                                     // FPU
+     877             :   ASMJIT_INST_1x(fcmovu, Fcmovu, X86Fp)                                       // FPU
+     878             :   ASMJIT_INST_1x(fcom, Fcom, X86Fp)                                           // FPU
+     879             :   ASMJIT_INST_0x(fcom, Fcom)                                                  // FPU
+     880             :   ASMJIT_INST_1x(fcom, Fcom, X86Mem)                                          // FPU
+     881             :   ASMJIT_INST_1x(fcomp, Fcomp, X86Fp)                                         // FPU
+     882             :   ASMJIT_INST_0x(fcomp, Fcomp)                                                // FPU
+     883             :   ASMJIT_INST_1x(fcomp, Fcomp, X86Mem)                                        // FPU
+     884             :   ASMJIT_INST_0x(fcompp, Fcompp)                                              // FPU
+     885             :   ASMJIT_INST_1x(fcomi, Fcomi, X86Fp)                                         // FPU
+     886             :   ASMJIT_INST_1x(fcomip, Fcomip, X86Fp)                                       // FPU
+     887             :   ASMJIT_INST_0x(fcos, Fcos)                                                  // FPU
+     888             :   ASMJIT_INST_0x(fdecstp, Fdecstp)                                            // FPU
+     889             :   ASMJIT_INST_2x(fdiv, Fdiv, X86Fp, X86Fp)                                    // FPU
+     890             :   ASMJIT_INST_1x(fdiv, Fdiv, X86Mem)                                          // FPU
+     891             :   ASMJIT_INST_1x(fdivp, Fdivp, X86Fp)                                         // FPU
+     892             :   ASMJIT_INST_0x(fdivp, Fdivp)                                                // FPU
+     893             :   ASMJIT_INST_2x(fdivr, Fdivr, X86Fp, X86Fp)                                  // FPU
+     894             :   ASMJIT_INST_1x(fdivr, Fdivr, X86Mem)                                        // FPU
+     895             :   ASMJIT_INST_1x(fdivrp, Fdivrp, X86Fp)                                       // FPU
+     896             :   ASMJIT_INST_0x(fdivrp, Fdivrp)                                              // FPU
+     897             :   ASMJIT_INST_1x(ffree, Ffree, X86Fp)                                         // FPU
+     898             :   ASMJIT_INST_1x(fiadd, Fiadd, X86Mem)                                        // FPU
+     899             :   ASMJIT_INST_1x(ficom, Ficom, X86Mem)                                        // FPU
+     900             :   ASMJIT_INST_1x(ficomp, Ficomp, X86Mem)                                      // FPU
+     901             :   ASMJIT_INST_1x(fidiv, Fidiv, X86Mem)                                        // FPU
+     902             :   ASMJIT_INST_1x(fidivr, Fidivr, X86Mem)                                      // FPU
+     903             :   ASMJIT_INST_1x(fild, Fild, X86Mem)                                          // FPU
+     904             :   ASMJIT_INST_1x(fimul, Fimul, X86Mem)                                        // FPU
+     905             :   ASMJIT_INST_0x(fincstp, Fincstp)                                            // FPU
+     906             :   ASMJIT_INST_0x(finit, Finit)                                                // FPU
+     907             :   ASMJIT_INST_1x(fisub, Fisub, X86Mem)                                        // FPU
+     908             :   ASMJIT_INST_1x(fisubr, Fisubr, X86Mem)                                      // FPU
+     909             :   ASMJIT_INST_0x(fninit, Fninit)                                              // FPU
+     910             :   ASMJIT_INST_1x(fist, Fist, X86Mem)                                          // FPU
+     911             :   ASMJIT_INST_1x(fistp, Fistp, X86Mem)                                        // FPU
+     912             :   ASMJIT_INST_1x(fisttp, Fisttp, X86Mem)                                      // FPU+SSE3
+     913           0 :   ASMJIT_INST_1x(fld, Fld, X86Mem)                                            // FPU
+     914             :   ASMJIT_INST_1x(fld, Fld, X86Fp)                                             // FPU
+     915             :   ASMJIT_INST_0x(fld1, Fld1)                                                  // FPU
+     916             :   ASMJIT_INST_0x(fldl2t, Fldl2t)                                              // FPU
+     917             :   ASMJIT_INST_0x(fldl2e, Fldl2e)                                              // FPU
+     918             :   ASMJIT_INST_0x(fldpi, Fldpi)                                                // FPU
+     919             :   ASMJIT_INST_0x(fldlg2, Fldlg2)                                              // FPU
+     920             :   ASMJIT_INST_0x(fldln2, Fldln2)                                              // FPU
+     921             :   ASMJIT_INST_0x(fldz, Fldz)                                                  // FPU
+     922             :   ASMJIT_INST_1x(fldcw, Fldcw, X86Mem)                                        // FPU
+     923             :   ASMJIT_INST_1x(fldenv, Fldenv, X86Mem)                                      // FPU
+     924             :   ASMJIT_INST_2x(fmul, Fmul, X86Fp, X86Fp)                                    // FPU
+     925             :   ASMJIT_INST_1x(fmul, Fmul, X86Mem)                                          // FPU
+     926             :   ASMJIT_INST_1x(fmulp, Fmulp, X86Fp)                                         // FPU
+     927             :   ASMJIT_INST_0x(fmulp, Fmulp)                                                // FPU
+     928             :   ASMJIT_INST_0x(fnclex, Fnclex)                                              // FPU
+     929             :   ASMJIT_INST_0x(fnop, Fnop)                                                  // FPU
+     930             :   ASMJIT_INST_1x(fnsave, Fnsave, X86Mem)                                      // FPU
+     931             :   ASMJIT_INST_1x(fnstenv, Fnstenv, X86Mem)                                    // FPU
+     932             :   ASMJIT_INST_1x(fnstcw, Fnstcw, X86Mem)                                      // FPU
+     933             :   ASMJIT_INST_0x(fpatan, Fpatan)                                              // FPU
+     934             :   ASMJIT_INST_0x(fprem, Fprem)                                                // FPU
+     935             :   ASMJIT_INST_0x(fprem1, Fprem1)                                              // FPU
+     936             :   ASMJIT_INST_0x(fptan, Fptan)                                                // FPU
+     937             :   ASMJIT_INST_0x(frndint, Frndint)                                            // FPU
+     938             :   ASMJIT_INST_1x(frstor, Frstor, X86Mem)                                      // FPU
+     939             :   ASMJIT_INST_1x(fsave, Fsave, X86Mem)                                        // FPU
+     940             :   ASMJIT_INST_0x(fscale, Fscale)                                              // FPU
+     941             :   ASMJIT_INST_0x(fsin, Fsin)                                                  // FPU
+     942             :   ASMJIT_INST_0x(fsincos, Fsincos)                                            // FPU
+     943             :   ASMJIT_INST_0x(fsqrt, Fsqrt)                                                // FPU
+     944             :   ASMJIT_INST_1x(fst, Fst, X86Mem)                                            // FPU
+     945             :   ASMJIT_INST_1x(fst, Fst, X86Fp)                                             // FPU
+     946           0 :   ASMJIT_INST_1x(fstp, Fstp, X86Mem)                                          // FPU
+     947             :   ASMJIT_INST_1x(fstp, Fstp, X86Fp)                                           // FPU
+     948             :   ASMJIT_INST_1x(fstcw, Fstcw, X86Mem)                                        // FPU
+     949             :   ASMJIT_INST_1x(fstenv, Fstenv, X86Mem)                                      // FPU
+     950             :   ASMJIT_INST_2x(fsub, Fsub, X86Fp, X86Fp)                                    // FPU
+     951             :   ASMJIT_INST_1x(fsub, Fsub, X86Mem)                                          // FPU
+     952             :   ASMJIT_INST_1x(fsubp, Fsubp, X86Fp)                                         // FPU
+     953             :   ASMJIT_INST_0x(fsubp, Fsubp)                                                // FPU
+     954             :   ASMJIT_INST_2x(fsubr, Fsubr, X86Fp, X86Fp)                                  // FPU
+     955             :   ASMJIT_INST_1x(fsubr, Fsubr, X86Mem)                                        // FPU
+     956             :   ASMJIT_INST_1x(fsubrp, Fsubrp, X86Fp)                                       // FPU
+     957             :   ASMJIT_INST_0x(fsubrp, Fsubrp)                                              // FPU
+     958             :   ASMJIT_INST_0x(ftst, Ftst)                                                  // FPU
+     959             :   ASMJIT_INST_1x(fucom, Fucom, X86Fp)                                         // FPU
+     960             :   ASMJIT_INST_0x(fucom, Fucom)                                                // FPU
+     961             :   ASMJIT_INST_1x(fucomi, Fucomi, X86Fp)                                       // FPU
+     962             :   ASMJIT_INST_1x(fucomip, Fucomip, X86Fp)                                     // FPU
+     963             :   ASMJIT_INST_1x(fucomp, Fucomp, X86Fp)                                       // FPU
+     964             :   ASMJIT_INST_0x(fucomp, Fucomp)                                              // FPU
+     965             :   ASMJIT_INST_0x(fucompp, Fucompp)                                            // FPU
+     966             :   ASMJIT_INST_0x(fwait, Fwait)                                                // FPU
+     967             :   ASMJIT_INST_0x(fxam, Fxam)                                                  // FPU
+     968             :   ASMJIT_INST_1x(fxch, Fxch, X86Fp)                                           // FPU
+     969             :   ASMJIT_INST_0x(fxtract, Fxtract)                                            // FPU
+     970             :   ASMJIT_INST_0x(fyl2x, Fyl2x)                                                // FPU
+     971             :   ASMJIT_INST_0x(fyl2xp1, Fyl2xp1)                                            // FPU
+     972             :   ASMJIT_INST_1x(fstsw, Fstsw, X86Gp)                                         // FPU
+     973             :   ASMJIT_INST_1x(fstsw, Fstsw, X86Mem)                                        // FPU
+     974             :   ASMJIT_INST_1x(fnstsw, Fnstsw, X86Gp)                                       // FPU
+     975             :   ASMJIT_INST_1x(fnstsw, Fnstsw, X86Mem)                                      // FPU
+     976             : 
+     977             :   // --------------------------------------------------------------------------
+     978             :   // [MMX & SSE Instructions]
+     979             :   // --------------------------------------------------------------------------
+     980             : 
+     981             :   ASMJIT_INST_2x(addpd, Addpd, X86Xmm, X86Xmm)                                // SSE2
+     982             :   ASMJIT_INST_2x(addpd, Addpd, X86Xmm, X86Mem)                                // SSE2
+     983             :   ASMJIT_INST_2x(addps, Addps, X86Xmm, X86Xmm)                                // SSE
+     984             :   ASMJIT_INST_2x(addps, Addps, X86Xmm, X86Mem)                                // SSE
+     985        1986 :   ASMJIT_INST_2x(addsd, Addsd, X86Xmm, X86Xmm)                                // SSE2
+     986             :   ASMJIT_INST_2x(addsd, Addsd, X86Xmm, X86Mem)                                // SSE2
+     987             :   ASMJIT_INST_2x(addss, Addss, X86Xmm, X86Xmm)                                // SSE
+     988             :   ASMJIT_INST_2x(addss, Addss, X86Xmm, X86Mem)                                // SSE
+     989             :   ASMJIT_INST_2x(addsubpd, Addsubpd, X86Xmm, X86Xmm)                          // SSE3
+     990             :   ASMJIT_INST_2x(addsubpd, Addsubpd, X86Xmm, X86Mem)                          // SSE3
+     991             :   ASMJIT_INST_2x(addsubps, Addsubps, X86Xmm, X86Xmm)                          // SSE3
+     992             :   ASMJIT_INST_2x(addsubps, Addsubps, X86Xmm, X86Mem)                          // SSE3
+     993             :   ASMJIT_INST_2x(andnpd, Andnpd, X86Xmm, X86Xmm)                              // SSE2
+     994             :   ASMJIT_INST_2x(andnpd, Andnpd, X86Xmm, X86Mem)                              // SSE2
+     995             :   ASMJIT_INST_2x(andnps, Andnps, X86Xmm, X86Xmm)                              // SSE
+     996             :   ASMJIT_INST_2x(andnps, Andnps, X86Xmm, X86Mem)                              // SSE
+     997             :   ASMJIT_INST_2x(andpd, Andpd, X86Xmm, X86Xmm)                                // SSE2
+     998             :   ASMJIT_INST_2x(andpd, Andpd, X86Xmm, X86Mem)                                // SSE2
+     999         120 :   ASMJIT_INST_2x(andps, Andps, X86Xmm, X86Xmm)                                // SSE
+    1000             :   ASMJIT_INST_2x(andps, Andps, X86Xmm, X86Mem)                                // SSE
+    1001             :   ASMJIT_INST_3i(blendpd, Blendpd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1002             :   ASMJIT_INST_3i(blendpd, Blendpd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1003             :   ASMJIT_INST_3i(blendps, Blendps, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1004             :   ASMJIT_INST_3i(blendps, Blendps, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1005             :   ASMJIT_INST_3x(blendvpd, Blendvpd, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1006             :   ASMJIT_INST_3x(blendvpd, Blendvpd, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1007             :   ASMJIT_INST_3x(blendvps, Blendvps, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1008             :   ASMJIT_INST_3x(blendvps, Blendvps, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1009             :   ASMJIT_INST_3i(cmppd, Cmppd, X86Xmm, X86Xmm, Imm)                           // SSE2
+    1010             :   ASMJIT_INST_3i(cmppd, Cmppd, X86Xmm, X86Mem, Imm)                           // SSE2
+    1011             :   ASMJIT_INST_3i(cmpps, Cmpps, X86Xmm, X86Xmm, Imm)                           // SSE
+    1012             :   ASMJIT_INST_3i(cmpps, Cmpps, X86Xmm, X86Mem, Imm)                           // SSE
+    1013         120 :   ASMJIT_INST_3i(cmpsd, Cmpsd, X86Xmm, X86Xmm, Imm)                           // SSE2
+    1014             :   ASMJIT_INST_3i(cmpsd, Cmpsd, X86Xmm, X86Mem, Imm)                           // SSE2
+    1015             :   ASMJIT_INST_3i(cmpss, Cmpss, X86Xmm, X86Xmm, Imm)                           // SSE
+    1016             :   ASMJIT_INST_3i(cmpss, Cmpss, X86Xmm, X86Mem, Imm)                           // SSE
+    1017             :   ASMJIT_INST_2x(comisd, Comisd, X86Xmm, X86Xmm)                              // SSE2
+    1018             :   ASMJIT_INST_2x(comisd, Comisd, X86Xmm, X86Mem)                              // SSE2
+    1019             :   ASMJIT_INST_2x(comiss, Comiss, X86Xmm, X86Xmm)                              // SSE
+    1020             :   ASMJIT_INST_2x(comiss, Comiss, X86Xmm, X86Mem)                              // SSE
+    1021             :   ASMJIT_INST_2x(cvtdq2pd, Cvtdq2pd, X86Xmm, X86Xmm)                          // SSE2
+    1022             :   ASMJIT_INST_2x(cvtdq2pd, Cvtdq2pd, X86Xmm, X86Mem)                          // SSE2
+    1023             :   ASMJIT_INST_2x(cvtdq2ps, Cvtdq2ps, X86Xmm, X86Xmm)                          // SSE2
+    1024             :   ASMJIT_INST_2x(cvtdq2ps, Cvtdq2ps, X86Xmm, X86Mem)                          // SSE2
+    1025             :   ASMJIT_INST_2x(cvtpd2dq, Cvtpd2dq, X86Xmm, X86Xmm)                          // SSE2
+    1026             :   ASMJIT_INST_2x(cvtpd2dq, Cvtpd2dq, X86Xmm, X86Mem)                          // SSE2
+    1027             :   ASMJIT_INST_2x(cvtpd2pi, Cvtpd2pi, X86Mm, X86Xmm)                           // SSE2
+    1028             :   ASMJIT_INST_2x(cvtpd2pi, Cvtpd2pi, X86Mm, X86Mem)                           // SSE2
+    1029             :   ASMJIT_INST_2x(cvtpd2ps, Cvtpd2ps, X86Xmm, X86Xmm)                          // SSE2
+    1030             :   ASMJIT_INST_2x(cvtpd2ps, Cvtpd2ps, X86Xmm, X86Mem)                          // SSE2
+    1031             :   ASMJIT_INST_2x(cvtpi2pd, Cvtpi2pd, X86Xmm, X86Mm)                           // SSE2
+    1032             :   ASMJIT_INST_2x(cvtpi2pd, Cvtpi2pd, X86Xmm, X86Mem)                          // SSE2
+    1033             :   ASMJIT_INST_2x(cvtpi2ps, Cvtpi2ps, X86Xmm, X86Mm)                           // SSE
+    1034             :   ASMJIT_INST_2x(cvtpi2ps, Cvtpi2ps, X86Xmm, X86Mem)                          // SSE
+    1035             :   ASMJIT_INST_2x(cvtps2dq, Cvtps2dq, X86Xmm, X86Xmm)                          // SSE2
+    1036             :   ASMJIT_INST_2x(cvtps2dq, Cvtps2dq, X86Xmm, X86Mem)                          // SSE2
+    1037             :   ASMJIT_INST_2x(cvtps2pd, Cvtps2pd, X86Xmm, X86Xmm)                          // SSE2
+    1038             :   ASMJIT_INST_2x(cvtps2pd, Cvtps2pd, X86Xmm, X86Mem)                          // SSE2
+    1039             :   ASMJIT_INST_2x(cvtps2pi, Cvtps2pi, X86Mm, X86Xmm)                           // SSE
+    1040             :   ASMJIT_INST_2x(cvtps2pi, Cvtps2pi, X86Mm, X86Mem)                           // SSE
+    1041             :   ASMJIT_INST_2x(cvtsd2si, Cvtsd2si, X86Gp, X86Xmm)                           // SSE2
+    1042             :   ASMJIT_INST_2x(cvtsd2si, Cvtsd2si, X86Gp, X86Mem)                           // SSE2
+    1043             :   ASMJIT_INST_2x(cvtsd2ss, Cvtsd2ss, X86Xmm, X86Xmm)                          // SSE2
+    1044             :   ASMJIT_INST_2x(cvtsd2ss, Cvtsd2ss, X86Xmm, X86Mem)                          // SSE2
+    1045             :   ASMJIT_INST_2x(cvtsi2sd, Cvtsi2sd, X86Xmm, X86Gp)                           // SSE2
+    1046             :   ASMJIT_INST_2x(cvtsi2sd, Cvtsi2sd, X86Xmm, X86Mem)                          // SSE2
+    1047             :   ASMJIT_INST_2x(cvtsi2ss, Cvtsi2ss, X86Xmm, X86Gp)                           // SSE
+    1048             :   ASMJIT_INST_2x(cvtsi2ss, Cvtsi2ss, X86Xmm, X86Mem)                          // SSE
+    1049             :   ASMJIT_INST_2x(cvtss2sd, Cvtss2sd, X86Xmm, X86Xmm)                          // SSE2
+    1050             :   ASMJIT_INST_2x(cvtss2sd, Cvtss2sd, X86Xmm, X86Mem)                          // SSE2
+    1051             :   ASMJIT_INST_2x(cvtss2si, Cvtss2si, X86Gp, X86Xmm)                           // SSE
+    1052             :   ASMJIT_INST_2x(cvtss2si, Cvtss2si, X86Gp, X86Mem)                           // SSE
+    1053             :   ASMJIT_INST_2x(cvttpd2pi, Cvttpd2pi, X86Mm, X86Xmm)                         // SSE2
+    1054             :   ASMJIT_INST_2x(cvttpd2pi, Cvttpd2pi, X86Mm, X86Mem)                         // SSE2
+    1055             :   ASMJIT_INST_2x(cvttpd2dq, Cvttpd2dq, X86Xmm, X86Xmm)                        // SSE2
+    1056             :   ASMJIT_INST_2x(cvttpd2dq, Cvttpd2dq, X86Xmm, X86Mem)                        // SSE2
+    1057             :   ASMJIT_INST_2x(cvttps2dq, Cvttps2dq, X86Xmm, X86Xmm)                        // SSE2
+    1058             :   ASMJIT_INST_2x(cvttps2dq, Cvttps2dq, X86Xmm, X86Mem)                        // SSE2
+    1059             :   ASMJIT_INST_2x(cvttps2pi, Cvttps2pi, X86Mm, X86Xmm)                         // SSE
+    1060             :   ASMJIT_INST_2x(cvttps2pi, Cvttps2pi, X86Mm, X86Mem)                         // SSE
+    1061             :   ASMJIT_INST_2x(cvttsd2si, Cvttsd2si, X86Gp, X86Xmm)                         // SSE2
+    1062             :   ASMJIT_INST_2x(cvttsd2si, Cvttsd2si, X86Gp, X86Mem)                         // SSE2
+    1063             :   ASMJIT_INST_2x(cvttss2si, Cvttss2si, X86Gp, X86Xmm)                         // SSE
+    1064             :   ASMJIT_INST_2x(cvttss2si, Cvttss2si, X86Gp, X86Mem)                         // SSE
+    1065             :   ASMJIT_INST_2x(divpd, Divpd, X86Xmm, X86Xmm)                                // SSE2
+    1066             :   ASMJIT_INST_2x(divpd, Divpd, X86Xmm, X86Mem)                                // SSE2
+    1067             :   ASMJIT_INST_2x(divps, Divps, X86Xmm, X86Xmm)                                // SSE
+    1068             :   ASMJIT_INST_2x(divps, Divps, X86Xmm, X86Mem)                                // SSE
+    1069         270 :   ASMJIT_INST_2x(divsd, Divsd, X86Xmm, X86Xmm)                                // SSE2
+    1070             :   ASMJIT_INST_2x(divsd, Divsd, X86Xmm, X86Mem)                                // SSE2
+    1071             :   ASMJIT_INST_2x(divss, Divss, X86Xmm, X86Xmm)                                // SSE
+    1072             :   ASMJIT_INST_2x(divss, Divss, X86Xmm, X86Mem)                                // SSE
+    1073             :   ASMJIT_INST_3i(dppd, Dppd, X86Xmm, X86Xmm, Imm)                             // SSE4_1
+    1074             :   ASMJIT_INST_3i(dppd, Dppd, X86Xmm, X86Mem, Imm)                             // SSE4_1
+    1075             :   ASMJIT_INST_3i(dpps, Dpps, X86Xmm, X86Xmm, Imm)                             // SSE4_1
+    1076             :   ASMJIT_INST_3i(dpps, Dpps, X86Xmm, X86Mem, Imm)                             // SSE4_1
+    1077             :   ASMJIT_INST_3i(extractps, Extractps, X86Gp, X86Xmm, Imm)                    // SSE4_1
+    1078             :   ASMJIT_INST_3i(extractps, Extractps, X86Mem, X86Xmm, Imm)                   // SSE4_1
+    1079             :   ASMJIT_INST_2x(extrq, Extrq, X86Xmm, X86Xmm)                                // SSE4A
+    1080             :   ASMJIT_INST_3ii(extrq, Extrq, X86Xmm, Imm, Imm)                             // SSE4A
+    1081             :   ASMJIT_INST_2x(haddpd, Haddpd, X86Xmm, X86Xmm)                              // SSE3
+    1082             :   ASMJIT_INST_2x(haddpd, Haddpd, X86Xmm, X86Mem)                              // SSE3
+    1083             :   ASMJIT_INST_2x(haddps, Haddps, X86Xmm, X86Xmm)                              // SSE3
+    1084             :   ASMJIT_INST_2x(haddps, Haddps, X86Xmm, X86Mem)                              // SSE3
+    1085             :   ASMJIT_INST_2x(hsubpd, Hsubpd, X86Xmm, X86Xmm)                              // SSE3
+    1086             :   ASMJIT_INST_2x(hsubpd, Hsubpd, X86Xmm, X86Mem)                              // SSE3
+    1087             :   ASMJIT_INST_2x(hsubps, Hsubps, X86Xmm, X86Xmm)                              // SSE3
+    1088             :   ASMJIT_INST_2x(hsubps, Hsubps, X86Xmm, X86Mem)                              // SSE3
+    1089             :   ASMJIT_INST_3i(insertps, Insertps, X86Xmm, X86Xmm, Imm)                     // SSE4_1
+    1090             :   ASMJIT_INST_3i(insertps, Insertps, X86Xmm, X86Mem, Imm)                     // SSE4_1
+    1091             :   ASMJIT_INST_2x(insertq, Insertq, X86Xmm, X86Xmm)                            // SSE4A
+    1092             :   ASMJIT_INST_4ii(insertq, Insertq, X86Xmm, X86Xmm, Imm, Imm)                 // SSE4A
+    1093             :   ASMJIT_INST_2x(lddqu, Lddqu, X86Xmm, X86Mem)                                // SSE3
+    1094             :   ASMJIT_INST_3x(maskmovq, Maskmovq, X86Mm, X86Mm, DS_ZDI)                    // SSE  [EXPLICIT]
+    1095             :   ASMJIT_INST_3x(maskmovdqu, Maskmovdqu, X86Xmm, X86Xmm, DS_ZDI)              // SSE2 [EXPLICIT]
+    1096             :   ASMJIT_INST_2x(maxpd, Maxpd, X86Xmm, X86Xmm)                                // SSE2
+    1097             :   ASMJIT_INST_2x(maxpd, Maxpd, X86Xmm, X86Mem)                                // SSE2
+    1098             :   ASMJIT_INST_2x(maxps, Maxps, X86Xmm, X86Xmm)                                // SSE
+    1099             :   ASMJIT_INST_2x(maxps, Maxps, X86Xmm, X86Mem)                                // SSE
+    1100             :   ASMJIT_INST_2x(maxsd, Maxsd, X86Xmm, X86Xmm)                                // SSE2
+    1101             :   ASMJIT_INST_2x(maxsd, Maxsd, X86Xmm, X86Mem)                                // SSE2
+    1102             :   ASMJIT_INST_2x(maxss, Maxss, X86Xmm, X86Xmm)                                // SSE
+    1103             :   ASMJIT_INST_2x(maxss, Maxss, X86Xmm, X86Mem)                                // SSE
+    1104             :   ASMJIT_INST_2x(minpd, Minpd, X86Xmm, X86Xmm)                                // SSE2
+    1105             :   ASMJIT_INST_2x(minpd, Minpd, X86Xmm, X86Mem)                                // SSE2
+    1106             :   ASMJIT_INST_2x(minps, Minps, X86Xmm, X86Xmm)                                // SSE
+    1107             :   ASMJIT_INST_2x(minps, Minps, X86Xmm, X86Mem)                                // SSE
+    1108             :   ASMJIT_INST_2x(minsd, Minsd, X86Xmm, X86Xmm)                                // SSE2
+    1109             :   ASMJIT_INST_2x(minsd, Minsd, X86Xmm, X86Mem)                                // SSE2
+    1110             :   ASMJIT_INST_2x(minss, Minss, X86Xmm, X86Xmm)                                // SSE
+    1111             :   ASMJIT_INST_2x(minss, Minss, X86Xmm, X86Mem)                                // SSE
+    1112             :   ASMJIT_INST_2x(movapd, Movapd, X86Xmm, X86Xmm)                              // SSE2
+    1113             :   ASMJIT_INST_2x(movapd, Movapd, X86Xmm, X86Mem)                              // SSE2
+    1114             :   ASMJIT_INST_2x(movapd, Movapd, X86Mem, X86Xmm)                              // SSE2
+    1115             :   ASMJIT_INST_2x(movaps, Movaps, X86Xmm, X86Xmm)                              // SSE
+    1116             :   ASMJIT_INST_2x(movaps, Movaps, X86Xmm, X86Mem)                              // SSE
+    1117             :   ASMJIT_INST_2x(movaps, Movaps, X86Mem, X86Xmm)                              // SSE
+    1118             :   ASMJIT_INST_2x(movd, Movd, X86Mem, X86Mm)                                   // MMX
+    1119             :   ASMJIT_INST_2x(movd, Movd, X86Mem, X86Xmm)                                  // SSE
+    1120             :   ASMJIT_INST_2x(movd, Movd, X86Gp, X86Mm)                                    // MMX
+    1121             :   ASMJIT_INST_2x(movd, Movd, X86Gp, X86Xmm)                                   // SSE
+    1122             :   ASMJIT_INST_2x(movd, Movd, X86Mm, X86Mem)                                   // MMX
+    1123             :   ASMJIT_INST_2x(movd, Movd, X86Xmm, X86Mem)                                  // SSE
+    1124             :   ASMJIT_INST_2x(movd, Movd, X86Mm, X86Gp)                                    // MMX
+    1125             :   ASMJIT_INST_2x(movd, Movd, X86Xmm, X86Gp)                                   // SSE
+    1126             :   ASMJIT_INST_2x(movddup, Movddup, X86Xmm, X86Xmm)                            // SSE3
+    1127             :   ASMJIT_INST_2x(movddup, Movddup, X86Xmm, X86Mem)                            // SSE3
+    1128             :   ASMJIT_INST_2x(movdq2q, Movdq2q, X86Mm, X86Xmm)                             // SSE2
+    1129             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Xmm, X86Xmm)                              // SSE2
+    1130             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Xmm, X86Mem)                              // SSE2
+    1131             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Mem, X86Xmm)                              // SSE2
+    1132             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Xmm, X86Xmm)                              // SSE2
+    1133             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Xmm, X86Mem)                              // SSE2
+    1134             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Mem, X86Xmm)                              // SSE2
+    1135             :   ASMJIT_INST_2x(movhlps, Movhlps, X86Xmm, X86Xmm)                            // SSE
+    1136             :   ASMJIT_INST_2x(movhpd, Movhpd, X86Xmm, X86Mem)                              // SSE2
+    1137             :   ASMJIT_INST_2x(movhpd, Movhpd, X86Mem, X86Xmm)                              // SSE2
+    1138             :   ASMJIT_INST_2x(movhps, Movhps, X86Xmm, X86Mem)                              // SSE
+    1139             :   ASMJIT_INST_2x(movhps, Movhps, X86Mem, X86Xmm)                              // SSE
+    1140             :   ASMJIT_INST_2x(movlhps, Movlhps, X86Xmm, X86Xmm)                            // SSE
+    1141             :   ASMJIT_INST_2x(movlpd, Movlpd, X86Xmm, X86Mem)                              // SSE2
+    1142             :   ASMJIT_INST_2x(movlpd, Movlpd, X86Mem, X86Xmm)                              // SSE2
+    1143             :   ASMJIT_INST_2x(movlps, Movlps, X86Xmm, X86Mem)                              // SSE
+    1144             :   ASMJIT_INST_2x(movlps, Movlps, X86Mem, X86Xmm)                              // SSE
+    1145             :   ASMJIT_INST_2x(movmskps, Movmskps, X86Gp, X86Xmm)                           // SSE2
+    1146             :   ASMJIT_INST_2x(movmskpd, Movmskpd, X86Gp, X86Xmm)                           // SSE2
+    1147             :   ASMJIT_INST_2x(movntdq, Movntdq, X86Mem, X86Xmm)                            // SSE2
+    1148             :   ASMJIT_INST_2x(movntdqa, Movntdqa, X86Xmm, X86Mem)                          // SSE4_1
+    1149             :   ASMJIT_INST_2x(movntpd, Movntpd, X86Mem, X86Xmm)                            // SSE2
+    1150             :   ASMJIT_INST_2x(movntps, Movntps, X86Mem, X86Xmm)                            // SSE
+    1151             :   ASMJIT_INST_2x(movntsd, Movntsd, X86Mem, X86Xmm)                            // SSE4A
+    1152             :   ASMJIT_INST_2x(movntss, Movntss, X86Mem, X86Xmm)                            // SSE4A
+    1153             :   ASMJIT_INST_2x(movntq, Movntq, X86Mem, X86Mm)                               // SSE
+    1154             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Mm)                                    // MMX
+    1155             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Xmm)                                  // SSE
+    1156             :   ASMJIT_INST_2x(movq, Movq, X86Mem, X86Mm)                                   // MMX
+    1157             :   ASMJIT_INST_2x(movq, Movq, X86Mem, X86Xmm)                                  // SSE
+    1158             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Mem)                                   // MMX
+    1159             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Mem)                                  // SSE
+    1160             :   ASMJIT_INST_2x(movq, Movq, X86Gp, X86Mm)                                    // MMX
+    1161             :   ASMJIT_INST_2x(movq, Movq, X86Gp, X86Xmm)                                   // SSE+X64.
+    1162             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Gp)                                    // MMX
+    1163             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Gp)                                   // SSE+X64.
+    1164             :   ASMJIT_INST_2x(movq2dq, Movq2dq, X86Xmm, X86Mm)                             // SSE2
+    1165        8664 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Xmm)                                // SSE2
+    1166        5834 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Mem)                                // SSE2
+    1167         266 :   ASMJIT_INST_2x(movsd, Movsd, X86Mem, X86Xmm)                                // SSE2
+    1168             :   ASMJIT_INST_2x(movshdup, Movshdup, X86Xmm, X86Xmm)                          // SSE3
+    1169             :   ASMJIT_INST_2x(movshdup, Movshdup, X86Xmm, X86Mem)                          // SSE3
+    1170             :   ASMJIT_INST_2x(movsldup, Movsldup, X86Xmm, X86Xmm)                          // SSE3
+    1171             :   ASMJIT_INST_2x(movsldup, Movsldup, X86Xmm, X86Mem)                          // SSE3
+    1172             :   ASMJIT_INST_2x(movss, Movss, X86Xmm, X86Xmm)                                // SSE
+    1173             :   ASMJIT_INST_2x(movss, Movss, X86Xmm, X86Mem)                                // SSE
+    1174             :   ASMJIT_INST_2x(movss, Movss, X86Mem, X86Xmm)                                // SSE
+    1175             :   ASMJIT_INST_2x(movupd, Movupd, X86Xmm, X86Xmm)                              // SSE2
+    1176             :   ASMJIT_INST_2x(movupd, Movupd, X86Xmm, X86Mem)                              // SSE2
+    1177             :   ASMJIT_INST_2x(movupd, Movupd, X86Mem, X86Xmm)                              // SSE2
+    1178             :   ASMJIT_INST_2x(movups, Movups, X86Xmm, X86Xmm)                              // SSE
+    1179             :   ASMJIT_INST_2x(movups, Movups, X86Xmm, X86Mem)                              // SSE
+    1180             :   ASMJIT_INST_2x(movups, Movups, X86Mem, X86Xmm)                              // SSE
+    1181             :   ASMJIT_INST_3i(mpsadbw, Mpsadbw, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1182             :   ASMJIT_INST_3i(mpsadbw, Mpsadbw, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1183             :   ASMJIT_INST_2x(mulpd, Mulpd, X86Xmm, X86Xmm)                                // SSE2
+    1184             :   ASMJIT_INST_2x(mulpd, Mulpd, X86Xmm, X86Mem)                                // SSE2
+    1185             :   ASMJIT_INST_2x(mulps, Mulps, X86Xmm, X86Xmm)                                // SSE
+    1186             :   ASMJIT_INST_2x(mulps, Mulps, X86Xmm, X86Mem)                                // SSE
+    1187        5200 :   ASMJIT_INST_2x(mulsd, Mulsd, X86Xmm, X86Xmm)                                // SSE2
+    1188             :   ASMJIT_INST_2x(mulsd, Mulsd, X86Xmm, X86Mem)                                // SSE2
+    1189             :   ASMJIT_INST_2x(mulss, Mulss, X86Xmm, X86Xmm)                                // SSE
+    1190             :   ASMJIT_INST_2x(mulss, Mulss, X86Xmm, X86Mem)                                // SSE
+    1191             :   ASMJIT_INST_2x(orpd, Orpd, X86Xmm, X86Xmm)                                  // SSE2
+    1192             :   ASMJIT_INST_2x(orpd, Orpd, X86Xmm, X86Mem)                                  // SSE2
+    1193             :   ASMJIT_INST_2x(orps, Orps, X86Xmm, X86Xmm)                                  // SSE
+    1194             :   ASMJIT_INST_2x(orps, Orps, X86Xmm, X86Mem)                                  // SSE
+    1195             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Mm, X86Mm)                            // MMX
+    1196             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Mm, X86Mem)                           // MMX
+    1197             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Xmm, X86Xmm)                          // SSE2
+    1198             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Xmm, X86Mem)                          // SSE2
+    1199             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Mm, X86Mm)                            // MMX
+    1200             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Mm, X86Mem)                           // MMX
+    1201             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Xmm, X86Xmm)                          // SSE2
+    1202             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Xmm, X86Mem)                          // SSE2
+    1203             :   ASMJIT_INST_2x(packusdw, Packusdw, X86Xmm, X86Xmm)                          // SSE4_1
+    1204             :   ASMJIT_INST_2x(packusdw, Packusdw, X86Xmm, X86Mem)                          // SSE4_1
+    1205             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Mm, X86Mm)                            // MMX
+    1206             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Mm, X86Mem)                           // MMX
+    1207             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Xmm, X86Xmm)                          // SSE2
+    1208             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Xmm, X86Mem)                          // SSE2
+    1209             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Mm, X86Mm)                                  // SSSE3
+    1210             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Mm, X86Mem)                                 // SSSE3
+    1211             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Xmm, X86Xmm)                                // SSSE3
+    1212             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Xmm, X86Mem)                                // SSSE3
+    1213             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Mm, X86Mm)                                  // SSSE3
+    1214             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Mm, X86Mem)                                 // SSSE3
+    1215             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Xmm, X86Xmm)                                // SSSE3
+    1216             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Xmm, X86Mem)                                // SSSE3
+    1217             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Mm, X86Mm)                                  // SSSE3
+    1218             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Mm, X86Mem)                                 // SSSE3
+    1219             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Xmm, X86Xmm)                                // SSSE3
+    1220             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Xmm, X86Mem)                                // SSSE3
+    1221             :   ASMJIT_INST_2x(paddb, Paddb, X86Mm, X86Mm)                                  // MMX
+    1222             :   ASMJIT_INST_2x(paddb, Paddb, X86Mm, X86Mem)                                 // MMX
+    1223             :   ASMJIT_INST_2x(paddb, Paddb, X86Xmm, X86Xmm)                                // SSE2
+    1224             :   ASMJIT_INST_2x(paddb, Paddb, X86Xmm, X86Mem)                                // SSE2
+    1225             :   ASMJIT_INST_2x(paddd, Paddd, X86Mm, X86Mm)                                  // MMX
+    1226             :   ASMJIT_INST_2x(paddd, Paddd, X86Mm, X86Mem)                                 // MMX
+    1227             :   ASMJIT_INST_2x(paddd, Paddd, X86Xmm, X86Xmm)                                // SSE2
+    1228             :   ASMJIT_INST_2x(paddd, Paddd, X86Xmm, X86Mem)                                // SSE2
+    1229             :   ASMJIT_INST_2x(paddq, Paddq, X86Mm, X86Mm)                                  // SSE2
+    1230             :   ASMJIT_INST_2x(paddq, Paddq, X86Mm, X86Mem)                                 // SSE2
+    1231             :   ASMJIT_INST_2x(paddq, Paddq, X86Xmm, X86Xmm)                                // SSE2
+    1232             :   ASMJIT_INST_2x(paddq, Paddq, X86Xmm, X86Mem)                                // SSE2
+    1233             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Mm, X86Mm)                                // MMX
+    1234             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Mm, X86Mem)                               // MMX
+    1235             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Xmm, X86Xmm)                              // SSE2
+    1236             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Xmm, X86Mem)                              // SSE2
+    1237             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Mm, X86Mm)                                // MMX
+    1238             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Mm, X86Mem)                               // MMX
+    1239             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Xmm, X86Xmm)                              // SSE2
+    1240             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Xmm, X86Mem)                              // SSE2
+    1241             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Mm, X86Mm)                              // MMX
+    1242             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Mm, X86Mem)                             // MMX
+    1243             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Xmm, X86Xmm)                            // SSE2
+    1244             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Xmm, X86Mem)                            // SSE2
+    1245             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Mm, X86Mm)                              // MMX
+    1246             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Mm, X86Mem)                             // MMX
+    1247             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Xmm, X86Xmm)                            // SSE2
+    1248             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Xmm, X86Mem)                            // SSE2
+    1249             :   ASMJIT_INST_2x(paddw, Paddw, X86Mm, X86Mm)                                  // MMX
+    1250             :   ASMJIT_INST_2x(paddw, Paddw, X86Mm, X86Mem)                                 // MMX
+    1251             :   ASMJIT_INST_2x(paddw, Paddw, X86Xmm, X86Xmm)                                // SSE2
+    1252             :   ASMJIT_INST_2x(paddw, Paddw, X86Xmm, X86Mem)                                // SSE2
+    1253             :   ASMJIT_INST_3i(palignr, Palignr, X86Mm, X86Mm, Imm)                         // SSSE3
+    1254             :   ASMJIT_INST_3i(palignr, Palignr, X86Mm, X86Mem, Imm)                        // SSSE3
+    1255             :   ASMJIT_INST_3i(palignr, Palignr, X86Xmm, X86Xmm, Imm)                       // SSSE3
+    1256             :   ASMJIT_INST_3i(palignr, Palignr, X86Xmm, X86Mem, Imm)                       // SSSE3
+    1257             :   ASMJIT_INST_2x(pand, Pand, X86Mm, X86Mm)                                    // MMX
+    1258             :   ASMJIT_INST_2x(pand, Pand, X86Mm, X86Mem)                                   // MMX
+    1259             :   ASMJIT_INST_2x(pand, Pand, X86Xmm, X86Xmm)                                  // SSE2
+    1260             :   ASMJIT_INST_2x(pand, Pand, X86Xmm, X86Mem)                                  // SSE2
+    1261             :   ASMJIT_INST_2x(pandn, Pandn, X86Mm, X86Mm)                                  // MMX
+    1262             :   ASMJIT_INST_2x(pandn, Pandn, X86Mm, X86Mem)                                 // MMX
+    1263             :   ASMJIT_INST_2x(pandn, Pandn, X86Xmm, X86Xmm)                                // SSE2
+    1264             :   ASMJIT_INST_2x(pandn, Pandn, X86Xmm, X86Mem)                                // SSE2
+    1265             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Mm, X86Mm)                                  // SSE
+    1266             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Mm, X86Mem)                                 // SSE
+    1267             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Xmm, X86Xmm)                                // SSE2
+    1268             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Xmm, X86Mem)                                // SSE2
+    1269             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Mm, X86Mm)                                  // SSE
+    1270             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Mm, X86Mem)                                 // SSE
+    1271             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Xmm, X86Xmm)                                // SSE2
+    1272             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Xmm, X86Mem)                                // SSE2
+    1273             :   ASMJIT_INST_3x(pblendvb, Pblendvb, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1274             :   ASMJIT_INST_3x(pblendvb, Pblendvb, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1275             :   ASMJIT_INST_3i(pblendw, Pblendw, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1276             :   ASMJIT_INST_3i(pblendw, Pblendw, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1277             :   ASMJIT_INST_3i(pclmulqdq, Pclmulqdq, X86Xmm, X86Xmm, Imm)                   // PCLMULQDQ.
+    1278             :   ASMJIT_INST_3i(pclmulqdq, Pclmulqdq, X86Xmm, X86Mem, Imm)                   // PCLMULQDQ.
+    1279             :   ASMJIT_INST_6x(pcmpestri, Pcmpestri, X86Xmm, X86Xmm, Imm, ECX, EAX, EDX)    // SSE4_2 [EXPLICIT]
+    1280             :   ASMJIT_INST_6x(pcmpestri, Pcmpestri, X86Xmm, X86Mem, Imm, ECX, EAX, EDX)    // SSE4_2 [EXPLICIT]
+    1281             :   ASMJIT_INST_6x(pcmpestrm, Pcmpestrm, X86Xmm, X86Xmm, Imm, XMM0, EAX, EDX)   // SSE4_2 [EXPLICIT]
+    1282             :   ASMJIT_INST_6x(pcmpestrm, Pcmpestrm, X86Xmm, X86Mem, Imm, XMM0, EAX, EDX)   // SSE4_2 [EXPLICIT]
+    1283             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Mm, X86Mm)                              // MMX
+    1284             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Mm, X86Mem)                             // MMX
+    1285             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Xmm, X86Xmm)                            // SSE2
+    1286             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Xmm, X86Mem)                            // SSE2
+    1287             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Mm, X86Mm)                              // MMX
+    1288             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Mm, X86Mem)                             // MMX
+    1289             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Xmm, X86Xmm)                            // SSE2
+    1290             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Xmm, X86Mem)                            // SSE2
+    1291             :   ASMJIT_INST_2x(pcmpeqq, Pcmpeqq, X86Xmm, X86Xmm)                            // SSE4_1
+    1292             :   ASMJIT_INST_2x(pcmpeqq, Pcmpeqq, X86Xmm, X86Mem)                            // SSE4_1
+    1293             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Mm, X86Mm)                              // MMX
+    1294             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Mm, X86Mem)                             // MMX
+    1295             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Xmm, X86Xmm)                            // SSE2
+    1296             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Xmm, X86Mem)                            // SSE2
+    1297             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Mm, X86Mm)                              // MMX
+    1298             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Mm, X86Mem)                             // MMX
+    1299             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Xmm, X86Xmm)                            // SSE2
+    1300             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Xmm, X86Mem)                            // SSE2
+    1301             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Mm, X86Mm)                              // MMX
+    1302             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Mm, X86Mem)                             // MMX
+    1303             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Xmm, X86Xmm)                            // SSE2
+    1304             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Xmm, X86Mem)                            // SSE2
+    1305             :   ASMJIT_INST_2x(pcmpgtq, Pcmpgtq, X86Xmm, X86Xmm)                            // SSE4_2.
+    1306             :   ASMJIT_INST_2x(pcmpgtq, Pcmpgtq, X86Xmm, X86Mem)                            // SSE4_2.
+    1307             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Mm, X86Mm)                              // MMX
+    1308             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Mm, X86Mem)                             // MMX
+    1309             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Xmm, X86Xmm)                            // SSE2
+    1310             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Xmm, X86Mem)                            // SSE2
+    1311             :   ASMJIT_INST_4x(pcmpistri, Pcmpistri, X86Xmm, X86Xmm, Imm, ECX)              // SSE4_2 [EXPLICIT]
+    1312             :   ASMJIT_INST_4x(pcmpistri, Pcmpistri, X86Xmm, X86Mem, Imm, ECX)              // SSE4_2 [EXPLICIT]
+    1313             :   ASMJIT_INST_4x(pcmpistrm, Pcmpistrm, X86Xmm, X86Xmm, Imm, XMM0)             // SSE4_2 [EXPLICIT]
+    1314             :   ASMJIT_INST_4x(pcmpistrm, Pcmpistrm, X86Xmm, X86Mem, Imm, XMM0)             // SSE4_2 [EXPLICIT]
+    1315             :   ASMJIT_INST_3i(pextrb, Pextrb, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1316             :   ASMJIT_INST_3i(pextrb, Pextrb, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1317             :   ASMJIT_INST_3i(pextrd, Pextrd, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1318             :   ASMJIT_INST_3i(pextrd, Pextrd, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1319             :   ASMJIT_INST_3i(pextrq, Pextrq, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1320             :   ASMJIT_INST_3i(pextrq, Pextrq, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1321             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Gp, X86Mm, Imm)                           // SSE
+    1322             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Gp, X86Xmm, Imm)                          // SSE2
+    1323             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1324             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Mm, X86Mm)                                // SSSE3
+    1325             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Mm, X86Mem)                               // SSSE3
+    1326             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Xmm, X86Xmm)                              // SSSE3
+    1327             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Xmm, X86Mem)                              // SSSE3
+    1328             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Mm, X86Mm)                              // SSSE3
+    1329             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Mm, X86Mem)                             // SSSE3
+    1330             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Xmm, X86Xmm)                            // SSSE3
+    1331             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Xmm, X86Mem)                            // SSSE3
+    1332             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Mm, X86Mm)                                // SSSE3
+    1333             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Mm, X86Mem)                               // SSSE3
+    1334             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Xmm, X86Xmm)                              // SSSE3
+    1335             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Xmm, X86Mem)                              // SSSE3
+    1336             :   ASMJIT_INST_2x(phminposuw, Phminposuw, X86Xmm, X86Xmm)                      // SSE4_1
+    1337             :   ASMJIT_INST_2x(phminposuw, Phminposuw, X86Xmm, X86Mem)                      // SSE4_1
+    1338             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Mm, X86Mm)                                // SSSE3
+    1339             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Mm, X86Mem)                               // SSSE3
+    1340             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Xmm, X86Xmm)                              // SSSE3
+    1341             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Xmm, X86Mem)                              // SSSE3
+    1342             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Mm, X86Mm)                              // SSSE3
+    1343             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Mm, X86Mem)                             // SSSE3
+    1344             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Xmm, X86Xmm)                            // SSSE3
+    1345             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Xmm, X86Mem)                            // SSSE3
+    1346             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Mm, X86Mm)                                // SSSE3
+    1347             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Mm, X86Mem)                               // SSSE3
+    1348             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Xmm, X86Xmm)                              // SSSE3
+    1349             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Xmm, X86Mem)                              // SSSE3
+    1350             :   ASMJIT_INST_3i(pinsrb, Pinsrb, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1351             :   ASMJIT_INST_3i(pinsrb, Pinsrb, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1352             :   ASMJIT_INST_3i(pinsrd, Pinsrd, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1353             :   ASMJIT_INST_3i(pinsrd, Pinsrd, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1354             :   ASMJIT_INST_3i(pinsrq, Pinsrq, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1355             :   ASMJIT_INST_3i(pinsrq, Pinsrq, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1356             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Mm, X86Gp, Imm)                           // SSE
+    1357             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Mm, X86Mem, Imm)                          // SSE
+    1358             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Xmm, X86Gp, Imm)                          // SSE2
+    1359             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Xmm, X86Mem, Imm)                         // SSE2
+    1360             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Mm, X86Mm)                          // SSSE3
+    1361             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Mm, X86Mem)                         // SSSE3
+    1362             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Xmm, X86Xmm)                        // SSSE3
+    1363             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Xmm, X86Mem)                        // SSSE3
+    1364             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Mm, X86Mm)                              // MMX
+    1365             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Mm, X86Mem)                             // MMX
+    1366             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Xmm, X86Xmm)                            // SSE2
+    1367             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Xmm, X86Mem)                            // SSE2
+    1368             :   ASMJIT_INST_2x(pmaxsb, Pmaxsb, X86Xmm, X86Xmm)                              // SSE4_1
+    1369             :   ASMJIT_INST_2x(pmaxsb, Pmaxsb, X86Xmm, X86Mem)                              // SSE4_1
+    1370             :   ASMJIT_INST_2x(pmaxsd, Pmaxsd, X86Xmm, X86Xmm)                              // SSE4_1
+    1371             :   ASMJIT_INST_2x(pmaxsd, Pmaxsd, X86Xmm, X86Mem)                              // SSE4_1
+    1372             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Mm, X86Mm)                                // SSE
+    1373             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Mm, X86Mem)                               // SSE
+    1374             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Xmm, X86Xmm)                              // SSE2
+    1375             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Xmm, X86Mem)                              // SSE2
+    1376             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Mm, X86Mm)                                // SSE
+    1377             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Mm, X86Mem)                               // SSE
+    1378             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Xmm, X86Xmm)                              // SSE2
+    1379             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Xmm, X86Mem)                              // SSE2
+    1380             :   ASMJIT_INST_2x(pmaxud, Pmaxud, X86Xmm, X86Xmm)                              // SSE4_1
+    1381             :   ASMJIT_INST_2x(pmaxud, Pmaxud, X86Xmm, X86Mem)                              // SSE4_1
+    1382             :   ASMJIT_INST_2x(pmaxuw, Pmaxuw, X86Xmm, X86Xmm)                              // SSE4_1
+    1383             :   ASMJIT_INST_2x(pmaxuw, Pmaxuw, X86Xmm, X86Mem)                              // SSE4_1
+    1384             :   ASMJIT_INST_2x(pminsb, Pminsb, X86Xmm, X86Xmm)                              // SSE4_1
+    1385             :   ASMJIT_INST_2x(pminsb, Pminsb, X86Xmm, X86Mem)                              // SSE4_1
+    1386             :   ASMJIT_INST_2x(pminsd, Pminsd, X86Xmm, X86Xmm)                              // SSE4_1
+    1387             :   ASMJIT_INST_2x(pminsd, Pminsd, X86Xmm, X86Mem)                              // SSE4_1
+    1388             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Mm, X86Mm)                                // SSE
+    1389             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Mm, X86Mem)                               // SSE
+    1390             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Xmm, X86Xmm)                              // SSE2
+    1391             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Xmm, X86Mem)                              // SSE2
+    1392             :   ASMJIT_INST_2x(pminub, Pminub, X86Mm, X86Mm)                                // SSE
+    1393             :   ASMJIT_INST_2x(pminub, Pminub, X86Mm, X86Mem)                               // SSE
+    1394             :   ASMJIT_INST_2x(pminub, Pminub, X86Xmm, X86Xmm)                              // SSE2
+    1395             :   ASMJIT_INST_2x(pminub, Pminub, X86Xmm, X86Mem)                              // SSE2
+    1396             :   ASMJIT_INST_2x(pminud, Pminud, X86Xmm, X86Xmm)                              // SSE4_1
+    1397             :   ASMJIT_INST_2x(pminud, Pminud, X86Xmm, X86Mem)                              // SSE4_1
+    1398             :   ASMJIT_INST_2x(pminuw, Pminuw, X86Xmm, X86Xmm)                              // SSE4_1
+    1399             :   ASMJIT_INST_2x(pminuw, Pminuw, X86Xmm, X86Mem)                              // SSE4_1
+    1400             :   ASMJIT_INST_2x(pmovmskb, Pmovmskb, X86Gp, X86Mm)                            // SSE
+    1401             :   ASMJIT_INST_2x(pmovmskb, Pmovmskb, X86Gp, X86Xmm)                           // SSE2
+    1402             :   ASMJIT_INST_2x(pmovsxbd, Pmovsxbd, X86Xmm, X86Xmm)                          // SSE4_1
+    1403             :   ASMJIT_INST_2x(pmovsxbd, Pmovsxbd, X86Xmm, X86Mem)                          // SSE4_1
+    1404             :   ASMJIT_INST_2x(pmovsxbq, Pmovsxbq, X86Xmm, X86Xmm)                          // SSE4_1
+    1405             :   ASMJIT_INST_2x(pmovsxbq, Pmovsxbq, X86Xmm, X86Mem)                          // SSE4_1
+    1406             :   ASMJIT_INST_2x(pmovsxbw, Pmovsxbw, X86Xmm, X86Xmm)                          // SSE4_1
+    1407             :   ASMJIT_INST_2x(pmovsxbw, Pmovsxbw, X86Xmm, X86Mem)                          // SSE4_1
+    1408             :   ASMJIT_INST_2x(pmovsxdq, Pmovsxdq, X86Xmm, X86Xmm)                          // SSE4_1
+    1409             :   ASMJIT_INST_2x(pmovsxdq, Pmovsxdq, X86Xmm, X86Mem)                          // SSE4_1
+    1410             :   ASMJIT_INST_2x(pmovsxwd, Pmovsxwd, X86Xmm, X86Xmm)                          // SSE4_1
+    1411             :   ASMJIT_INST_2x(pmovsxwd, Pmovsxwd, X86Xmm, X86Mem)                          // SSE4_1
+    1412             :   ASMJIT_INST_2x(pmovsxwq, Pmovsxwq, X86Xmm, X86Xmm)                          // SSE4_1
+    1413             :   ASMJIT_INST_2x(pmovsxwq, Pmovsxwq, X86Xmm, X86Mem)                          // SSE4_1
+    1414             :   ASMJIT_INST_2x(pmovzxbd, Pmovzxbd, X86Xmm, X86Xmm)                          // SSE4_1
+    1415             :   ASMJIT_INST_2x(pmovzxbd, Pmovzxbd, X86Xmm, X86Mem)                          // SSE4_1
+    1416             :   ASMJIT_INST_2x(pmovzxbq, Pmovzxbq, X86Xmm, X86Xmm)                          // SSE4_1
+    1417             :   ASMJIT_INST_2x(pmovzxbq, Pmovzxbq, X86Xmm, X86Mem)                          // SSE4_1
+    1418             :   ASMJIT_INST_2x(pmovzxbw, Pmovzxbw, X86Xmm, X86Xmm)                          // SSE4_1
+    1419             :   ASMJIT_INST_2x(pmovzxbw, Pmovzxbw, X86Xmm, X86Mem)                          // SSE4_1
+    1420             :   ASMJIT_INST_2x(pmovzxdq, Pmovzxdq, X86Xmm, X86Xmm)                          // SSE4_1
+    1421             :   ASMJIT_INST_2x(pmovzxdq, Pmovzxdq, X86Xmm, X86Mem)                          // SSE4_1
+    1422             :   ASMJIT_INST_2x(pmovzxwd, Pmovzxwd, X86Xmm, X86Xmm)                          // SSE4_1
+    1423             :   ASMJIT_INST_2x(pmovzxwd, Pmovzxwd, X86Xmm, X86Mem)                          // SSE4_1
+    1424             :   ASMJIT_INST_2x(pmovzxwq, Pmovzxwq, X86Xmm, X86Xmm)                          // SSE4_1
+    1425             :   ASMJIT_INST_2x(pmovzxwq, Pmovzxwq, X86Xmm, X86Mem)                          // SSE4_1
+    1426             :   ASMJIT_INST_2x(pmuldq, Pmuldq, X86Xmm, X86Xmm)                              // SSE4_1
+    1427             :   ASMJIT_INST_2x(pmuldq, Pmuldq, X86Xmm, X86Mem)                              // SSE4_1
+    1428             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Mm, X86Mm)                            // SSSE3
+    1429             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Mm, X86Mem)                           // SSSE3
+    1430             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Xmm, X86Xmm)                          // SSSE3
+    1431             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Xmm, X86Mem)                          // SSSE3
+    1432             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Mm, X86Mm)                                // MMX
+    1433             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Mm, X86Mem)                               // MMX
+    1434             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Xmm, X86Xmm)                              // SSE2
+    1435             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Xmm, X86Mem)                              // SSE2
+    1436             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Mm, X86Mm)                              // SSE
+    1437             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Mm, X86Mem)                             // SSE
+    1438             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Xmm, X86Xmm)                            // SSE2
+    1439             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Xmm, X86Mem)                            // SSE2
+    1440             :   ASMJIT_INST_2x(pmulld, Pmulld, X86Xmm, X86Xmm)                              // SSE4_1
+    1441             :   ASMJIT_INST_2x(pmulld, Pmulld, X86Xmm, X86Mem)                              // SSE4_1
+    1442             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Mm, X86Mm)                                // MMX
+    1443             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Mm, X86Mem)                               // MMX
+    1444             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Xmm, X86Xmm)                              // SSE2
+    1445             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Xmm, X86Mem)                              // SSE2
+    1446             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Mm, X86Mm)                              // SSE2
+    1447             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Mm, X86Mem)                             // SSE2
+    1448             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Xmm, X86Xmm)                            // SSE2
+    1449             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Xmm, X86Mem)                            // SSE2
+    1450             :   ASMJIT_INST_2x(por, Por, X86Mm, X86Mm)                                      // MMX
+    1451             :   ASMJIT_INST_2x(por, Por, X86Mm, X86Mem)                                     // MMX
+    1452             :   ASMJIT_INST_2x(por, Por, X86Xmm, X86Xmm)                                    // SSE2
+    1453             :   ASMJIT_INST_2x(por, Por, X86Xmm, X86Mem)                                    // SSE2
+    1454             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Mm, X86Mm)                                // SSE
+    1455             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Mm, X86Mem)                               // SSE
+    1456             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Xmm, X86Xmm)                              // SSE
+    1457             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Xmm, X86Mem)                              // SSE
+    1458             :   ASMJIT_INST_2x(pslld, Pslld, X86Mm, X86Mm)                                  // MMX
+    1459             :   ASMJIT_INST_2x(pslld, Pslld, X86Mm, X86Mem)                                 // MMX
+    1460             :   ASMJIT_INST_2i(pslld, Pslld, X86Mm, Imm)                                    // MMX
+    1461             :   ASMJIT_INST_2x(pslld, Pslld, X86Xmm, X86Xmm)                                // SSE2
+    1462             :   ASMJIT_INST_2x(pslld, Pslld, X86Xmm, X86Mem)                                // SSE2
+    1463             :   ASMJIT_INST_2i(pslld, Pslld, X86Xmm, Imm)                                   // SSE2
+    1464             :   ASMJIT_INST_2i(pslldq, Pslldq, X86Xmm, Imm)                                 // SSE2
+    1465             :   ASMJIT_INST_2x(psllq, Psllq, X86Mm, X86Mm)                                  // MMX
+    1466             :   ASMJIT_INST_2x(psllq, Psllq, X86Mm, X86Mem)                                 // MMX
+    1467             :   ASMJIT_INST_2i(psllq, Psllq, X86Mm, Imm)                                    // MMX
+    1468             :   ASMJIT_INST_2x(psllq, Psllq, X86Xmm, X86Xmm)                                // SSE2
+    1469             :   ASMJIT_INST_2x(psllq, Psllq, X86Xmm, X86Mem)                                // SSE2
+    1470             :   ASMJIT_INST_2i(psllq, Psllq, X86Xmm, Imm)                                   // SSE2
+    1471             :   ASMJIT_INST_2x(psllw, Psllw, X86Mm, X86Mm)                                  // MMX
+    1472             :   ASMJIT_INST_2x(psllw, Psllw, X86Mm, X86Mem)                                 // MMX
+    1473             :   ASMJIT_INST_2i(psllw, Psllw, X86Mm, Imm)                                    // MMX
+    1474             :   ASMJIT_INST_2x(psllw, Psllw, X86Xmm, X86Xmm)                                // SSE2
+    1475             :   ASMJIT_INST_2x(psllw, Psllw, X86Xmm, X86Mem)                                // SSE2
+    1476             :   ASMJIT_INST_2i(psllw, Psllw, X86Xmm, Imm)                                   // SSE2
+    1477             :   ASMJIT_INST_2x(psrad, Psrad, X86Mm, X86Mm)                                  // MMX
+    1478             :   ASMJIT_INST_2x(psrad, Psrad, X86Mm, X86Mem)                                 // MMX
+    1479             :   ASMJIT_INST_2i(psrad, Psrad, X86Mm, Imm)                                    // MMX
+    1480             :   ASMJIT_INST_2x(psrad, Psrad, X86Xmm, X86Xmm)                                // SSE2
+    1481             :   ASMJIT_INST_2x(psrad, Psrad, X86Xmm, X86Mem)                                // SSE2
+    1482             :   ASMJIT_INST_2i(psrad, Psrad, X86Xmm, Imm)                                   // SSE2
+    1483             :   ASMJIT_INST_2x(psraw, Psraw, X86Mm, X86Mm)                                  // MMX
+    1484             :   ASMJIT_INST_2x(psraw, Psraw, X86Mm, X86Mem)                                 // MMX
+    1485             :   ASMJIT_INST_2i(psraw, Psraw, X86Mm, Imm)                                    // MMX
+    1486             :   ASMJIT_INST_2x(psraw, Psraw, X86Xmm, X86Xmm)                                // SSE2
+    1487             :   ASMJIT_INST_2x(psraw, Psraw, X86Xmm, X86Mem)                                // SSE2
+    1488             :   ASMJIT_INST_2i(psraw, Psraw, X86Xmm, Imm)                                   // SSE2
+    1489             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Mm, X86Mm)                                // SSSE3
+    1490             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Mm, X86Mem)                               // SSSE3
+    1491             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Xmm, X86Xmm)                              // SSSE3
+    1492             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Xmm, X86Mem)                              // SSSE3
+    1493             :   ASMJIT_INST_3i(pshufd, Pshufd, X86Xmm, X86Xmm, Imm)                         // SSE2
+    1494             :   ASMJIT_INST_3i(pshufd, Pshufd, X86Xmm, X86Mem, Imm)                         // SSE2
+    1495             :   ASMJIT_INST_3i(pshufhw, Pshufhw, X86Xmm, X86Xmm, Imm)                       // SSE2
+    1496             :   ASMJIT_INST_3i(pshufhw, Pshufhw, X86Xmm, X86Mem, Imm)                       // SSE2
+    1497             :   ASMJIT_INST_3i(pshuflw, Pshuflw, X86Xmm, X86Xmm, Imm)                       // SSE2
+    1498             :   ASMJIT_INST_3i(pshuflw, Pshuflw, X86Xmm, X86Mem, Imm)                       // SSE2
+    1499             :   ASMJIT_INST_3i(pshufw, Pshufw, X86Mm, X86Mm, Imm)                           // SSE
+    1500             :   ASMJIT_INST_3i(pshufw, Pshufw, X86Mm, X86Mem, Imm)                          // SSE
+    1501             :   ASMJIT_INST_2x(psignb, Psignb, X86Mm, X86Mm)                                // SSSE3
+    1502             :   ASMJIT_INST_2x(psignb, Psignb, X86Mm, X86Mem)                               // SSSE3
+    1503             :   ASMJIT_INST_2x(psignb, Psignb, X86Xmm, X86Xmm)                              // SSSE3
+    1504             :   ASMJIT_INST_2x(psignb, Psignb, X86Xmm, X86Mem)                              // SSSE3
+    1505             :   ASMJIT_INST_2x(psignd, Psignd, X86Mm, X86Mm)                                // SSSE3
+    1506             :   ASMJIT_INST_2x(psignd, Psignd, X86Mm, X86Mem)                               // SSSE3
+    1507             :   ASMJIT_INST_2x(psignd, Psignd, X86Xmm, X86Xmm)                              // SSSE3
+    1508             :   ASMJIT_INST_2x(psignd, Psignd, X86Xmm, X86Mem)                              // SSSE3
+    1509             :   ASMJIT_INST_2x(psignw, Psignw, X86Mm, X86Mm)                                // SSSE3
+    1510             :   ASMJIT_INST_2x(psignw, Psignw, X86Mm, X86Mem)                               // SSSE3
+    1511             :   ASMJIT_INST_2x(psignw, Psignw, X86Xmm, X86Xmm)                              // SSSE3
+    1512             :   ASMJIT_INST_2x(psignw, Psignw, X86Xmm, X86Mem)                              // SSSE3
+    1513             :   ASMJIT_INST_2x(psrld, Psrld, X86Mm, X86Mm)                                  // MMX
+    1514             :   ASMJIT_INST_2x(psrld, Psrld, X86Mm, X86Mem)                                 // MMX
+    1515             :   ASMJIT_INST_2i(psrld, Psrld, X86Mm, Imm)                                    // MMX
+    1516             :   ASMJIT_INST_2x(psrld, Psrld, X86Xmm, X86Xmm)                                // SSE2
+    1517             :   ASMJIT_INST_2x(psrld, Psrld, X86Xmm, X86Mem)                                // SSE2
+    1518             :   ASMJIT_INST_2i(psrld, Psrld, X86Xmm, Imm)                                   // SSE2
+    1519             :   ASMJIT_INST_2i(psrldq, Psrldq, X86Xmm, Imm)                                 // SSE2
+    1520             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Mm, X86Mm)                                  // MMX
+    1521             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Mm, X86Mem)                                 // MMX
+    1522             :   ASMJIT_INST_2i(psrlq, Psrlq, X86Mm, Imm)                                    // MMX
+    1523             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Xmm, X86Xmm)                                // SSE2
+    1524             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Xmm, X86Mem)                                // SSE2
+    1525             :   ASMJIT_INST_2i(psrlq, Psrlq, X86Xmm, Imm)                                   // SSE2
+    1526             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Mm, X86Mm)                                  // MMX
+    1527             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Mm, X86Mem)                                 // MMX
+    1528             :   ASMJIT_INST_2i(psrlw, Psrlw, X86Mm, Imm)                                    // MMX
+    1529             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Xmm, X86Xmm)                                // SSE2
+    1530             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Xmm, X86Mem)                                // SSE2
+    1531             :   ASMJIT_INST_2i(psrlw, Psrlw, X86Xmm, Imm)                                   // SSE2
+    1532             :   ASMJIT_INST_2x(psubb, Psubb, X86Mm, X86Mm)                                  // MMX
+    1533             :   ASMJIT_INST_2x(psubb, Psubb, X86Mm, X86Mem)                                 // MMX
+    1534             :   ASMJIT_INST_2x(psubb, Psubb, X86Xmm, X86Xmm)                                // SSE2
+    1535             :   ASMJIT_INST_2x(psubb, Psubb, X86Xmm, X86Mem)                                // SSE2
+    1536             :   ASMJIT_INST_2x(psubd, Psubd, X86Mm, X86Mm)                                  // MMX
+    1537             :   ASMJIT_INST_2x(psubd, Psubd, X86Mm, X86Mem)                                 // MMX
+    1538             :   ASMJIT_INST_2x(psubd, Psubd, X86Xmm, X86Xmm)                                // SSE2
+    1539             :   ASMJIT_INST_2x(psubd, Psubd, X86Xmm, X86Mem)                                // SSE2
+    1540             :   ASMJIT_INST_2x(psubq, Psubq, X86Mm, X86Mm)                                  // SSE2
+    1541             :   ASMJIT_INST_2x(psubq, Psubq, X86Mm, X86Mem)                                 // SSE2
+    1542             :   ASMJIT_INST_2x(psubq, Psubq, X86Xmm, X86Xmm)                                // SSE2
+    1543             :   ASMJIT_INST_2x(psubq, Psubq, X86Xmm, X86Mem)                                // SSE2
+    1544             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Mm, X86Mm)                                // MMX
+    1545             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Mm, X86Mem)                               // MMX
+    1546             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Xmm, X86Xmm)                              // SSE2
+    1547             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Xmm, X86Mem)                              // SSE2
+    1548             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Mm, X86Mm)                                // MMX
+    1549             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Mm, X86Mem)                               // MMX
+    1550             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Xmm, X86Xmm)                              // SSE2
+    1551             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Xmm, X86Mem)                              // SSE2
+    1552             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Mm, X86Mm)                              // MMX
+    1553             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Mm, X86Mem)                             // MMX
+    1554             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Xmm, X86Xmm)                            // SSE2
+    1555             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Xmm, X86Mem)                            // SSE2
+    1556             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Mm, X86Mm)                              // MMX
+    1557             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Mm, X86Mem)                             // MMX
+    1558             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Xmm, X86Xmm)                            // SSE2
+    1559             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Xmm, X86Mem)                            // SSE2
+    1560             :   ASMJIT_INST_2x(psubw, Psubw, X86Mm, X86Mm)                                  // MMX
+    1561             :   ASMJIT_INST_2x(psubw, Psubw, X86Mm, X86Mem)                                 // MMX
+    1562             :   ASMJIT_INST_2x(psubw, Psubw, X86Xmm, X86Xmm)                                // SSE2
+    1563             :   ASMJIT_INST_2x(psubw, Psubw, X86Xmm, X86Mem)                                // SSE2
+    1564             :   ASMJIT_INST_2x(ptest, Ptest, X86Xmm, X86Xmm)                                // SSE4_1
+    1565             :   ASMJIT_INST_2x(ptest, Ptest, X86Xmm, X86Mem)                                // SSE4_1
+    1566             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Mm, X86Mm)                          // MMX
+    1567             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Mm, X86Mem)                         // MMX
+    1568             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Xmm, X86Xmm)                        // SSE2
+    1569             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Xmm, X86Mem)                        // SSE2
+    1570             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Mm, X86Mm)                          // MMX
+    1571             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Mm, X86Mem)                         // MMX
+    1572             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Xmm, X86Xmm)                        // SSE2
+    1573             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Xmm, X86Mem)                        // SSE2
+    1574             :   ASMJIT_INST_2x(punpckhqdq, Punpckhqdq, X86Xmm, X86Xmm)                      // SSE2
+    1575             :   ASMJIT_INST_2x(punpckhqdq, Punpckhqdq, X86Xmm, X86Mem)                      // SSE2
+    1576             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Mm, X86Mm)                          // MMX
+    1577             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Mm, X86Mem)                         // MMX
+    1578             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Xmm, X86Xmm)                        // SSE2
+    1579             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Xmm, X86Mem)                        // SSE2
+    1580             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Mm, X86Mm)                          // MMX
+    1581             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Mm, X86Mem)                         // MMX
+    1582             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Xmm, X86Xmm)                        // SSE2
+    1583             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Xmm, X86Mem)                        // SSE2
+    1584             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Mm, X86Mm)                          // MMX
+    1585             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Mm, X86Mem)                         // MMX
+    1586             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Xmm, X86Xmm)                        // SSE2
+    1587             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Xmm, X86Mem)                        // SSE2
+    1588             :   ASMJIT_INST_2x(punpcklqdq, Punpcklqdq, X86Xmm, X86Xmm)                      // SSE2
+    1589             :   ASMJIT_INST_2x(punpcklqdq, Punpcklqdq, X86Xmm, X86Mem)                      // SSE2
+    1590             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Mm, X86Mm)                          // MMX
+    1591             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Mm, X86Mem)                         // MMX
+    1592             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Xmm, X86Xmm)                        // SSE2
+    1593             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Xmm, X86Mem)                        // SSE2
+    1594             :   ASMJIT_INST_2x(pxor, Pxor, X86Mm, X86Mm)                                    // MMX
+    1595             :   ASMJIT_INST_2x(pxor, Pxor, X86Mm, X86Mem)                                   // MMX
+    1596             :   ASMJIT_INST_2x(pxor, Pxor, X86Xmm, X86Xmm)                                  // SSE2
+    1597             :   ASMJIT_INST_2x(pxor, Pxor, X86Xmm, X86Mem)                                  // SSE2
+    1598             :   ASMJIT_INST_2x(rcpps, Rcpps, X86Xmm, X86Xmm)                                // SSE
+    1599             :   ASMJIT_INST_2x(rcpps, Rcpps, X86Xmm, X86Mem)                                // SSE
+    1600             :   ASMJIT_INST_2x(rcpss, Rcpss, X86Xmm, X86Xmm)                                // SSE
+    1601             :   ASMJIT_INST_2x(rcpss, Rcpss, X86Xmm, X86Mem)                                // SSE
+    1602             :   ASMJIT_INST_3i(roundpd, Roundpd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1603             :   ASMJIT_INST_3i(roundpd, Roundpd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1604             :   ASMJIT_INST_3i(roundps, Roundps, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1605             :   ASMJIT_INST_3i(roundps, Roundps, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1606             :   ASMJIT_INST_3i(roundsd, Roundsd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1607             :   ASMJIT_INST_3i(roundsd, Roundsd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1608             :   ASMJIT_INST_3i(roundss, Roundss, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1609             :   ASMJIT_INST_3i(roundss, Roundss, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1610             :   ASMJIT_INST_2x(rsqrtps, Rsqrtps, X86Xmm, X86Xmm)                            // SSE
+    1611             :   ASMJIT_INST_2x(rsqrtps, Rsqrtps, X86Xmm, X86Mem)                            // SSE
+    1612             :   ASMJIT_INST_2x(rsqrtss, Rsqrtss, X86Xmm, X86Xmm)                            // SSE
+    1613             :   ASMJIT_INST_2x(rsqrtss, Rsqrtss, X86Xmm, X86Mem)                            // SSE
+    1614             :   ASMJIT_INST_3i(shufpd, Shufpd, X86Xmm, X86Xmm, Imm)                         // SSE2
+    1615             :   ASMJIT_INST_3i(shufpd, Shufpd, X86Xmm, X86Mem, Imm)                         // SSE2
+    1616             :   ASMJIT_INST_3i(shufps, Shufps, X86Xmm, X86Xmm, Imm)                         // SSE
+    1617             :   ASMJIT_INST_3i(shufps, Shufps, X86Xmm, X86Mem, Imm)                         // SSE
+    1618             :   ASMJIT_INST_2x(sqrtpd, Sqrtpd, X86Xmm, X86Xmm)                              // SSE2
+    1619             :   ASMJIT_INST_2x(sqrtpd, Sqrtpd, X86Xmm, X86Mem)                              // SSE2
+    1620             :   ASMJIT_INST_2x(sqrtps, Sqrtps, X86Xmm, X86Xmm)                              // SSE
+    1621             :   ASMJIT_INST_2x(sqrtps, Sqrtps, X86Xmm, X86Mem)                              // SSE
+    1622         126 :   ASMJIT_INST_2x(sqrtsd, Sqrtsd, X86Xmm, X86Xmm)                              // SSE2
+    1623             :   ASMJIT_INST_2x(sqrtsd, Sqrtsd, X86Xmm, X86Mem)                              // SSE2
+    1624             :   ASMJIT_INST_2x(sqrtss, Sqrtss, X86Xmm, X86Xmm)                              // SSE
+    1625             :   ASMJIT_INST_2x(sqrtss, Sqrtss, X86Xmm, X86Mem)                              // SSE
+    1626             :   ASMJIT_INST_2x(subpd, Subpd, X86Xmm, X86Xmm)                                // SSE2
+    1627             :   ASMJIT_INST_2x(subpd, Subpd, X86Xmm, X86Mem)                                // SSE2
+    1628             :   ASMJIT_INST_2x(subps, Subps, X86Xmm, X86Xmm)                                // SSE
+    1629             :   ASMJIT_INST_2x(subps, Subps, X86Xmm, X86Mem)                                // SSE
+    1630         990 :   ASMJIT_INST_2x(subsd, Subsd, X86Xmm, X86Xmm)                                // SSE2
+    1631             :   ASMJIT_INST_2x(subsd, Subsd, X86Xmm, X86Mem)                                // SSE2
+    1632             :   ASMJIT_INST_2x(subss, Subss, X86Xmm, X86Xmm)                                // SSE
+    1633             :   ASMJIT_INST_2x(subss, Subss, X86Xmm, X86Mem)                                // SSE
+    1634             :   ASMJIT_INST_2x(ucomisd, Ucomisd, X86Xmm, X86Xmm)                            // SSE2
+    1635             :   ASMJIT_INST_2x(ucomisd, Ucomisd, X86Xmm, X86Mem)                            // SSE2
+    1636             :   ASMJIT_INST_2x(ucomiss, Ucomiss, X86Xmm, X86Xmm)                            // SSE
+    1637             :   ASMJIT_INST_2x(ucomiss, Ucomiss, X86Xmm, X86Mem)                            // SSE
+    1638             :   ASMJIT_INST_2x(unpckhpd, Unpckhpd, X86Xmm, X86Xmm)                          // SSE2
+    1639             :   ASMJIT_INST_2x(unpckhpd, Unpckhpd, X86Xmm, X86Mem)                          // SSE2
+    1640             :   ASMJIT_INST_2x(unpckhps, Unpckhps, X86Xmm, X86Xmm)                          // SSE
+    1641             :   ASMJIT_INST_2x(unpckhps, Unpckhps, X86Xmm, X86Mem)                          // SSE
+    1642             :   ASMJIT_INST_2x(unpcklpd, Unpcklpd, X86Xmm, X86Xmm)                          // SSE2
+    1643             :   ASMJIT_INST_2x(unpcklpd, Unpcklpd, X86Xmm, X86Mem)                          // SSE2
+    1644             :   ASMJIT_INST_2x(unpcklps, Unpcklps, X86Xmm, X86Xmm)                          // SSE
+    1645             :   ASMJIT_INST_2x(unpcklps, Unpcklps, X86Xmm, X86Mem)                          // SSE
+    1646             :   ASMJIT_INST_2x(xorpd, Xorpd, X86Xmm, X86Xmm)                                // SSE2
+    1647             :   ASMJIT_INST_2x(xorpd, Xorpd, X86Xmm, X86Mem)                                // SSE2
+    1648         248 :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Xmm)                                // SSE
+    1649             :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Mem)                                // SSE
+    1650             : 
+    1651             :   // -------------------------------------------------------------------------
+    1652             :   // [3DNOW & GEODE]
+    1653             :   // -------------------------------------------------------------------------
+    1654             : 
+    1655             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mm)                              // 3DNOW
+    1656             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mem)                             // 3DNOW
+    1657             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mm)                                  // 3DNOW
+    1658             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mem)                                 // 3DNOW
+    1659             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mm)                                  // 3DNOW
+    1660             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mem)                                 // 3DNOW
+    1661             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mm)                                  // 3DNOW
+    1662             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mem)                                 // 3DNOW
+    1663             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mm)                                  // 3DNOW
+    1664             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mem)                                 // 3DNOW
+    1665             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mm)                              // 3DNOW
+    1666             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mem)                             // 3DNOW
+    1667             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mm)                              // 3DNOW
+    1668             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mem)                             // 3DNOW
+    1669             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mm)                              // 3DNOW
+    1670             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mem)                             // 3DNOW
+    1671             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mm)                                  // 3DNOW
+    1672             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mem)                                 // 3DNOW
+    1673             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mm)                                  // 3DNOW
+    1674             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mem)                                 // 3DNOW
+    1675             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mm)                                  // 3DNOW
+    1676             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mem)                                 // 3DNOW
+    1677             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mm)                                // 3DNOW
+    1678             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mem)                               // 3DNOW
+    1679             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mm)                              // 3DNOW
+    1680             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mem)                             // 3DNOW
+    1681             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mm)                                  // 3DNOW
+    1682             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mem)                                 // 3DNOW
+    1683             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mm)                            // 3DNOW
+    1684             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mem)                           // 3DNOW
+    1685             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mm)                            // 3DNOW
+    1686             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mem)                           // 3DNOW
+    1687             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mm)                                // GEODE
+    1688             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mem)                               // GEODE
+    1689             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mm)                            // 3DNOW
+    1690             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mem)                           // 3DNOW
+    1691             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mm)                              // 3DNOW
+    1692             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mem)                             // 3DNOW
+    1693             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mm)                            // GEODE
+    1694             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mem)                           // GEODE
+    1695             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mm)                                  // 3DNOW
+    1696             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mem)                                 // 3DNOW
+    1697             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mm)                                // 3DNOW
+    1698             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mem)                               // 3DNOW
+    1699             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mm)                                  // 3DNOW
+    1700             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mem)                                 // 3DNOW
+    1701             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mm)                                  // 3DNOW
+    1702             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mem)                                 // 3DNOW
+    1703             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mm)                              // 3DNOW
+    1704             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mem)                             // 3DNOW
+    1705             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mm)                                // 3DNOW
+    1706             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mem)                               // 3DNOW
+    1707             :   ASMJIT_INST_0x(femms, Femms)                                                // 3DNOW
+    1708             : 
+    1709             :   // --------------------------------------------------------------------------
+    1710             :   // [AESNI]
+    1711             :   // --------------------------------------------------------------------------
+    1712             : 
+    1713             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Xmm)                              // AESNI
+    1714             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Mem)                              // AESNI
+    1715             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Xmm)                      // AESNI
+    1716             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Mem)                      // AESNI
+    1717             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Xmm)                              // AESNI
+    1718             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Mem)                              // AESNI
+    1719             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Xmm)                      // AESNI
+    1720             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Mem)                      // AESNI
+    1721             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Xmm)                              // AESNI
+    1722             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Mem)                              // AESNI
+    1723             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Xmm, Imm)       // AESNI
+    1724             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Mem, Imm)       // AESNI
+    1725             : 
+    1726             :   // --------------------------------------------------------------------------
+    1727             :   // [SHA]
+    1728             :   // --------------------------------------------------------------------------
+    1729             : 
+    1730             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Xmm)                          // SHA
+    1731             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Mem)                          // SHA
+    1732             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Xmm)                          // SHA
+    1733             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Mem)                          // SHA
+    1734             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Xmm)                        // SHA
+    1735             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Mem)                        // SHA
+    1736             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Xmm, Imm)                   // SHA
+    1737             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Mem, Imm)                   // SHA
+    1738             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Xmm)                      // SHA
+    1739             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Mem)                      // SHA
+    1740             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Xmm)                      // SHA
+    1741             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Mem)                      // SHA
+    1742             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm, XMM0)              // SHA [EXPLICIT]
+    1743             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem, XMM0)              // SHA [EXPLICIT]
+    1744             : 
+    1745             :   // --------------------------------------------------------------------------
+    1746             :   // [AVX...AVX512]
+    1747             :   // --------------------------------------------------------------------------
+    1748             : 
+    1749             :   ASMJIT_INST_3x(kaddb, Kaddb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1750             :   ASMJIT_INST_3x(kaddd, Kaddd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1751             :   ASMJIT_INST_3x(kaddq, Kaddq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1752             :   ASMJIT_INST_3x(kaddw, Kaddw, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1753             :   ASMJIT_INST_3x(kandb, Kandb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1754             :   ASMJIT_INST_3x(kandd, Kandd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1755             :   ASMJIT_INST_3x(kandnb, Kandnb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1756             :   ASMJIT_INST_3x(kandnd, Kandnd, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1757             :   ASMJIT_INST_3x(kandnq, Kandnq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1758             :   ASMJIT_INST_3x(kandnw, Kandnw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1759             :   ASMJIT_INST_3x(kandq, Kandq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1760             :   ASMJIT_INST_3x(kandw, Kandw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1761             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86KReg)                              // AVX512_DQ
+    1762             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Mem)                               // AVX512_DQ
+    1763             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Gp)                                // AVX512_DQ
+    1764             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Mem, X86KReg)                               // AVX512_DQ
+    1765             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Gp, X86KReg)                                // AVX512_DQ
+    1766             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86KReg)                              // AVX512_BW
+    1767             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Mem)                               // AVX512_BW
+    1768             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Gp)                                // AVX512_BW
+    1769             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Mem, X86KReg)                               // AVX512_BW
+    1770             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Gp, X86KReg)                                // AVX512_BW
+    1771             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86KReg)                              // AVX512_BW
+    1772             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Mem)                               // AVX512_BW
+    1773             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Gp)                                // AVX512_BW
+    1774             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Mem, X86KReg)                               // AVX512_BW
+    1775             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Gp, X86KReg)                                // AVX512_BW
+    1776             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86KReg)                              // AVX512_F
+    1777             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Mem)                               // AVX512_F
+    1778             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Gp)                                // AVX512_F
+    1779             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Mem, X86KReg)                               // AVX512_F
+    1780             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Gp, X86KReg)                                // AVX512_F
+    1781             :   ASMJIT_INST_2x(knotb, Knotb, X86KReg, X86KReg)                              // AVX512_DQ
+    1782             :   ASMJIT_INST_2x(knotd, Knotd, X86KReg, X86KReg)                              // AVX512_BW
+    1783             :   ASMJIT_INST_2x(knotq, Knotq, X86KReg, X86KReg)                              // AVX512_BW
+    1784             :   ASMJIT_INST_2x(knotw, Knotw, X86KReg, X86KReg)                              // AVX512_F
+    1785             :   ASMJIT_INST_3x(korb, Korb, X86KReg, X86KReg, X86KReg)                       // AVX512_DQ
+    1786             :   ASMJIT_INST_3x(kord, Kord, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1787             :   ASMJIT_INST_3x(korq, Korq, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1788             :   ASMJIT_INST_2x(kortestb, Kortestb, X86KReg, X86KReg)                        // AVX512_DQ
+    1789             :   ASMJIT_INST_2x(kortestd, Kortestd, X86KReg, X86KReg)                        // AVX512_BW
+    1790             :   ASMJIT_INST_2x(kortestq, Kortestq, X86KReg, X86KReg)                        // AVX512_BW
+    1791             :   ASMJIT_INST_2x(kortestw, Kortestw, X86KReg, X86KReg)                        // AVX512_F
+    1792             :   ASMJIT_INST_3x(korw, Korw, X86KReg, X86KReg, X86KReg)                       // AVX512_F
+    1793             :   ASMJIT_INST_3i(kshiftlb, Kshiftlb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1794             :   ASMJIT_INST_3i(kshiftld, Kshiftld, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1795             :   ASMJIT_INST_3i(kshiftlq, Kshiftlq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1796             :   ASMJIT_INST_3i(kshiftlw, Kshiftlw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1797             :   ASMJIT_INST_3i(kshiftrb, Kshiftrb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1798             :   ASMJIT_INST_3i(kshiftrd, Kshiftrd, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1799             :   ASMJIT_INST_3i(kshiftrq, Kshiftrq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1800             :   ASMJIT_INST_3i(kshiftrw, Kshiftrw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1801             :   ASMJIT_INST_2x(ktestb, Ktestb, X86KReg, X86KReg)                            // AVX512_DQ
+    1802             :   ASMJIT_INST_2x(ktestd, Ktestd, X86KReg, X86KReg)                            // AVX512_BW
+    1803             :   ASMJIT_INST_2x(ktestq, Ktestq, X86KReg, X86KReg)                            // AVX512_BW
+    1804             :   ASMJIT_INST_2x(ktestw, Ktestw, X86KReg, X86KReg)                            // AVX512_DQ
+    1805             :   ASMJIT_INST_3x(kunpckbw, Kunpckbw, X86KReg, X86KReg, X86KReg)               // AVX512_F
+    1806             :   ASMJIT_INST_3x(kunpckdq, Kunpckdq, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1807             :   ASMJIT_INST_3x(kunpckwd, Kunpckwd, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1808             :   ASMJIT_INST_3x(kxnorb, Kxnorb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1809             :   ASMJIT_INST_3x(kxnord, Kxnord, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1810             :   ASMJIT_INST_3x(kxnorq, Kxnorq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1811             :   ASMJIT_INST_3x(kxnorw, Kxnorw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1812             :   ASMJIT_INST_3x(kxorb, Kxorb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1813             :   ASMJIT_INST_3x(kxord, Kxord, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1814             :   ASMJIT_INST_3x(kxorq, Kxorq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1815             :   ASMJIT_INST_3x(kxorw, Kxorw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1816             :   ASMJIT_INST_6x(v4fmaddps, V4fmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    1817             :   ASMJIT_INST_6x(v4fnmaddps, V4fnmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    1818             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    1819             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1820             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    1821             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1822             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    1823             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    1824             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    1825             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1826             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    1827             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1828             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    1829             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    1830             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1831             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1832             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1833             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1834             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1835             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1836             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1837             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1838             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1839             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1840             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1841             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1842             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1843             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1844             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1845             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1846             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1847             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1848             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1849             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1850             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Xmm)                            // AVX
+    1851             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Mem)                            // AVX
+    1852             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Xmm, Imm)     // AVX
+    1853             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Mem, Imm)     // AVX
+    1854             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    1855             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1856             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    1857             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1858             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    1859             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    1860             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    1861             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1862             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    1863             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1864             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    1865             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    1866             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1867             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1868             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1869             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1870             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    1871             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    1872             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1873             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1874             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1875             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1876             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b32}
+    1877             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b32}
+    1878             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1879             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1880             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1881             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1882             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    1883             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    1884             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1885             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1886             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1887             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1888             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    1889             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    1890             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1891             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1892             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1893             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1894             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1895             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1896             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    1897             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1898             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    1899             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1900             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    1901             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    1902             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    1903             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1904             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    1905             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1906             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    1907             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    1908             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    1909             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1910             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    1911             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1912             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    1913             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    1914             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    1915             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1916             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    1917             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1918             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    1919             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    1920             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1921             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1922             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1923             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1924             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1925             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1926             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1927             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1928             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1929             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1930             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1931             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1932             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1933             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1934             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1935             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1936             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1937             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1938             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1939             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1940             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1941             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1942             :   ASMJIT_INST_2x(vbroadcastf128, Vbroadcastf128, X86Ymm, X86Mem)              // AVX
+    1943             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1944             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1945             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1946             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1947             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}
+    1948             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1949             :   ASMJIT_INST_2x(vbroadcastf32x8, Vbroadcastf32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1950             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1951             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1952             :   ASMJIT_INST_2x(vbroadcastf64x4, Vbroadcastf64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1953             :   ASMJIT_INST_2x(vbroadcasti128, Vbroadcasti128, X86Ymm, X86Mem)              // AVX2
+    1954             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1955             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1956             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1957             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1958             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1959             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1960             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Xmm)            //      AVX512_F{kz}-VL
+    1961             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}-VL
+    1962             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1963             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1964             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1965             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1966             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1967             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1968             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1969             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1970             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1971             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1972             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1973             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1974             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    1975             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    1976             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1977             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1978             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}
+    1979             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}
+    1980             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Xmm)                  //      AVX512_F{kz}-VL
+    1981             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Mem)                  //      AVX512_F{kz}-VL
+    1982             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1983             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1984             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1985             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1986             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b64}-VL
+    1987             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1988             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b64}-VL
+    1989             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1990             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b64}
+    1991             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b64}
+    1992             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1993             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1994             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1995             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1996             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b32}-VL
+    1997             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    1998             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b32}-VL
+    1999             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    2000             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b32}
+    2001             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b32}
+    2002             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2003             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2004             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2005             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2006             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2007             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2008             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2009             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2010             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2011             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2012             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2013             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2014             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2015             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2016             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2017             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2018             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2019             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2020             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2021             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2022             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2023             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2024             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2025             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2026             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2027             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2028             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2029             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2030             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|b32}
+    2031             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2032             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2033             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2034             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2035             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2036             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2037             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2038             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b64}-VL
+    2039             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b64}-VL
+    2040             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Ymm)                        // AVX  AVX512_F{kz|b64}-VL
+    2041             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Zmm)                        //      AVX512_F{kz|er|b64}
+    2042             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Mem)                        //      AVX512_F{kz|er|b64}
+    2043             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Xmm)                        // AVX
+    2044             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Mem)                        // AVX
+    2045             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Ymm)                        // AVX
+    2046             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2047             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2048             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2049             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2050             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2051             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2052             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2053             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2054             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2055             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2056             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2057             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2058             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2059             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2060             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2061             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2062             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2063             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2064             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2065             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2066             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2067             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Ymm)                        //      AVX512_F{kz|sae}
+    2068             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2069             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2070             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2071             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2072             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2073             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2074             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2075             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2076             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2077             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2078             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2079             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|er|b32}
+    2080             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2081             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2082             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2083             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2084             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2085             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Ymm, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2086             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2087             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2088             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2089             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2090             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2091             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Ymm)                        //      AVX512_DQ{kz|er|b32}
+    2092             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b32}
+    2093             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2094             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2095             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2096             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2097             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2098             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2099             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2100             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2101             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2102             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2103             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|er|b32}
+    2104             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b32}
+    2105             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2106             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2107             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2108             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2109             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2110             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2111             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2112             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2113             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2114             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2115             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2116             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2117             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2118             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|er}
+    2119             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|er}
+    2120             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2121             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2122             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2123             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2124             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2125             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2126             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|sae}
+    2127             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|sae}
+    2128             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2129             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2130             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2131             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2132             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2133             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2134             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2135             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2136             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2137             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2138             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2139             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2140             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2141             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2142             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2143             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    2144             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    2145             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    2146             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Zmm)                    //      AVX512_F{kz|sae|b64}
+    2147             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|sae|b64}
+    2148             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    2149             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2150             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    2151             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2152             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|sae|b64}
+    2153             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b64}
+    2154             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2155             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2156             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2157             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2158             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2159             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2160             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2161             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2162             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2163             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2164             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|sae|b32}
+    2165             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|sae|b32}
+    2166             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    2167             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2168             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    2169             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2170             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Zmm)                    //      AVX512_F{kz|sae|b32}
+    2171             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Mem)                    //      AVX512_F{kz|sae|b32}
+    2172             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2173             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2174             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2175             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2176             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Ymm)                    //      AVX512_DQ{kz|sae|b32}
+    2177             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b32}
+    2178             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2179             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2180             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2181             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2182             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2183             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2184             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2185             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2186             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2187             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2188             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2189             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2190             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Ymm)                      //      AVX512_F{kz|b32}
+    2191             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2192             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2193             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2194             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2195             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2196             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2197             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2198             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2199             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2200             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2201             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2202             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2203             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2204             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2205             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2206             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2207             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2208             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2209             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2210             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2211             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2212             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2213             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_BW{kz}-VL
+    2214             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2215             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)           //      AVX512_BW{kz}-VL
+    2216             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2217             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Zmm, Imm)           //      AVX512_BW{kz}
+    2218             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Mem, Imm)           //      AVX512_BW{kz}
+    2219             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2220             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2221             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2222             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2223             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2224             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2225             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2226             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2227             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2228             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2229             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2230             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2231             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2232             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2233             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2234             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2235             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2236             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2237             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2238             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2239             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Ymm, Imm)                   // AVX
+    2240             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Mem, Imm)                   // AVX
+    2241             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b64}
+    2242             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b64}
+    2243             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b32}
+    2244             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b32}
+    2245             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2246             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2247             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2248             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2249             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2250             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2251             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2252             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2253             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2254             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2255             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2256             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2257             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Xmm, X86Ymm, Imm)             // AVX
+    2258             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Mem, X86Ymm, Imm)             // AVX
+    2259             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2260             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2261             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2262             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2263             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2264             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2265             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2266             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2267             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2268             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2269             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2270             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2271             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Xmm, X86Ymm, Imm)             // AVX2
+    2272             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Mem, X86Ymm, Imm)             // AVX2
+    2273             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2274             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2275             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2276             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2277             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2278             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2279             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2280             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2281             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2282             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2283             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2284             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2285             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Gp, X86Xmm, Imm)                  // AVX  AVX512_F
+    2286             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Mem, X86Xmm, Imm)                 // AVX  AVX512_F
+    2287             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b64}-VL
+    2288             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2289             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b64}-VL
+    2290             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2291             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b64}
+    2292             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b64}
+    2293             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b32}-VL
+    2294             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2295             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b32}-VL
+    2296             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2297             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b32}
+    2298             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b32}
+    2299             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2300             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2301             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2302             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2303             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2304             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2305             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2306             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2307             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2308             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2309             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2310             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2311             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2312             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2313             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2314             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2315             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2316             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2317             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2318             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2319             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2320             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2321             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2322             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2323             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2324             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2325             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2326             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2327             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2328             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2329             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2330             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2331             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2332             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2333             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2334             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2335             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2336             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2337             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2338             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2339             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2340             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2341             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2342             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2343             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2344             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2345             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2346             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2347             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2348             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2349             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2350             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2351             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2352             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2353             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2354             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2355             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2356             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2357             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2358             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2359             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2360             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2361             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2362             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2363             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2364             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2365             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2366             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2367             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2368             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2369             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2370             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2371             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2372             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2373             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2374             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2375             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2376             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2377             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2378             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2379             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2380             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2381             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2382             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2383             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2384             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2385             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2386             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2387             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2388             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2389             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2390             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2391             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2392             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2393             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2394             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2395             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2396             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2397             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2398             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2399             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2400             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2401             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2402             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2403             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2404             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2405             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2406             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2407             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2408             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2409             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2410             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2411             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2412             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2413             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2414             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2415             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2416             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2417             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2418             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2419             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2420             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2421             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2422             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2423             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2424             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2425             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2426             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2427             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2428             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2429             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2430             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2431             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2432             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2433             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2434             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2435             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2436             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2437             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2438             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2439             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2440             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2441             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2442             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2443             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2444             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2445             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2446             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2447             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2448             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2449             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2450             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2451             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2452             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2453             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2454             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2455             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2456             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2457             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2458             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2459             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2460             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2461             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2462             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2463             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2464             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2465             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2466             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2467             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2468             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2469             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2470             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2471             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2472             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2473             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2474             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2475             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2476             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2477             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2478             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2479             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2480             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2481             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2482             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2483             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2484             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2485             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2486             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2487             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2488             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2489             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2490             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2491             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2492             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2493             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2494             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2495             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2496             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2497             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2498             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2499             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2500             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2501             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2502             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2503             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2504             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2505             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2506             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2507             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2508             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2509             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2510             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2511             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2512             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2513             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2514             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2515             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2516             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2517             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2518             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2519             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2520             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2521             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2522             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2523             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2524             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2525             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2526             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2527             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2528             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2529             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2530             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2531             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2532             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2533             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2534             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2535             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2536             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2537             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2538             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2539             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2540             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2541             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2542             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2543             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2544             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2545             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2546             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2547             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2548             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2549             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2550             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2551             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2552             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2553             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2554             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2555             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2556             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2557             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2558             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2559             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2560             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2561             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2562             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2563             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2564             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2565             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2566             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2567             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2568             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b64} AVX512_DQ{k|b64}-VL
+    2569             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2570             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b64}
+    2571             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2572             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b32} AVX512_DQ{k|b32}-VL
+    2573             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2574             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b32}
+    2575             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2576             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2577             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2578             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2579             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2580             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2581             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2582             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2583             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2584             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2585             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2586             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2587             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2588             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2589             :   ASMJIT_INST_1x(vgatherpf0dpd, Vgatherpf0dpd, X86Mem)                        //      AVX512_PF{k}
+    2590             :   ASMJIT_INST_1x(vgatherpf0dps, Vgatherpf0dps, X86Mem)                        //      AVX512_PF{k}
+    2591             :   ASMJIT_INST_1x(vgatherpf0qpd, Vgatherpf0qpd, X86Mem)                        //      AVX512_PF{k}
+    2592             :   ASMJIT_INST_1x(vgatherpf0qps, Vgatherpf0qps, X86Mem)                        //      AVX512_PF{k}
+    2593             :   ASMJIT_INST_1x(vgatherpf1dpd, Vgatherpf1dpd, X86Mem)                        //      AVX512_PF{k}
+    2594             :   ASMJIT_INST_1x(vgatherpf1dps, Vgatherpf1dps, X86Mem)                        //      AVX512_PF{k}
+    2595             :   ASMJIT_INST_1x(vgatherpf1qpd, Vgatherpf1qpd, X86Mem)                        //      AVX512_PF{k}
+    2596             :   ASMJIT_INST_1x(vgatherpf1qps, Vgatherpf1qps, X86Mem)                        //      AVX512_PF{k}
+    2597             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2598             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2599             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2600             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2601             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2602             :   ASMJIT_INST_3x(vgatherqps, Vgatherqps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2603             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2604             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2605             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2606             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    2607             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2608             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    2609             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2610             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b64}
+    2611             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b64}
+    2612             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    2613             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2614             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    2615             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2616             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b32}
+    2617             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b32}
+    2618             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2619             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2620             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2621             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2622             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2623             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2624             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2625             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2626             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b64}
+    2627             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b64}
+    2628             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2629             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2630             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2631             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2632             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b32}
+    2633             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b32}
+    2634             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2635             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2636             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2637             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2638             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2639             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2640             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2641             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2642             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2643             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2644             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2645             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2646             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2647             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2648             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2649             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2650             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2651             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2652             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2653             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2654             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX
+    2655             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX
+    2656             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2657             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2658             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2659             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2660             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2661             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2662             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2663             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2664             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2665             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2666             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2667             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2668             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX2
+    2669             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX2
+    2670             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2671             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2672             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2673             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2674             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2675             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2676             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2677             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2678             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2679             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2680             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2681             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2682             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Xmm, Imm)           // AVX  AVX512_F
+    2683             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Mem, Imm)           // AVX  AVX512_F
+    2684             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Xmm, X86Mem)                              // AVX
+    2685             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Ymm, X86Mem)                              // AVX
+    2686             :   ASMJIT_INST_1x(vldmxcsr, Vldmxcsr, X86Mem)                                  // AVX
+    2687             :   ASMJIT_INST_3x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm, DS_ZDI)            // AVX  [EXPLICIT]
+    2688             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2689             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2690             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2691             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2692             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2693             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2694             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2695             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2696             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2697             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2698             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2699             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2700             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2701             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2702             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2703             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2704             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2705             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2706             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2707             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2708             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2709             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2710             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2711             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2712             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2713             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2714             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2715             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2716             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2717             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2718             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2719             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2720             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2721             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2722             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2723             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2724             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2725             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2726             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2727             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2728             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2729             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2730             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2731             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2732             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2733             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2734             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2735             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2736             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2737             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2738             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2739             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2740             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2741             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2742             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2743             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2744             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2745             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2746             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2747             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2748             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2749             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2750             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Xmm)                          // AVX  AVX512_F{kz}-VL
+    2751             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2752             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Ymm)                          // AVX  AVX512_F{kz}-VL
+    2753             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2754             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Zmm)                          //      AVX512_F{kz}
+    2755             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Mem)                          //      AVX512_F{kz}
+    2756             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Xmm)                            // AVX
+    2757             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Mem)                            // AVX
+    2758             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Xmm)                            // AVX
+    2759             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Ymm)                            // AVX
+    2760             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Mem)                            // AVX
+    2761             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Ymm)                            // AVX
+    2762             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2763             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2764             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2765             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2766             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2767             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2768             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2769             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2770             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2771             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2772             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2773             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2774             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2775             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2776             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2777             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2778             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2779             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2780             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Xmm)                            // AVX
+    2781             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Mem)                            // AVX
+    2782             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Xmm)                            // AVX
+    2783             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Ymm)                            // AVX
+    2784             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Mem)                            // AVX
+    2785             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Ymm)                            // AVX
+    2786             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2787             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2788             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2789             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2790             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2791             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2792             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Zmm)                        //      AVX512_BW{kz}
+    2793             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    2794             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    2795             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2796             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2797             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2798             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2799             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2800             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2801             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2802             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2803             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2804             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2805             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2806             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2807             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2808             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2809             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2810             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2811             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2812             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2813             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2814             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2815             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2816             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2817             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2818             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2819             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Zmm)                          //      AVX512_BW{kz}
+    2820             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Mem)                          //      AVX512_BW{kz}
+    2821             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    2822             :   ASMJIT_INST_3x(vmovhlps, Vmovhlps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2823             :   ASMJIT_INST_2x(vmovhpd, Vmovhpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2824             :   ASMJIT_INST_3x(vmovhpd, Vmovhpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2825             :   ASMJIT_INST_2x(vmovhps, Vmovhps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2826             :   ASMJIT_INST_3x(vmovhps, Vmovhps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2827             :   ASMJIT_INST_3x(vmovlhps, Vmovlhps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2828             :   ASMJIT_INST_2x(vmovlpd, Vmovlpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2829             :   ASMJIT_INST_3x(vmovlpd, Vmovlpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2830             :   ASMJIT_INST_2x(vmovlps, Vmovlps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2831             :   ASMJIT_INST_3x(vmovlps, Vmovlps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2832             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Xmm)                         // AVX
+    2833             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Ymm)                         // AVX
+    2834             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Xmm)                         // AVX
+    2835             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Ymm)                         // AVX
+    2836             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2837             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2838             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Zmm)                          //      AVX512_F
+    2839             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Xmm, X86Mem)                        // AVX  AVX512_F-VL
+    2840             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Ymm, X86Mem)                        // AVX2 AVX512_F-VL
+    2841             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Zmm, X86Mem)                        //      AVX512_F
+    2842             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2843             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2844             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Zmm)                          //      AVX512_F
+    2845             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2846             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2847             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Zmm)                          //      AVX512_F
+    2848             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2849             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2850             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2851             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2852             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Xmm)                                // AVX  AVX512_F
+    2853             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2854             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2855             :   ASMJIT_INST_3x(vmovsd, Vmovsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2856             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2857             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2858             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2859             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2860             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2861             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2862             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2863             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2864             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2865             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2866             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2867             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2868             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2869             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2870             :   ASMJIT_INST_3x(vmovss, Vmovss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2871             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2872             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2873             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2874             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2875             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2876             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2877             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2878             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2879             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2880             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2881             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2882             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2883             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2884             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2885             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2886             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2887             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2888             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2889             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    2890             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    2891             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    2892             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    2893             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2894             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2895             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2896             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2897             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2898             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2899             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2900             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2901             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2902             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2903             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2904             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2905             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2906             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2907             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2908             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2909             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2910             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2911             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2912             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2913             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|b64}
+    2914             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|b64}
+    2915             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2916             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2917             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2918             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2919             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    2920             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2921             :   ASMJIT_INST_6x(vp4dpwssd, Vp4dpwssd, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    2922             :   ASMJIT_INST_6x(vp4dpwssds, Vp4dpwssds, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    2923             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2924             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2925             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2926             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2927             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2928             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2929             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Xmm)                              // AVX  AVX512_F{kz}-VL
+    2930             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}-VL
+    2931             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Ymm)                              // AVX2 AVX512_F{kz}-VL
+    2932             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Mem)                              // AVX2 AVX512_F{kz}-VL
+    2933             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2934             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2935             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Xmm)                              //      AVX512_F{kz}-VL
+    2936             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Mem)                              //      AVX512_F{kz}-VL
+    2937             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Ymm)                              //      AVX512_F{kz}-VL
+    2938             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Mem)                              //      AVX512_F{kz}-VL
+    2939             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2940             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2941             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2942             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2943             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2944             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2945             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2946             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2947             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2948             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2949             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2950             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2951             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2952             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2953             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2954             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2955             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2956             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2957             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2958             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2959             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2960             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2961             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2962             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2963             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2964             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2965             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2966             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2967             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2968             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2969             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2970             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2971             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    2972             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    2973             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    2974             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    2975             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    2976             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    2977             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2978             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2979             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2980             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2981             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    2982             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2983             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2984             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2985             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2986             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2987             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    2988             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    2989             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2990             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2991             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2992             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2993             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    2994             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    2995             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2996             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2997             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2998             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2999             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3000             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3001             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3002             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3003             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3004             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3005             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3006             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3007             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3008             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3009             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3010             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3011             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3012             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3013             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3014             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3015             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3016             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3017             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3018             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3019             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX  AVX512_BW{kz}-VL
+    3020             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX  AVX512_BW{kz}-VL
+    3021             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3022             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3023             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_BW{kz}
+    3024             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_BW{kz}
+    3025             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    3026             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    3027             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    3028             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    3029             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    3030             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3031             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    3032             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3033             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    3034             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    3035             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    3036             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    3037             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Ymm)                      // AVX2
+    3038             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Mem)                      // AVX2
+    3039             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3040             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3041             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3042             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3043             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3044             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3045             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3046             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3047             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3048             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3049             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3050             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3051             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    3052             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3053             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3054             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3055             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    3056             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    3057             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3058             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3059             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_BW{kz}-VL
+    3060             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3061             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3062             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3063             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    3064             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3065             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3066             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3067             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3068             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3069             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX2
+    3070             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX2
+    3071             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3072             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3073             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    3074             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    3075             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX2
+    3076             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX2
+    3077             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    3078             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    3079             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3080             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3081             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3082             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3083             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3084             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3085             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3086             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3087             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3088             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3089             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3090             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3091             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3092             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3093             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3094             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3095             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3096             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3097             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3098             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3099             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3100             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3101             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Zmm, X86KReg)           //      AVX512_CD
+    3102             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3103             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3104             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Zmm, X86KReg)           //      AVX512_CD
+    3105             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3106             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3107             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3108             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3109             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3110             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3111             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3112             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3113             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3114             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3115             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3116             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3117             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3118             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3119             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3120             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3121             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3122             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3123             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Xmm, Imm)         // AVX
+    3124             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Mem, Imm)         // AVX
+    3125             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k}-VL
+    3126             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3127             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k}-VL
+    3128             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3129             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k}
+    3130             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k}
+    3131             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b32}-VL
+    3132             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3133             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b32}-VL
+    3134             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3135             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b32}
+    3136             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b32}
+    3137             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3138             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3139             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3140             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3141             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3142             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3143             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3144             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3145             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3146             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3147             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3148             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3149             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3150             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3151             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3152             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3153             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3154             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3155             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3156             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3157             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3158             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3159             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3160             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3161             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3162             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3163             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3164             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3165             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3166             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3167             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3168             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3169             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3170             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3171             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3172             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3173             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3174             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3175             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3176             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3177             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3178             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3179             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3180             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3181             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3182             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3183             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3184             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3185             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3186             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3187             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3188             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3189             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3190             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3191             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3192             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3193             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3194             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3195             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3196             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3197             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3198             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3199             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3200             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3201             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3202             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3203             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3204             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3205             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3206             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3207             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3208             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3209             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3210             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3211             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3212             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3213             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3214             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3215             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3216             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3217             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3218             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3219             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3220             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3221             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm, ECX)            // AVX  [EXPLICIT]
+    3222             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm, ECX)            // AVX  [EXPLICIT]
+    3223             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm, XMM0)           // AVX  [EXPLICIT]
+    3224             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm, XMM0)           // AVX  [EXPLICIT]
+    3225             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b64}-VL
+    3226             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3227             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b64}-VL
+    3228             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3229             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b64}
+    3230             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b64}
+    3231             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k}-VL
+    3232             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3233             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k}-VL
+    3234             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3235             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k}
+    3236             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k}
+    3237             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b32}-VL
+    3238             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3239             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b32}-VL
+    3240             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3241             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b32}
+    3242             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b32}
+    3243             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b64}-VL
+    3244             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3245             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b64}-VL
+    3246             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3247             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b64}
+    3248             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b64}
+    3249             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k|b64}-VL
+    3250             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3251             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k|b64}-VL
+    3252             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3253             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k|b64}
+    3254             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k|b64}
+    3255             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k|b64}-VL
+    3256             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3257             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k|b64}-VL
+    3258             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3259             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k|b64}
+    3260             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k|b64}
+    3261             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3262             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3263             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3264             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3265             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3266             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3267             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3268             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3269             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3270             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3271             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3272             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3273             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3274             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3275             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3276             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3277             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3278             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3279             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3280             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3281             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3282             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3283             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3284             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3285             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX
+    3286             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX
+    3287             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX2
+    3288             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX2
+    3289             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_VBMI{kz}-VL
+    3290             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3291             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_VBMI{kz}-VL
+    3292             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3293             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_VBMI{kz}
+    3294             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_VBMI{kz}
+    3295             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    3296             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    3297             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}-VL
+    3298             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3299             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3300             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3301             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3302             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3303             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3304             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3305             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3306             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3307             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3308             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3309             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3310             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3311             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3312             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3313             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3314             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3315             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3316             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3317             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3318             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3319             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3320             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3321             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3322             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3323             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3324             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3325             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3326             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3327             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3328             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3329             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3330             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3331             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3332             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3333             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3334             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3335             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3336             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3337             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3338             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3339             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3340             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3341             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3342             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3343             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3344             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3345             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3346             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3347             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3348             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3349             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3350             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3351             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3352             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3353             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3354             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3355             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3356             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3357             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3358             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3359             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Ymm, Imm)                       // AVX2
+    3360             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Mem, Imm)                       // AVX2
+    3361             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3362             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3363             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3364             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Mem, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3365             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3366             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3367             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}-VL
+    3368             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3369             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3370             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3371             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3372             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3373             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3374             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3375             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3376             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3377             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3378             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3379             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3380             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3381             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3382             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3383             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3384             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3385             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3386             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3387             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3388             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3389             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3390             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3391             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3392             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3393             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3394             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3395             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3396             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3397             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3398             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3399             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3400             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3401             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3402             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3403             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3404             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3405             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3406             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3407             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_BW{kz}-VL
+    3408             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3409             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_BW{kz}-VL
+    3410             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3411             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3412             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3413             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3414             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3415             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3416             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3417             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3418             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3419             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3420             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3421             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3422             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3423             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3424             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3425             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3426             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3427             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3428             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3429             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3430             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3431             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3432             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3433             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3434             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3435             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3436             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3437             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3438             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3439             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3440             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3441             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3442             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3443             :   ASMJIT_INST_3x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3444             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3445             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3446             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3447             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3448             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3449             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3450             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3451             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3452             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3453             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3454             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3455             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3456             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3457             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3458             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3459             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3460             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3461             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3462             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3463             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3464             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Xmm)                    // AVX
+    3465             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Mem)                    // AVX
+    3466             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3467             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3468             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3469             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3470             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3471             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3472             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3473             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3474             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3475             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3476             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3477             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3478             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Gp, Imm)                        // AVX
+    3479             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Mem, Imm)                       // AVX
+    3480             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_BW{kz}
+    3481             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_BW{kz}
+    3482             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Gp, Imm)                        // AVX
+    3483             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Mem, Imm)                       // AVX
+    3484             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3485             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3486             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Gp, Imm)                        // AVX
+    3487             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Mem, Imm)                       // AVX
+    3488             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3489             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3490             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Gp, Imm)                // AVX  AVX512_BW{kz}
+    3491             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_BW{kz}
+    3492             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b32}-VL
+    3493             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3494             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b32}-VL
+    3495             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3496             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b32}
+    3497             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b32}
+    3498             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b64}-VL
+    3499             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3500             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b64}-VL
+    3501             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3502             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b64}
+    3503             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b64}
+    3504             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3505             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3506             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3507             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3508             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3509             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3510             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3511             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3512             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3513             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3514             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3515             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3516             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    3517             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    3518             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    3519             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    3520             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    3521             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    3522             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3523             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3524             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3525             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3526             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3527             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3528             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3529             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3530             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3531             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3532             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3533             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3534             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3535             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3536             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3537             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3538             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3539             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3540             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3541             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3542             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3543             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3544             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3545             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3546             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3547             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3548             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3549             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3550             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3551             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3552             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3553             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3554             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3555             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3556             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3557             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3558             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3559             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3560             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3561             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3562             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3563             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3564             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3565             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3566             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3567             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3568             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3569             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3570             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3571             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3572             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3573             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3574             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3575             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3576             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3577             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3578             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3579             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3580             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3581             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3582             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3583             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3584             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3585             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3586             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3587             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3588             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3589             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3590             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3591             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3592             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3593             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3594             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3595             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3596             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3597             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3598             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3599             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3600             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3601             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3602             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3603             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3604             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3605             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3606             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3607             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3608             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3609             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3610             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3611             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3612             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3613             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3614             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3615             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3616             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3617             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3618             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3619             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3620             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3621             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3622             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3623             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3624             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3625             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3626             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3627             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3628             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3629             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3630             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3631             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3632             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3633             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3634             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3635             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3636             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3637             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3638             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3639             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3640             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3641             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3642             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3643             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3644             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3645             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3646             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3647             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3648             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3649             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3650             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3651             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3652             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Zmm, X86KReg)                         //      AVX512_BW
+    3653             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3654             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3655             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3656             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3657             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3658             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3659             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3660             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3661             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Zmm, X86KReg)                         //      AVX512_BW
+    3662             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Xmm)                         // AVX
+    3663             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Ymm)                         // AVX2
+    3664             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3665             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3666             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3667             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3668             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3669             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3670             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3671             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3672             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3673             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3674             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3675             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3676             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3677             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3678             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3679             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3680             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3681             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3682             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3683             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3684             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3685             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3686             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3687             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3688             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3689             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3690             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3691             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3692             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3693             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3694             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3695             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3696             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3697             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3698             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3699             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3700             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3701             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3702             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3703             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3704             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3705             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3706             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3707             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3708             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3709             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3710             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3711             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3712             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3713             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3714             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3715             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3716             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3717             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3718             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3719             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Ymm, X86Zmm)                          //      AVX512_BW{kz}
+    3720             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    3721             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3722             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3723             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3724             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3725             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3726             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3727             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3728             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3729             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3730             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3731             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3732             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3733             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3734             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3735             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3736             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3737             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3738             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3739             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3740             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3741             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3742             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3743             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3744             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3745             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3746             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3747             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3748             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3749             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3750             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3751             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3752             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3753             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3754             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3755             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3756             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3757             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3758             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3759             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3760             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3761             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3762             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3763             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3764             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3765             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3766             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3767             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3768             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3769             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3770             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3771             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3772             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3773             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3774             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3775             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3776             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3777             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3778             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3779             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3780             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3781             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3782             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3783             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3784             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3785             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3786             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3787             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3788             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3789             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3790             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3791             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Ymm, X86Zmm)                        //      AVX512_BW{kz}
+    3792             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    3793             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3794             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3795             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3796             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3797             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3798             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3799             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3800             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Ymm, X86Zmm)                            //      AVX512_BW{kz}
+    3801             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Zmm)                            //      AVX512_BW{kz}
+    3802             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3803             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3804             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3805             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3806             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3807             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3808             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3809             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3810             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3811             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3812             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3813             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3814             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3815             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3816             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3817             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3818             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3819             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3820             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3821             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3822             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3823             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3824             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3825             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3826             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3827             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3828             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3829             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3830             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3831             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3832             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3833             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3834             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3835             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3836             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3837             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3838             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b64}-VL
+    3839             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b64}-VL
+    3840             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    3841             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    3842             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3843             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3844             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    3845             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    3846             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    3847             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    3848             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    3849             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    3850             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3851             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3852             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3853             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3854             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3855             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3856             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3857             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3858             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3859             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3860             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3861             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3862             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3863             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3864             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3865             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3866             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3867             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3868             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    3869             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3870             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    3871             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3872             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    3873             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    3874             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3875             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3876             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3877             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3878             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3879             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3880             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Xmm)      //      AVX512_VBMI{kz|b64}-VL
+    3881             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3882             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Ymm)      //      AVX512_VBMI{kz|b64}-VL
+    3883             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3884             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Zmm)      //      AVX512_VBMI{kz|b64}
+    3885             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Mem)      //      AVX512_VBMI{kz|b64}
+    3886             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F{kz|b64}-VL
+    3887             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz|b64}-VL
+    3888             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_F{kz|b64}-VL
+    3889             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz|b64}-VL
+    3890             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3891             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3892             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3893             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3894             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3895             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3896             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Xmm)                          // AVX
+    3897             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Mem)                          // AVX
+    3898             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Ymm)                          // AVX2
+    3899             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Mem)                          // AVX2
+    3900             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    3901             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3902             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    3903             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3904             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    3905             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    3906             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    3907             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3908             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    3909             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3910             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b64}
+    3911             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b64}
+    3912             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3913             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3914             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3915             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3916             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3917             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3918             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3919             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3920             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3921             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3922             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3923             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3924             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3925             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3926             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3927             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3928             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3929             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3930             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3931             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3932             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3933             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3934             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3935             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3936             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3937             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3938             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3939             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3940             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3941             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3942             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3943             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3944             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3945             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3946             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3947             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3948             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3949             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3950             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3951             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3952             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3953             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3954             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3955             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3956             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3957             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3958             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3959             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3960             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW-VL
+    3961             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW-VL
+    3962             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW-VL
+    3963             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW-VL
+    3964             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW
+    3965             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW
+    3966             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3967             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3968             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3969             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3970             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3971             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3972             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3973             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    3974             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3975             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3976             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3977             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3978             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3979             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3980             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3981             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3982             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3983             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3984             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Mem, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3985             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3986             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Mem, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3987             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Zmm, Imm)                       //      AVX512_F{kz|b32}
+    3988             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Mem, Imm)                       //      AVX512_F{kz|b32}
+    3989             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3990             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3991             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3992             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3993             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    3994             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    3995             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3996             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3997             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3998             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3999             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    4000             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    4001             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4002             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4003             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4004             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4005             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4006             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4007             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4008             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4009             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4010             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4011             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4012             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4013             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4014             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4015             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4016             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4017             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4018             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4019             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4020             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4021             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4022             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4023             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4024             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4025             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4026             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4027             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4028             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4029             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4030             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4031             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4032             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4033             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4034             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4035             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4036             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4037             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4038             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4039             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4040             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4041             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4042             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4043             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4044             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4045             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4046             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4047             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4048             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4049             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4050             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4051             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4052             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4053             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4054             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4055             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4056             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4057             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4058             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4059             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4060             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4061             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4062             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4063             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4064             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4065             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4066             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4067             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4068             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4069             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4070             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4071             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4072             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4073             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4074             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4075             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4076             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4077             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4078             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4079             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4080             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4081             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4082             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4083             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4084             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4085             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4086             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz}-VL
+    4087             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4088             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4089             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4090             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz}-VL
+    4091             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4092             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4093             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4094             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4095             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4096             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4097             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4098             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4099             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4100             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4101             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4102             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4103             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    4104             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4105             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    4106             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4107             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4108             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4109             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4110             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4111             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4112             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4113             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4114             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4115             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4116             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4117             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4118             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4119             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4120             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4121             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4122             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4123             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4124             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4125             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4126             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4127             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4128             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4129             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4130             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4131             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4132             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4133             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4134             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4135             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4136             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4137             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4138             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4139             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4140             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4141             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4142             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4143             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4144             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4145             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4146             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4147             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4148             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4149             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4150             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4151             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4152             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4153             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4154             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4155             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4156             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4157             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4158             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4159             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4160             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4161             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4162             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4163             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4164             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4165             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4166             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4167             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4168             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4169             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4170             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4171             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4172             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4173             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4174             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4175             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4176             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4177             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4178             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4179             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4180             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4181             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4182             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4183             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4184             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4185             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4186             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4187             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4188             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4189             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4190             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4191             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4192             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4193             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4194             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4195             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4196             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4197             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4198             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4199             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4200             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4201             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4202             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4203             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4204             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4205             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4206             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4207             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4208             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4209             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4210             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4211             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4212             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4213             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4214             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4215             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4216             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4217             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4218             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4219             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4220             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4221             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4222             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4223             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4224             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4225             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4226             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4227             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4228             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4229             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4230             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4231             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4232             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4233             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4234             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4235             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b32}-VL
+    4236             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4237             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4238             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4239             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4240             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4241             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b64}-VL
+    4242             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4243             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4244             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4245             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4246             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4247             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Xmm)                              // AVX
+    4248             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Mem)                              // AVX
+    4249             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Ymm)                              // AVX
+    4250             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Mem)                              // AVX
+    4251             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4252             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4253             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4254             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4255             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4256             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4257             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    4258             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4259             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    4260             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4261             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    4262             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    4263             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    4264             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4265             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    4266             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4267             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    4268             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    4269             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4270             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4271             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4272             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4273             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4274             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4275             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4276             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4277             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4278             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4279             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4280             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4281             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b32}-VL
+    4282             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4283             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b32}-VL
+    4284             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4285             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b32}
+    4286             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b32}
+    4287             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b64}-VL
+    4288             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4289             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b64}-VL
+    4290             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4291             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b64}
+    4292             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b64}
+    4293             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4294             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4295             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4296             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4297             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4298             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4299             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4300             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4301             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4302             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4303             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4304             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4305             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4306             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4307             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4308             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4309             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4310             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4311             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4312             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4313             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4314             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4315             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4316             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4317             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4318             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4319             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4320             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4321             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4322             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4323             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4324             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4325             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4326             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4327             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4328             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4329             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4330             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4331             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4332             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4333             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4334             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4335             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4336             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4337             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4338             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4339             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4340             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4341             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4342             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4343             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4344             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4345             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4346             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4347             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    4348             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    4349             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    4350             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    4351             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4352             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4353             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4354             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4355             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4356             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4357             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4358             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4359             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4360             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4361             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4362             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4363             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4364             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4365             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4366             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4367             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4368             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4369             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4370             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4371             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4372             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4373             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4374             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4375             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4376             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4377             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4378             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4379             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b64}-VL
+    4380             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4381             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b64}-VL
+    4382             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4383             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b64}
+    4384             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Mem)                          //      AVX512_F{kz|b64}
+    4385             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b32}-VL
+    4386             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4387             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b32}-VL
+    4388             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4389             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b32}
+    4390             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Mem)                          //      AVX512_F{kz|b32}
+    4391             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4392             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4393             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4394             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4395             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b64}
+    4396             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b64}
+    4397             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b32}
+    4398             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b32}
+    4399             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4400             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4401             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4402             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4403             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Xmm)                              // AVX
+    4404             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Mem)                              // AVX
+    4405             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Ymm)                              // AVX
+    4406             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Mem)                              // AVX
+    4407             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    4408             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    4409             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4410             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4411             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4412             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4413             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b64}
+    4414             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}
+    4415             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4416             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4417             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4418             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4419             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b32}
+    4420             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}
+    4421             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4422             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4423             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4424             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4425             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    4426             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4427             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    4428             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4429             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b64}
+    4430             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b64}
+    4431             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    4432             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4433             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    4434             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4435             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b32}
+    4436             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b32}
+    4437             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4438             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4439             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4440             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4441             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Xmm, Imm)                     // AVX
+    4442             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Mem, Imm)                     // AVX
+    4443             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Ymm, Imm)                     // AVX
+    4444             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Mem, Imm)                     // AVX
+    4445             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Xmm, Imm)                     // AVX
+    4446             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Mem, Imm)                     // AVX
+    4447             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Ymm, Imm)                     // AVX
+    4448             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Mem, Imm)                     // AVX
+    4449             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4450             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4451             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4452             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4453             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4454             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4455             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4456             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4457             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4458             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4459             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4460             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4461             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4462             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4463             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4464             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4465             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4466             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4467             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4468             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4469             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b64}
+    4470             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b64}
+    4471             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b32}
+    4472             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b32}
+    4473             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4474             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4475             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4476             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4477             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Xmm)                          // AVX
+    4478             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Mem)                          // AVX
+    4479             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Ymm)                          // AVX
+    4480             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Mem)                          // AVX
+    4481             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    4482             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    4483             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    4484             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4485             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    4486             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4487             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b64}
+    4488             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b64}
+    4489             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    4490             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4491             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    4492             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4493             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b32}
+    4494             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b32}
+    4495             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4496             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4497             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4498             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4499             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4500             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4501             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4502             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4503             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4504             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4505             :   ASMJIT_INST_1x(vscatterpf0dpd, Vscatterpf0dpd, X86Mem)                      //      AVX512_PF{k}
+    4506             :   ASMJIT_INST_1x(vscatterpf0dps, Vscatterpf0dps, X86Mem)                      //      AVX512_PF{k}
+    4507             :   ASMJIT_INST_1x(vscatterpf0qpd, Vscatterpf0qpd, X86Mem)                      //      AVX512_PF{k}
+    4508             :   ASMJIT_INST_1x(vscatterpf0qps, Vscatterpf0qps, X86Mem)                      //      AVX512_PF{k}
+    4509             :   ASMJIT_INST_1x(vscatterpf1dpd, Vscatterpf1dpd, X86Mem)                      //      AVX512_PF{k}
+    4510             :   ASMJIT_INST_1x(vscatterpf1dps, Vscatterpf1dps, X86Mem)                      //      AVX512_PF{k}
+    4511             :   ASMJIT_INST_1x(vscatterpf1qpd, Vscatterpf1qpd, X86Mem)                      //      AVX512_PF{k}
+    4512             :   ASMJIT_INST_1x(vscatterpf1qps, Vscatterpf1qps, X86Mem)                      //      AVX512_PF{k}
+    4513             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4514             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4515             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4516             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4517             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    4518             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4519             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4520             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4521             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4522             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4523             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4524             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4525             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4526             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4527             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4528             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4529             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4530             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4531             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4532             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4533             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4534             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4535             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4536             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4537             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4538             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    4539             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    4540             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4541             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4542             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4543             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4544             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    4545             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    4546             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b64}-VL
+    4547             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4548             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b64}-VL
+    4549             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4550             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b64}
+    4551             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b64}
+    4552             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b32}-VL
+    4553             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4554             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b32}-VL
+    4555             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4556             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b32}
+    4557             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b32}
+    4558             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4559             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4560             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4561             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4562             :   ASMJIT_INST_1x(vstmxcsr, Vstmxcsr, X86Mem)                                  // AVX
+    4563             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4564             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4565             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4566             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4567             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    4568             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    4569             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4570             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4571             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4572             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4573             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    4574             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    4575             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4576             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4577             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4578             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4579             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Xmm)                            // AVX
+    4580             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Mem)                            // AVX
+    4581             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Ymm)                            // AVX
+    4582             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Mem)                            // AVX
+    4583             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Xmm)                            // AVX
+    4584             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Mem)                            // AVX
+    4585             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Ymm)                            // AVX
+    4586             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Mem)                            // AVX
+    4587             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4588             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4589             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4590             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4591             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4592             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4593             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4594             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4595             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4596             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4597             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4598             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4599             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4600             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4601             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4602             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4603             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4604             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4605             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4606             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4607             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4608             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4609             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4610             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4611             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4612             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4613             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4614             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4615             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4616             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4617             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4618             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4619             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    4620             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    4621             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4622             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4623             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4624             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4625             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    4626             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    4627             :   ASMJIT_INST_0x(vzeroall, Vzeroall)                                          // AVX
+    4628           0 :   ASMJIT_INST_0x(vzeroupper, Vzeroupper)                                      // AVX
+    4629             : 
+    4630             :   // --------------------------------------------------------------------------
+    4631             :   // [FMA4]
+    4632             :   // --------------------------------------------------------------------------
+    4633             : 
+    4634             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4635             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4636             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4637             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4638             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4639             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4640             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4641             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4642             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4643             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4644             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4645             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4646             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4647             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4648             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4649             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4650             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4651             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4652             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4653             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4654             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4655             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4656             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4657             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4658             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4659             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4660             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4661             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4662             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4663             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4664             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4665             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4666             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4667             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4668             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4669             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4670             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4671             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4672             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4673             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4674             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4675             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4676             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4677             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4678             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4679             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4680             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4681             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4682             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4683             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4684             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4685             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4686             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4687             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4688             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4689             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4690             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4691             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4692             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4693             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4694             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4695             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4696             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4697             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4698             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4699             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4700             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4701             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4702             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4703             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4704             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4705             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4706             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4707             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4708             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4709             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4710             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4711             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4712             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4713             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4714             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4715             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4716             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4717             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4718             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4719             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4720             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4721             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4722             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4723             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4724             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4725             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4726             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4727             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4728             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4729             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4730             : 
+    4731             :   // --------------------------------------------------------------------------
+    4732             :   // [XOP]
+    4733             :   // --------------------------------------------------------------------------
+    4734             : 
+    4735             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Xmm)                            // XOP
+    4736             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Mem)                            // XOP
+    4737             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Ymm)                            // XOP
+    4738             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Mem)                            // XOP
+    4739             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Xmm)                            // XOP
+    4740             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Mem)                            // XOP
+    4741             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Ymm)                            // XOP
+    4742             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Mem)                            // XOP
+    4743             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Xmm)                            // XOP
+    4744             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Mem)                            // XOP
+    4745             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Xmm)                            // XOP
+    4746             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Mem)                            // XOP
+    4747             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4748             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4749             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4750             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Ymm)              // XOP
+    4751             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Mem, X86Ymm)              // XOP
+    4752             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Mem)              // XOP
+    4753             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4754             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4755             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4756             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4757             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4758             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4759             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4760             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4761             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4762             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4763             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4764             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4765             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4766             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4767             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4768             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4769             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4770             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4771             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4772             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4773             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4774             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4775             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4776             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4777             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4778             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4779             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4780             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4781             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Xmm)                          // XOP
+    4782             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Mem)                          // XOP
+    4783             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Xmm)                          // XOP
+    4784             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Mem)                          // XOP
+    4785             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Xmm)                          // XOP
+    4786             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Mem)                          // XOP
+    4787             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Xmm)                          // XOP
+    4788             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Mem)                          // XOP
+    4789             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Xmm)                          // XOP
+    4790             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Mem)                          // XOP
+    4791             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Xmm)                          // XOP
+    4792             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Mem)                          // XOP
+    4793             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Xmm)                        // XOP
+    4794             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Mem)                        // XOP
+    4795             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Xmm)                        // XOP
+    4796             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Mem)                        // XOP
+    4797             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Xmm)                        // XOP
+    4798             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Mem)                        // XOP
+    4799             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Xmm)                        // XOP
+    4800             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Mem)                        // XOP
+    4801             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Xmm)                        // XOP
+    4802             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Mem)                        // XOP
+    4803             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Xmm)                        // XOP
+    4804             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Mem)                        // XOP
+    4805             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Xmm)                          // XOP
+    4806             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Mem)                          // XOP
+    4807             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Xmm)                          // XOP
+    4808             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Mem)                          // XOP
+    4809             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Xmm)                          // XOP
+    4810             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Mem)                          // XOP
+    4811             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4812             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4813             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4814             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4815             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4816             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4817             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4818             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4819             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4820             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4821             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4822             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4823             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4824             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4825             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4826             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4827             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4828             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4829             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4830             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4831             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4832             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4833             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4834             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4835             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4836             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4837             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4838             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4839             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4840             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4841             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Xmm, Imm)                         // XOP
+    4842             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Mem, Imm)                         // XOP
+    4843             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4844             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4845             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4846             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Xmm, Imm)                         // XOP
+    4847             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Mem, Imm)                         // XOP
+    4848             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4849             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4850             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4851             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Xmm, Imm)                         // XOP
+    4852             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Mem, Imm)                         // XOP
+    4853             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4854             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4855             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4856             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Xmm, Imm)                         // XOP
+    4857             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Mem, Imm)                         // XOP
+    4858             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4859             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4860             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4861             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4862             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4863             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4864             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4865             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4866             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4867             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4868             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4869             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4870             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4871             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4872             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4873             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4874             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4875             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4876             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4877             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4878             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4879             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4880             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4881             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4882             : };
+    4883             : 
+    4884             : // ============================================================================
+    4885             : // [asmjit::X86EmitterImplicitT]
+    4886             : // ============================================================================
+    4887             : 
+    4888             : template<typename This>
+    4889             : struct X86EmitterImplicitT : public X86EmitterExplicitT<This> {
+    4890             :   // --------------------------------------------------------------------------
+    4891             :   // [Options]
+    4892             :   // --------------------------------------------------------------------------
+    4893             : 
+    4894             :   //! Use REP/REPZ prefix.
+    4895             :   ASMJIT_INLINE This& rep() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRep); }
+    4896             :   //! Use REPNZ prefix.
+    4897             :   ASMJIT_INLINE This& repnz() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRepnz); }
+    4898             : 
+    4899             :   //! Use REP/REPZ prefix.
+    4900             :   ASMJIT_INLINE This& repe() noexcept { return rep(); }
+    4901             :   //! Use REP/REPZ prefix.
+    4902             :   ASMJIT_INLINE This& repz() noexcept { return rep(); }
+    4903             :   //! Use REPNZ prefix.
+    4904             :   ASMJIT_INLINE This& repne() noexcept { return repnz(); }
+    4905             : 
+    4906             :   // --------------------------------------------------------------------------
+    4907             :   // [General Purpose and Non-SIMD Instructions]
+    4908             :   // --------------------------------------------------------------------------
+    4909             : 
+    4910             :   // TODO: xrstor and xsave don't have explicit variants yet.
+    4911             : 
+    4912             :   using X86EmitterExplicitT<This>::cbw;
+    4913             :   using X86EmitterExplicitT<This>::cdq;
+    4914             :   using X86EmitterExplicitT<This>::cdqe;
+    4915             :   using X86EmitterExplicitT<This>::clzero;
+    4916             :   using X86EmitterExplicitT<This>::cqo;
+    4917             :   using X86EmitterExplicitT<This>::cwd;
+    4918             :   using X86EmitterExplicitT<This>::cwde;
+    4919             :   using X86EmitterExplicitT<This>::cmpsd;
+    4920             :   using X86EmitterExplicitT<This>::cmpxchg;
+    4921             :   using X86EmitterExplicitT<This>::cmpxchg8b;
+    4922             :   using X86EmitterExplicitT<This>::cmpxchg16b;
+    4923             :   using X86EmitterExplicitT<This>::cpuid;
+    4924             :   using X86EmitterExplicitT<This>::div;
+    4925             :   using X86EmitterExplicitT<This>::idiv;
+    4926             :   using X86EmitterExplicitT<This>::imul;
+    4927             :   using X86EmitterExplicitT<This>::jecxz;
+    4928             :   using X86EmitterExplicitT<This>::lahf;
+    4929             :   using X86EmitterExplicitT<This>::mulx;
+    4930             :   using X86EmitterExplicitT<This>::movsd;
+    4931             :   using X86EmitterExplicitT<This>::mul;
+    4932             :   using X86EmitterExplicitT<This>::rdmsr;
+    4933             :   using X86EmitterExplicitT<This>::rdpmc;
+    4934             :   using X86EmitterExplicitT<This>::rdtsc;
+    4935             :   using X86EmitterExplicitT<This>::rdtscp;
+    4936             :   using X86EmitterExplicitT<This>::sahf;
+    4937             :   using X86EmitterExplicitT<This>::wrmsr;
+    4938             :   using X86EmitterExplicitT<This>::xgetbv;
+    4939             :   using X86EmitterExplicitT<This>::xsetbv;
+    4940             : 
+    4941             :   ASMJIT_INST_0x(cbw, Cbw)                                                    // ANY       [IMPLICIT] AX      <- Sign Extend AL
+    4942             :   ASMJIT_INST_0x(cdq, Cdq)                                                    // ANY       [IMPLICIT] EDX:EAX <- Sign Extend EAX
+    4943             :   ASMJIT_INST_0x(cdqe, Cdqe)                                                  // X64       [IMPLICIT] RAX     <- Sign Extend EAX
+    4944             :   ASMJIT_INST_0x(clzero, Clzero)                                              // CLZERO    [IMPLICIT]
+    4945             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Gp, X86Gp)                              // I486      [IMPLICIT]
+    4946             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Mem, X86Gp)                             // I486      [IMPLICIT]
+    4947             :   ASMJIT_INST_1x(cmpxchg16b, Cmpxchg16b, X86Mem)                              // CMPXCHG8B [IMPLICIT] m == RDX:RAX ? m <- RCX:RBX
+    4948             :   ASMJIT_INST_1x(cmpxchg8b, Cmpxchg8b, X86Mem)                                // CMPXCHG16B[IMPLICIT] m == EDX:EAX ? m <- ECX:EBX
+    4949             :   ASMJIT_INST_0x(cpuid, Cpuid)                                                // I486      [IMPLICIT] EAX:EBX:ECX:EDX  <- CPUID[EAX:ECX]
+    4950             :   ASMJIT_INST_0x(cqo, Cqo)                                                    // X64       [IMPLICIT] RDX:RAX <- Sign Extend RAX
+    4951             :   ASMJIT_INST_0x(cwd, Cwd)                                                    // ANY       [IMPLICIT] DX:AX   <- Sign Extend AX
+    4952             :   ASMJIT_INST_0x(cwde, Cwde)                                                  // ANY       [IMPLICIT] EAX     <- Sign Extend AX
+    4953             :   ASMJIT_INST_0x(daa, Daa)
+    4954             :   ASMJIT_INST_0x(das, Das)
+    4955             :   ASMJIT_INST_1x(div, Div, X86Gp)                                             // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4956             :   ASMJIT_INST_1x(div, Div, X86Mem)                                            // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4957             :   ASMJIT_INST_1x(idiv, Idiv, X86Gp)                                           // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4958             :   ASMJIT_INST_1x(idiv, Idiv, X86Mem)                                          // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4959             :   ASMJIT_INST_1x(imul, Imul, X86Gp)                                           // ANY       [IMPLICIT] {AX <- AL * r8} {xAX:xDX <- xAX * r16|r32|r64}
+    4960             :   ASMJIT_INST_1x(imul, Imul, X86Mem)                                          // ANY       [IMPLICIT] {AX <- AL * m8} {xAX:xDX <- xAX * m16|m32|m64}
+    4961             :   ASMJIT_INST_0x(iret, Iret)                                                  // ANY       [IMPLICIT]
+    4962             :   ASMJIT_INST_0x(iretd, Iretd)                                                // ANY       [IMPLICIT]
+    4963             :   ASMJIT_INST_0x(iretq, Iretq)                                                // X64       [IMPLICIT]
+    4964             :   ASMJIT_INST_0x(iretw, Iretw)                                                // ANY       [IMPLICIT]
+    4965             :   ASMJIT_INST_1x(jecxz, Jecxz, Label)                                         // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4966             :   ASMJIT_INST_1x(jecxz, Jecxz, Imm)                                           // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4967             :   ASMJIT_INST_1x(jecxz, Jecxz, uint64_t)                                      // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4968             :   ASMJIT_INST_0x(lahf, Lahf)                                                  // LAHFSAHF  [IMPLICIT] AH <- EFL
+    4969             :   ASMJIT_INST_1x(loop, Loop, Label)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4970             :   ASMJIT_INST_1x(loop, Loop, Imm)                                             // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4971             :   ASMJIT_INST_1x(loop, Loop, uint64_t)                                        // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4972             :   ASMJIT_INST_1x(loope, Loope, Label)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4973             :   ASMJIT_INST_1x(loope, Loope, Imm)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4974             :   ASMJIT_INST_1x(loope, Loope, uint64_t)                                      // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4975             :   ASMJIT_INST_1x(loopne, Loopne, Label)                                       // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4976             :   ASMJIT_INST_1x(loopne, Loopne, Imm)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4977             :   ASMJIT_INST_1x(loopne, Loopne, uint64_t)                                    // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4978             :   ASMJIT_INST_1x(mul, Mul, X86Gp)                                             // ANY       [IMPLICIT] {AX <- AL * r8} {xDX:xAX <- xAX * r16|r32|r64}
+    4979             :   ASMJIT_INST_1x(mul, Mul, X86Mem)                                            // ANY       [IMPLICIT] {AX <- AL * m8} {xDX:xAX <- xAX * m16|m32|m64}
+    4980             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Gp)                             // BMI2      [IMPLICIT]
+    4981             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Mem)                            // BMI2      [IMPLICIT]
+    4982             :   ASMJIT_INST_0x(rdmsr, Rdmsr)                                                // ANY       [IMPLICIT]
+    4983             :   ASMJIT_INST_0x(rdpmc, Rdpmc)                                                // ANY       [IMPLICIT]
+    4984             :   ASMJIT_INST_0x(rdtsc, Rdtsc)                                                // RDTSC     [IMPLICIT] EDX:EAX <- CNT
+    4985             :   ASMJIT_INST_0x(rdtscp, Rdtscp)                                              // RDTSCP    [IMPLICIT] EDX:EAX:EXC <- CNT
+    4986             :   ASMJIT_INST_0x(ret, Ret)
+    4987             :   ASMJIT_INST_1i(ret, Ret, Imm)
+    4988             :   ASMJIT_INST_0x(sahf, Sahf)                                                  // LAHFSAHF  [IMPLICIT] EFL <- AH
+    4989             :   ASMJIT_INST_0x(syscall, Syscall)                                            // X64       [IMPLICIT]
+    4990             :   ASMJIT_INST_0x(sysenter, Sysenter)                                          // X64       [IMPLICIT]
+    4991             :   ASMJIT_INST_0x(sysexit, Sysexit)                                            // X64       [IMPLICIT]
+    4992             :   ASMJIT_INST_0x(sysexit64, Sysexit64)                                        // X64       [IMPLICIT]
+    4993             :   ASMJIT_INST_0x(sysret, Sysret)                                              // X64       [IMPLICIT]
+    4994             :   ASMJIT_INST_0x(sysret64, Sysret64)                                          // X64       [IMPLICIT]
+    4995             :   ASMJIT_INST_0x(wrmsr, Wrmsr)                                                // ANY       [IMPLICIT]
+    4996             :   ASMJIT_INST_0x(xgetbv, Xgetbv)                                              // XSAVE     [IMPLICIT] EDX:EAX <- XCR[ECX]
+    4997             :   ASMJIT_INST_0x(xlatb, Xlatb)                                                // ANY       [IMPLICIT]
+    4998             :   ASMJIT_INST_1x(xrstor, Xrstor, X86Mem)                                      // XSAVE     [IMPLICIT]
+    4999             :   ASMJIT_INST_1x(xrstor64, Xrstor64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5000             :   ASMJIT_INST_1x(xrstors, Xrstors, X86Mem)                                    // XSAVE     [IMPLICIT]
+    5001             :   ASMJIT_INST_1x(xrstors64, Xrstors64, X86Mem)                                // XSAVE+X64 [IMPLICIT]
+    5002             :   ASMJIT_INST_1x(xsave, Xsave, X86Mem)                                        // XSAVE     [IMPLICIT]
+    5003             :   ASMJIT_INST_1x(xsave64, Xsave64, X86Mem)                                    // XSAVE+X64 [IMPLICIT]
+    5004             :   ASMJIT_INST_1x(xsavec, Xsavec, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5005             :   ASMJIT_INST_1x(xsavec64, Xsavec64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5006             :   ASMJIT_INST_1x(xsaveopt, Xsaveopt, X86Mem)                                  // XSAVE     [IMPLICIT]
+    5007             :   ASMJIT_INST_1x(xsaveopt64, Xsaveopt64, X86Mem)                              // XSAVE+X64 [IMPLICIT]
+    5008             :   ASMJIT_INST_1x(xsaves, Xsaves, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5009             :   ASMJIT_INST_1x(xsaves64, Xsaves64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5010             :   ASMJIT_INST_0x(xsetbv, Xsetbv)                                              // XSAVE     [IMPLICIT] XCR[ECX] <- EDX:EAX
+    5011             : 
+    5012             :   // String instructions aliases.
+    5013             :   ASMJIT_INLINE Error cmpsb() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 1), X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5014             :   ASMJIT_INLINE Error cmpsd() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 4), X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5015             :   ASMJIT_INLINE Error cmpsq() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 8), X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5016             :   ASMJIT_INLINE Error cmpsw() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 2), X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5017             : 
+    5018             :   ASMJIT_INLINE Error lodsb() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5019             :   ASMJIT_INLINE Error lodsd() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5020             :   ASMJIT_INLINE Error lodsq() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5021             :   ASMJIT_INLINE Error lodsw() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5022             : 
+    5023             :   ASMJIT_INLINE Error movsb() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 1), X86EmitterExplicitT<This>::ptr_zsi(0, 1)); }
+    5024             :   ASMJIT_INLINE Error movsd() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 4), X86EmitterExplicitT<This>::ptr_zsi(0, 4)); }
+    5025             :   ASMJIT_INLINE Error movsq() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 8), X86EmitterExplicitT<This>::ptr_zsi(0, 8)); }
+    5026             :   ASMJIT_INLINE Error movsw() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 2), X86EmitterExplicitT<This>::ptr_zsi(0, 2)); }
+    5027             : 
+    5028             :   ASMJIT_INLINE Error scasb() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5029             :   ASMJIT_INLINE Error scasd() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5030             :   ASMJIT_INLINE Error scasq() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5031             :   ASMJIT_INLINE Error scasw() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5032             : 
+    5033             :   ASMJIT_INLINE Error stosb() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 1), x86::al ); }
+    5034             :   ASMJIT_INLINE Error stosd() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 4), x86::eax); }
+    5035             :   ASMJIT_INLINE Error stosq() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 8), x86::rax); }
+    5036             :   ASMJIT_INLINE Error stosw() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 2), x86::ax ); }
+    5037             : 
+    5038             :   // --------------------------------------------------------------------------
+    5039             :   // [MONITOR|MWAIT]
+    5040             :   // --------------------------------------------------------------------------
+    5041             : 
+    5042             :   ASMJIT_INST_0x(monitor, Monitor)
+    5043             :   ASMJIT_INST_0x(mwait, Mwait)
+    5044             : 
+    5045             :   // --------------------------------------------------------------------------
+    5046             :   // [MMX & SSE Instructions]
+    5047             :   // --------------------------------------------------------------------------
+    5048             : 
+    5049             :   using X86EmitterExplicitT<This>::blendvpd;
+    5050             :   using X86EmitterExplicitT<This>::blendvps;
+    5051             :   using X86EmitterExplicitT<This>::maskmovq;
+    5052             :   using X86EmitterExplicitT<This>::maskmovdqu;
+    5053             :   using X86EmitterExplicitT<This>::pblendvb;
+    5054             :   using X86EmitterExplicitT<This>::pcmpestri;
+    5055             :   using X86EmitterExplicitT<This>::pcmpestrm;
+    5056             :   using X86EmitterExplicitT<This>::pcmpistri;
+    5057             :   using X86EmitterExplicitT<This>::pcmpistrm;
+    5058             : 
+    5059             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5060             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5061             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5062             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5063             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5064             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5065             :   ASMJIT_INST_2x(maskmovq, Maskmovq, X86Mm, X86Mm)                            // SSE    [IMPLICIT]
+    5066             :   ASMJIT_INST_2x(maskmovdqu, Maskmovdqu, X86Xmm, X86Xmm)                      // SSE2   [IMPLICIT]
+    5067             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5068             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5069             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5070             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5071             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5072             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5073             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5074             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5075             : 
+    5076             :   // --------------------------------------------------------------------------
+    5077             :   // [SHA]
+    5078             :   // --------------------------------------------------------------------------
+    5079             : 
+    5080             :   using X86EmitterExplicitT<This>::sha256rnds2;
+    5081             : 
+    5082             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm)                    // SHA [IMPLICIT]
+    5083             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem)                    // SHA [IMPLICIT]
+    5084             : 
+    5085             :   // --------------------------------------------------------------------------
+    5086             :   // [AVX...AVX512]
+    5087             :   // --------------------------------------------------------------------------
+    5088             : 
+    5089             :   using X86EmitterExplicitT<This>::vmaskmovdqu;
+    5090             :   using X86EmitterExplicitT<This>::vpcmpestri;
+    5091             :   using X86EmitterExplicitT<This>::vpcmpestrm;
+    5092             :   using X86EmitterExplicitT<This>::vpcmpistri;
+    5093             :   using X86EmitterExplicitT<This>::vpcmpistrm;
+    5094             : 
+    5095             :   ASMJIT_INST_2x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm)                    // AVX  [IMPLICIT]
+    5096             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5097             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5098             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5099             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5100             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5101             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5102             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5103             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5104             : };
+    5105             : 
+    5106             : #undef ASMJIT_INST_0x
+    5107             : #undef ASMJIT_INST_1x
+    5108             : #undef ASMJIT_INST_1i
+    5109             : #undef ASMJIT_INST_1c
+    5110             : #undef ASMJIT_INST_2x
+    5111             : #undef ASMJIT_INST_2i
+    5112             : #undef ASMJIT_INST_2c
+    5113             : #undef ASMJIT_INST_3x
+    5114             : #undef ASMJIT_INST_3i
+    5115             : #undef ASMJIT_INST_3ii
+    5116             : #undef ASMJIT_INST_4x
+    5117             : #undef ASMJIT_INST_4i
+    5118             : #undef ASMJIT_INST_4ii
+    5119             : #undef ASMJIT_INST_5x
+    5120             : #undef ASMJIT_INST_5i
+    5121             : #undef ASMJIT_INST_6x
+    5122             : #undef ASMJIT_EMIT
+    5123             : 
+    5124             : // ============================================================================
+    5125             : // [asmjit::X86Emitter]
+    5126             : // ============================================================================
+    5127             : 
+    5128             : //! X86/X64 emitter.
+    5129             : //!
+    5130             : //! NOTE: This class cannot be created, you can only cast to it and use it as
+    5131             : //! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
+    5132             : //! with caution with X86Compiler as it expects virtual registers to be used).
+    5133             : class X86Emitter : public CodeEmitter, public X86EmitterImplicitT<X86Emitter> {
+    5134             :   ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
+    5135             : };
+    5136             : 
+    5137             : //! \}
+    5138             : 
+    5139             : } // asmjit namespace
+    5140             : } // namespace PLMD
+    5141             : 
+    5142             : // [Api-End]
+    5143             : #include "./asmjit_apiend.h"
+    5144             : 
+    5145             : // [Guard]
+    5146             : #endif // _ASMJIT_X86_X86EMITTER_H
+    5147             : #pragma GCC diagnostic pop
+    5148             : #endif // __PLUMED_HAS_ASMJIT
+    5149             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html new file mode 100644 index 0000000000..00b66f97ff --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func.html b/coverage-libs/asmjit/x86inst.cpp.func.html new file mode 100644 index 0000000000..26b6bf5d18 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.gcov.html b/coverage-libs/asmjit/x86inst.cpp.gcov.html new file mode 100644 index 0000000000..58b19f0ffa --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.gcov.html @@ -0,0 +1,3829 @@ + + + + + + + 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-05-27 13:05:16Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // ----------------------------------------------------------------------------
+      30             : // IMPORTANT: AsmJit now uses an external instruction database to populate
+      31             : // static tables within this file. Perform the following steps to regenerate
+      32             : // all tables enclosed by ${...}:
+      33             : //
+      34             : //   1. Install node.js environment <https://nodejs.org>
+      35             : //   2. Go to asmjit/tools directory
+      36             : //   3. Install either asmdb package by executing `npm install asmdb` or get
+      37             : //      the latest asmdb from <https://github.com/asmjit/asmdb> and copy/link
+      38             : //      the `asmdb` directory to `asmjit/tools/asmdb`.
+      39             : //   4. Execute `node generate-x86.js`
+      40             : //
+      41             : // Instruction encoding and opcodes were added to the `x86inst.cpp` database
+      42             : // manually in the past and they are not updated by the script as they seem
+      43             : // consistent. However, everything else is updated including instruction
+      44             : // operands and tables required to validate them, instruction read/write
+      45             : // information (including registers and flags), and all indexes to all tables.
+      46             : // ----------------------------------------------------------------------------
+      47             : 
+      48             : // [Export]
+      49             : #define ASMJIT_EXPORTS
+      50             : 
+      51             : // [Guard]
+      52             : #include "./asmjit_build.h"
+      53             : #if defined(ASMJIT_BUILD_X86)
+      54             : 
+      55             : // [Dependencies]
+      56             : #include "./cpuinfo.h"
+      57             : #include "./utils.h"
+      58             : #include "./x86inst.h"
+      59             : #include "./x86operand.h"
+      60             : 
+      61             : // [Api-Begin]
+      62             : #include "./asmjit_apibegin.h"
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace asmjit {
+      66             : 
+      67             : // ============================================================================
+      68             : // [Enums (Internal)]
+      69             : // ============================================================================
+      70             : 
+      71             : //! \internal
+      72             : enum ODATA_ {
+      73             :   // PREFIX.
+      74             :   ODATA_000000  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_00,
+      75             :   ODATA_000F00  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F,
+      76             :   ODATA_000F01  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F01,
+      77             :   ODATA_000F38  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F38,
+      78             :   ODATA_000F3A  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F3A,
+      79             :   ODATA_660000  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_00,
+      80             :   ODATA_660F00  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F,
+      81             :   ODATA_660F38  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F38,
+      82             :   ODATA_660F3A  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F3A,
+      83             :   ODATA_F20000  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_00,
+      84             :   ODATA_F20F00  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F,
+      85             :   ODATA_F20F38  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F38,
+      86             :   ODATA_F20F3A  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F3A,
+      87             :   ODATA_F30000  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_00,
+      88             :   ODATA_F30F00  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F,
+      89             :   ODATA_F30F38  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F38,
+      90             :   ODATA_F30F3A  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F3A,
+      91             :   ODATA_000F0F  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F, // 3DNOW, special case.
+      92             : 
+      93             :   ODATA_FPU_00  = X86Inst::kOpCode_PP_00,
+      94             :   ODATA_FPU_9B  = X86Inst::kOpCode_PP_9B,
+      95             : 
+      96             :   ODATA_XOP_M8  = X86Inst::kOpCode_MM_XOP08,
+      97             :   ODATA_XOP_M9  = X86Inst::kOpCode_MM_XOP09,
+      98             : 
+      99             :   ODATA_O__     = 0,
+     100             :   ODATA_O_0     = 0 << X86Inst::kOpCode_O_Shift,
+     101             :   ODATA_O_1     = 1 << X86Inst::kOpCode_O_Shift,
+     102             :   ODATA_O_2     = 2 << X86Inst::kOpCode_O_Shift,
+     103             :   ODATA_O_3     = 3 << X86Inst::kOpCode_O_Shift,
+     104             :   ODATA_O_4     = 4 << X86Inst::kOpCode_O_Shift,
+     105             :   ODATA_O_5     = 5 << X86Inst::kOpCode_O_Shift,
+     106             :   ODATA_O_6     = 6 << X86Inst::kOpCode_O_Shift,
+     107             :   ODATA_O_7     = 7 << X86Inst::kOpCode_O_Shift,
+     108             : 
+     109             :   // REX/VEX.
+     110             :   ODATA_LL__    = 0,                                  // L is unspecified.
+     111             :   ODATA_LL_x    = 0,                                  // L is based on operand(s).
+     112             :   ODATA_LL_I    = 0,                                  // L is ignored (LIG).
+     113             :   ODATA_LL_0    = 0,                                  // L has to be zero (L.128).
+     114             :   ODATA_LL_1    = X86Inst::kOpCode_LL_256,            // L has to be one (L.256).
+     115             :   ODATA_LL_2    = X86Inst::kOpCode_LL_512,            // L has to be two (L.512).
+     116             : 
+     117             :   ODATA_W__     = 0,                                  // W is unspecified.
+     118             :   ODATA_W_x     = 0,                                  // W is based on operand(s).
+     119             :   ODATA_W_I     = 0,                                  // W is ignored (WIG).
+     120             :   ODATA_W_0     = 0,                                  // W has to be zero (W0).
+     121             :   ODATA_W_1     = X86Inst::kOpCode_W,                 // W has to be one (W1).
+     122             : 
+     123             :   // EVEX.
+     124             :   ODATA_EvexW__ = 0,                                  // Not EVEX instruction.
+     125             :   ODATA_EvexW_x = 0,                                  // EVEX.W is based on operand(s).
+     126             :   ODATA_EvexW_I = 0,                                  // EVEX.W is ignored     (EVEX.WIG).
+     127             :   ODATA_EvexW_0 = 0,                                  // EVEX.W has to be zero (EVEX.W0).
+     128             :   ODATA_EvexW_1 = X86Inst::kOpCode_EW,                // EVEX.W has to be one  (EVEX.W1).
+     129             : 
+     130             :   ODATA_N__      = 0,                                 // Base element size not used.
+     131             :   ODATA_N_0      = 0 << X86Inst::kOpCode_CDSHL_Shift, // N << 0 (BYTE).
+     132             :   ODATA_N_1      = 1 << X86Inst::kOpCode_CDSHL_Shift, // N << 1 (WORD).
+     133             :   ODATA_N_2      = 2 << X86Inst::kOpCode_CDSHL_Shift, // N << 2 (DWORD).
+     134             :   ODATA_N_3      = 3 << X86Inst::kOpCode_CDSHL_Shift, // N << 3 (QWORD).
+     135             :   ODATA_N_4      = 4 << X86Inst::kOpCode_CDSHL_Shift, // N << 4 (OWORD).
+     136             :   ODATA_N_5      = 5 << X86Inst::kOpCode_CDSHL_Shift, // N << 5 (YWORD).
+     137             : 
+     138             :   ODATA_TT__     = 0,
+     139             :   ODATA_TT_FV    = X86Inst::kOpCode_CDTT_FV,
+     140             :   ODATA_TT_HV    = X86Inst::kOpCode_CDTT_HV,
+     141             :   ODATA_TT_FVM   = X86Inst::kOpCode_CDTT_FVM,
+     142             :   ODATA_TT_T1S   = X86Inst::kOpCode_CDTT_T1S,
+     143             :   ODATA_TT_T1F   = X86Inst::kOpCode_CDTT_T1F,
+     144             :   ODATA_TT_T1W   = X86Inst::kOpCode_CDTT_T1W,
+     145             :   ODATA_TT_T2    = X86Inst::kOpCode_CDTT_T2,
+     146             :   ODATA_TT_T4    = X86Inst::kOpCode_CDTT_T4,
+     147             :   ODATA_TT_T8    = X86Inst::kOpCode_CDTT_T8,
+     148             :   ODATA_TT_HVM   = X86Inst::kOpCode_CDTT_HVM,
+     149             :   ODATA_TT_OVM   = X86Inst::kOpCode_CDTT_OVM,
+     150             :   ODATA_TT_QVM   = X86Inst::kOpCode_CDTT_QVM,
+     151             :   ODATA_TT_128   = X86Inst::kOpCode_CDTT_128,
+     152             :   ODATA_TT_DUP   = X86Inst::kOpCode_CDTT_DUP,
+     153             :   ODATA_TT_T4X   = X86Inst::kOpCode_CDTT_T1_4X
+     154             : };
+     155             : 
+     156             : // ============================================================================
+     157             : // [asmjit::X86Inst]
+     158             : // ============================================================================
+     159             : 
+     160             : // Instruction opcode definitions:
+     161             : //   - `O` encodes X86|MMX|SSE instructions.
+     162             : //   - `V` encodes VEX|XOP|EVEX instructions.
+     163             : #define O_ENCODE(VEX, PREFIX, OPCODE, O, L, W, EvexW, N, TT) \
+     164             :   ((PREFIX) | (OPCODE) | (O) | (L) | (W) | (EvexW) | (N) | (TT) | \
+     165             :    (VEX && ((PREFIX) & X86Inst::kOpCode_MM_Mask) != X86Inst::kOpCode_MM_0F ? int(X86Inst::kOpCode_MM_ForceVex3) : 0))
+     166             : 
+     167             : #define O(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(0, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     168             : #define V(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(1, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     169             : 
+     170             : #define O_FPU(PREFIX, OPCODE, O) (ODATA_FPU_##PREFIX | (0x##OPCODE & 0xFFU) | ((0x##OPCODE >> 8) << X86Inst::kOpCode_FPU_2B_Shift) | ODATA_O_##O)
+     171             : 
+     172             : // Don't store `_nameDataIndex` if instruction names are disabled. Since some
+     173             : // APIs can use `_nameDataIndex` it's much safer if it's zero if it's not used.
+     174             : #if defined(ASMJIT_DISABLE_TEXT)
+     175             : # define NAME_DATA_INDEX(X) 0
+     176             : #else
+     177             : # define NAME_DATA_INDEX(X) X
+     178             : #endif
+     179             : 
+     180             : // Defines an X86/X64 instruction.
+     181             : #define INST(id, encoding, opcode0, opcode1, writeIndex, writeSize, nameDataIndex, commonDataIndex, operationDataIndex, seeToAvxDataIndex) { \
+     182             :   uint32_t(X86Inst::kEncoding##encoding),   \
+     183             :   uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
+     184             :   uint32_t(commonDataIndex),                \
+     185             :   uint32_t(operationDataIndex),             \
+     186             :   uint32_t(seeToAvxDataIndex),              \
+     187             :   0,                                        \
+     188             :   opcode0                                   \
+     189             : }
+     190             : const X86Inst X86InstDB::instData[] = {
+     191             :   // <-----------------+--------------------+------------------+--------+------------------+--------+-------+-----+----+----+---+
+     192             :   //                   |                    |    Main OpCode   |#0 EVEX |Alternative OpCode|#1 EVEX | Write |     |    |    |Sse|
+     193             :   //    Instruction    |   Inst. Encoding   |                  +--------+                  +--------+---+---+NameX|ComX|OpnX|<->|
+     194             :   //                   |                    |#0:PP-MMM OP/O L|W|W|N|TT. |#1:PP-MMM OP/O L|W|W|N|TT. |Idx|Cnt|     |    |    |Avx|
+     195             :   // <-----------------+--------------------+------------------+--------+------------------+--------+---+---+-----+----+----+---+
+     196             :   // ${instData:Begin}
+     197             :   INST(None            , None               , 0                         , 0                         , 0 , 0 , 0   , 0  , 0  , 0 ),
+     198             :   INST(Aaa             , X86Op_xAX          , O(000000,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1   , 1  , 1  , 0 ),
+     199             :   INST(Aad             , X86I_xAX           , O(000000,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5   , 2  , 1  , 0 ),
+     200             :   INST(Aam             , X86I_xAX           , O(000000,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9   , 2  , 1  , 0 ),
+     201             :   INST(Aas             , X86Op_xAX          , O(000000,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 13  , 1  , 1  , 0 ),
+     202             :   INST(Adc             , X86Arith           , O(000000,10,2,_,x,_,_,_  ), 0                         , 0 , 0 , 17  , 3  , 2  , 0 ),
+     203             :   INST(Adcx            , X86Rm              , O(660F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 21  , 4  , 3  , 0 ),
+     204             :   INST(Add             , X86Arith           , O(000000,00,0,_,x,_,_,_  ), 0                         , 0 , 0 , 732 , 3  , 1  , 0 ),
+     205             :   INST(Addpd           , ExtRm              , O(660F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4619, 5  , 4  , 1 ),
+     206             :   INST(Addps           , ExtRm              , O(000F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4631, 5  , 5  , 1 ),
+     207             :   INST(Addsd           , ExtRm              , O(F20F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4853, 6  , 4  , 1 ),
+     208             :   INST(Addss           , ExtRm              , O(F30F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4863, 7  , 5  , 1 ),
+     209             :   INST(Addsubpd        , ExtRm              , O(660F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4358, 5  , 6  , 1 ),
+     210             :   INST(Addsubps        , ExtRm              , O(F20F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4370, 5  , 6  , 1 ),
+     211             :   INST(Adox            , X86Rm              , O(F30F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 26  , 4  , 7  , 0 ),
+     212             :   INST(Aesdec          , ExtRm              , O(660F38,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2854, 5  , 8  , 2 ),
+     213             :   INST(Aesdeclast      , ExtRm              , O(660F38,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2862, 5  , 8  , 2 ),
+     214             :   INST(Aesenc          , ExtRm              , O(660F38,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2874, 5  , 8  , 2 ),
+     215             :   INST(Aesenclast      , ExtRm              , O(660F38,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2882, 5  , 8  , 2 ),
+     216             :   INST(Aesimc          , ExtRm              , O(660F38,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2894, 8  , 8  , 3 ),
+     217             :   INST(Aeskeygenassist , ExtRmi             , O(660F3A,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2902, 9  , 8  , 3 ),
+     218             :   INST(And             , X86Arith           , O(000000,20,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2317, 10 , 1  , 0 ),
+     219             :   INST(Andn            , VexRvm_Wx          , V(000F38,F2,_,0,x,_,_,_  ), 0                         , 0 , 0 , 6150, 11 , 9  , 0 ),
+     220             :   INST(Andnpd          , ExtRm              , O(660F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2935, 5  , 4  , 2 ),
+     221             :   INST(Andnps          , ExtRm              , O(000F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2943, 5  , 5  , 2 ),
+     222             :   INST(Andpd           , ExtRm              , O(660F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3872, 12 , 4  , 2 ),
+     223             :   INST(Andps           , ExtRm              , O(000F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3882, 12 , 5  , 2 ),
+     224             :   INST(Arpl            , X86Mr_NoSize       , O(000000,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 31  , 13 , 10 , 0 ),
+     225             :   INST(Bextr           , VexRmv_Wx          , V(000F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 36  , 14 , 9  , 0 ),
+     226             :   INST(Blcfill         , VexVm_Wx           , V(XOP_M9,01,1,0,x,_,_,_  ), 0                         , 0 , 0 , 42  , 15 , 11 , 0 ),
+     227             :   INST(Blci            , VexVm_Wx           , V(XOP_M9,02,6,0,x,_,_,_  ), 0                         , 0 , 0 , 50  , 15 , 11 , 0 ),
+     228             :   INST(Blcic           , VexVm_Wx           , V(XOP_M9,01,5,0,x,_,_,_  ), 0                         , 0 , 0 , 55  , 15 , 11 , 0 ),
+     229             :   INST(Blcmsk          , VexVm_Wx           , V(XOP_M9,02,1,0,x,_,_,_  ), 0                         , 0 , 0 , 61  , 15 , 11 , 0 ),
+     230             :   INST(Blcs            , VexVm_Wx           , V(XOP_M9,01,3,0,x,_,_,_  ), 0                         , 0 , 0 , 68  , 15 , 11 , 0 ),
+     231             :   INST(Blendpd         , ExtRmi             , O(660F3A,0D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3021, 16 , 12 , 4 ),
+     232             :   INST(Blendps         , ExtRmi             , O(660F3A,0C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3030, 16 , 12 , 4 ),
+     233             :   INST(Blendvpd        , ExtRm_XMM0         , O(660F38,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3039, 17 , 12 , 5 ),
+     234             :   INST(Blendvps        , ExtRm_XMM0         , O(660F38,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3049, 17 , 12 , 5 ),
+     235             :   INST(Blsfill         , VexVm_Wx           , V(XOP_M9,01,2,0,x,_,_,_  ), 0                         , 0 , 0 , 73  , 15 , 11 , 0 ),
+     236             :   INST(Blsi            , VexVm_Wx           , V(000F38,F3,3,0,x,_,_,_  ), 0                         , 0 , 0 , 81  , 15 , 9  , 0 ),
+     237             :   INST(Blsic           , VexVm_Wx           , V(XOP_M9,01,6,0,x,_,_,_  ), 0                         , 0 , 0 , 86  , 15 , 11 , 0 ),
+     238             :   INST(Blsmsk          , VexVm_Wx           , V(000F38,F3,2,0,x,_,_,_  ), 0                         , 0 , 0 , 92  , 15 , 9  , 0 ),
+     239             :   INST(Blsr            , VexVm_Wx           , V(000F38,F3,1,0,x,_,_,_  ), 0                         , 0 , 0 , 99  , 15 , 9  , 0 ),
+     240             :   INST(Bndcl           , X86Rm              , O(F30F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 104 , 18 , 13 , 0 ),
+     241             :   INST(Bndcn           , X86Rm              , O(F20F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 110 , 18 , 13 , 0 ),
+     242             :   INST(Bndcu           , X86Rm              , O(F20F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 116 , 18 , 13 , 0 ),
+     243             :   INST(Bndldx          , X86Rm              , O(000F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 122 , 19 , 13 , 0 ),
+     244             :   INST(Bndmk           , X86Rm              , O(F30F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 129 , 20 , 13 , 0 ),
+     245             :   INST(Bndmov          , X86Bndmov          , O(660F00,1A,_,_,_,_,_,_  ), O(660F00,1B,_,_,_,_,_,_  ), 0 , 0 , 135 , 21 , 13 , 0 ),
+     246             :   INST(Bndstx          , X86Mr              , O(000F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 142 , 22 , 13 , 0 ),
+     247             :   INST(Bound           , X86Rm              , O(000000,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 149 , 23 , 0  , 0 ),
+     248             :   INST(Bsf             , X86Rm              , O(000F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 155 , 24 , 1  , 0 ),
+     249             :   INST(Bsr             , X86Rm              , O(000F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 159 , 24 , 1  , 0 ),
+     250             :   INST(Bswap           , X86Bswap           , O(000F00,C8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 163 , 25 , 0  , 0 ),
+     251             :   INST(Bt              , X86Bt              , O(000F00,A3,_,_,x,_,_,_  ), O(000F00,BA,4,_,x,_,_,_  ), 0 , 0 , 169 , 26 , 14 , 0 ),
+     252             :   INST(Btc             , X86Bt              , O(000F00,BB,_,_,x,_,_,_  ), O(000F00,BA,7,_,x,_,_,_  ), 0 , 0 , 172 , 27 , 14 , 0 ),
+     253             :   INST(Btr             , X86Bt              , O(000F00,B3,_,_,x,_,_,_  ), O(000F00,BA,6,_,x,_,_,_  ), 0 , 0 , 176 , 28 , 14 , 0 ),
+     254             :   INST(Bts             , X86Bt              , O(000F00,AB,_,_,x,_,_,_  ), O(000F00,BA,5,_,x,_,_,_  ), 0 , 0 , 180 , 29 , 14 , 0 ),
+     255             :   INST(Bzhi            , VexRmv_Wx          , V(000F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 184 , 14 , 15 , 0 ),
+     256             :   INST(Call            , X86Call            , O(000000,FF,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2713, 30 , 16 , 0 ),
+     257             :   INST(Cbw             , X86Op_xAX          , O(660000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 189 , 31 , 0  , 0 ),
+     258             :   INST(Cdq             , X86Op_xDX_xAX      , O(000000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 193 , 32 , 0  , 0 ),
+     259             :   INST(Cdqe            , X86Op_xAX          , O(000000,98,_,_,1,_,_,_  ), 0                         , 0 , 0 , 197 , 33 , 0  , 0 ),
+     260             :   INST(Clac            , X86Op              , O(000F01,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 202 , 34 , 17 , 0 ),
+     261             :   INST(Clc             , X86Op              , O(000000,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 207 , 34 , 18 , 0 ),
+     262             :   INST(Cld             , X86Op              , O(000000,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 211 , 34 , 19 , 0 ),
+     263             :   INST(Clflush         , X86M_Only          , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 215 , 35 , 20 , 0 ),
+     264             :   INST(Clflushopt      , X86M_Only          , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 223 , 35 , 21 , 0 ),
+     265             :   INST(Cli             , X86Op              , O(000000,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 234 , 34 , 22 , 0 ),
+     266             :   INST(Clts            , X86Op              , O(000F00,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 238 , 34 , 23 , 0 ),
+     267             :   INST(Clwb            , X86M_Only          , O(660F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 243 , 35 , 24 , 0 ),
+     268             :   INST(Clzero          , X86Op_ZAX          , O(000F01,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 248 , 36 , 25 , 0 ),
+     269             :   INST(Cmc             , X86Op              , O(000000,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 255 , 34 , 26 , 0 ),
+     270             :   INST(Cmova           , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 259 , 24 , 27 , 0 ),
+     271             :   INST(Cmovae          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 265 , 24 , 28 , 0 ),
+     272             :   INST(Cmovb           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 589 , 24 , 28 , 0 ),
+     273             :   INST(Cmovbe          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 596 , 24 , 27 , 0 ),
+     274             :   INST(Cmovc           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 272 , 24 , 28 , 0 ),
+     275             :   INST(Cmove           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 604 , 24 , 29 , 0 ),
+     276             :   INST(Cmovg           , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 278 , 24 , 30 , 0 ),
+     277             :   INST(Cmovge          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 284 , 24 , 31 , 0 ),
+     278             :   INST(Cmovl           , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 291 , 24 , 31 , 0 ),
+     279             :   INST(Cmovle          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 297 , 24 , 30 , 0 ),
+     280             :   INST(Cmovna          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 304 , 24 , 27 , 0 ),
+     281             :   INST(Cmovnae         , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 311 , 24 , 28 , 0 ),
+     282             :   INST(Cmovnb          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 611 , 24 , 28 , 0 ),
+     283             :   INST(Cmovnbe         , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 619 , 24 , 27 , 0 ),
+     284             :   INST(Cmovnc          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 319 , 24 , 28 , 0 ),
+     285             :   INST(Cmovne          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 628 , 24 , 29 , 0 ),
+     286             :   INST(Cmovng          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 326 , 24 , 30 , 0 ),
+     287             :   INST(Cmovnge         , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 333 , 24 , 31 , 0 ),
+     288             :   INST(Cmovnl          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 341 , 24 , 31 , 0 ),
+     289             :   INST(Cmovnle         , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 348 , 24 , 30 , 0 ),
+     290             :   INST(Cmovno          , X86Rm              , O(000F00,41,_,_,x,_,_,_  ), 0                         , 0 , 0 , 356 , 24 , 32 , 0 ),
+     291             :   INST(Cmovnp          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 363 , 24 , 33 , 0 ),
+     292             :   INST(Cmovns          , X86Rm              , O(000F00,49,_,_,x,_,_,_  ), 0                         , 0 , 0 , 370 , 24 , 34 , 0 ),
+     293             :   INST(Cmovnz          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 377 , 24 , 29 , 0 ),
+     294             :   INST(Cmovo           , X86Rm              , O(000F00,40,_,_,x,_,_,_  ), 0                         , 0 , 0 , 384 , 24 , 32 , 0 ),
+     295             :   INST(Cmovp           , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 390 , 24 , 33 , 0 ),
+     296             :   INST(Cmovpe          , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 396 , 24 , 33 , 0 ),
+     297             :   INST(Cmovpo          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 403 , 24 , 33 , 0 ),
+     298             :   INST(Cmovs           , X86Rm              , O(000F00,48,_,_,x,_,_,_  ), 0                         , 0 , 0 , 410 , 24 , 34 , 0 ),
+     299             :   INST(Cmovz           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 416 , 24 , 29 , 0 ),
+     300             :   INST(Cmp             , X86Arith           , O(000000,38,7,_,x,_,_,_  ), 0                         , 0 , 0 , 422 , 37 , 1  , 0 ),
+     301             :   INST(Cmppd           , ExtRmi             , O(660F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3275, 16 , 4  , 6 ),
+     302             :   INST(Cmpps           , ExtRmi             , O(000F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3282, 16 , 5  , 6 ),
+     303             :   INST(Cmps            , X86StrMm           , O(000000,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 426 , 38 , 35 , 0 ),
+     304             :   INST(Cmpsd           , ExtRmi             , O(F20F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3289, 39 , 4  , 7 ),
+     305             :   INST(Cmpss           , ExtRmi             , O(F30F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3296, 40 , 5  , 7 ),
+     306             :   INST(Cmpxchg         , X86Cmpxchg         , O(000F00,B0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 431 , 41 , 36 , 0 ),
+     307             :   INST(Cmpxchg16b      , X86M_Only          , O(000F00,C7,1,_,1,_,_,_  ), 0                         , 0 , 0 , 439 , 42 , 37 , 0 ),
+     308             :   INST(Cmpxchg8b       , X86M_Only          , O(000F00,C7,1,_,_,_,_,_  ), 0                         , 0 , 0 , 450 , 43 , 38 , 0 ),
+     309             :   INST(Comisd          , ExtRm              , O(660F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9371, 44 , 39 , 8 ),
+     310             :   INST(Comiss          , ExtRm              , O(000F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9380, 45 , 40 , 8 ),
+     311             :   INST(Cpuid           , X86Op              , O(000F00,A2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 460 , 46 , 41 , 0 ),
+     312             :   INST(Cqo             , X86Op_xDX_xAX      , O(000000,99,_,_,1,_,_,_  ), 0                         , 0 , 0 , 466 , 47 , 0  , 0 ),
+     313             :   INST(Crc32           , X86Crc             , O(F20F38,F0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 470 , 48 , 42 , 0 ),
+     314             :   INST(Cvtdq2pd        , ExtRm              , O(F30F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3343, 49 , 4  , 9 ),
+     315             :   INST(Cvtdq2ps        , ExtRm              , O(000F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3353, 50 , 4  , 9 ),
+     316             :   INST(Cvtpd2dq        , ExtRm              , O(F20F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3363, 50 , 4  , 9 ),
+     317             :   INST(Cvtpd2pi        , ExtRm              , O(660F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 476 , 51 , 4  , 0 ),
+     318             :   INST(Cvtpd2ps        , ExtRm              , O(660F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3373, 50 , 4  , 10),
+     319             :   INST(Cvtpi2pd        , ExtRm              , O(660F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 485 , 52 , 4  , 0 ),
+     320             :   INST(Cvtpi2ps        , ExtRm              , O(000F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 494 , 53 , 5  , 0 ),
+     321             :   INST(Cvtps2dq        , ExtRm              , O(660F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3425, 50 , 4  , 8 ),
+     322             :   INST(Cvtps2pd        , ExtRm              , O(000F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3435, 49 , 4  , 8 ),
+     323             :   INST(Cvtps2pi        , ExtRm              , O(000F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 503 , 54 , 5  , 0 ),
+     324             :   INST(Cvtsd2si        , ExtRm_Wx           , O(F20F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3507, 55 , 4  , 11),
+     325             :   INST(Cvtsd2ss        , ExtRm              , O(F20F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 3517, 56 , 4  , 12),
+     326             :   INST(Cvtsi2sd        , ExtRm_Wx           , O(F20F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3538, 57 , 4  , 13),
+     327             :   INST(Cvtsi2ss        , ExtRm_Wx           , O(F30F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 4 , 3548, 58 , 5  , 13),
+     328             :   INST(Cvtss2sd        , ExtRm              , O(F30F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 3558, 59 , 4  , 13),
+     329             :   INST(Cvtss2si        , ExtRm_Wx           , O(F30F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3568, 60 , 5  , 14),
+     330             :   INST(Cvttpd2dq       , ExtRm              , O(660F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3589, 50 , 4  , 15),
+     331             :   INST(Cvttpd2pi       , ExtRm              , O(660F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 512 , 51 , 4  , 0 ),
+     332             :   INST(Cvttps2dq       , ExtRm              , O(F30F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3635, 50 , 4  , 16),
+     333             :   INST(Cvttps2pi       , ExtRm              , O(000F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 522 , 54 , 5  , 0 ),
+     334             :   INST(Cvttsd2si       , ExtRm_Wx           , O(F20F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3681, 55 , 4  , 17),
+     335             :   INST(Cvttss2si       , ExtRm_Wx           , O(F30F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3704, 60 , 5  , 18),
+     336             :   INST(Cwd             , X86Op_xDX_xAX      , O(660000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 532 , 61 , 0  , 0 ),
+     337             :   INST(Cwde            , X86Op_xAX          , O(000000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 536 , 62 , 0  , 0 ),
+     338             :   INST(Daa             , X86Op              , O(000000,27,_,_,_,_,_,_  ), 0                         , 0 , 0 , 541 , 1  , 1  , 0 ),
+     339             :   INST(Das             , X86Op              , O(000000,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 545 , 1  , 1  , 0 ),
+     340             :   INST(Dec             , X86IncDec          , O(000000,FE,1,_,x,_,_,_  ), O(000000,48,_,_,x,_,_,_  ), 0 , 0 , 2857, 63 , 43 , 0 ),
+     341             :   INST(Div             , X86M_GPB_MulDiv    , O(000000,F6,6,_,x,_,_,_  ), 0                         , 0 , 0 , 751 , 64 , 1  , 0 ),
+     342             :   INST(Divpd           , ExtRm              , O(660F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3803, 5  , 4  , 19),
+     343             :   INST(Divps           , ExtRm              , O(000F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3810, 5  , 5  , 19),
+     344             :   INST(Divsd           , ExtRm              , O(F20F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3817, 6  , 4  , 19),
+     345             :   INST(Divss           , ExtRm              , O(F30F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3824, 7  , 5  , 19),
+     346             :   INST(Dppd            , ExtRmi             , O(660F3A,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3831, 16 , 12 , 19),
+     347             :   INST(Dpps            , ExtRmi             , O(660F3A,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3837, 16 , 12 , 19),
+     348             :   INST(Emms            , X86Op              , O(000F00,77,_,_,_,_,_,_  ), 0                         , 0 , 0 , 719 , 65 , 44 , 0 ),
+     349             :   INST(Enter           , X86Enter           , O(000000,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2721, 66 , 45 , 0 ),
+     350             :   INST(Extractps       , ExtExtract         , O(660F3A,17,_,_,_,_,_,_  ), 0                         , 0 , 8 , 4027, 67 , 12 , 20),
+     351             :   INST(Extrq           , ExtExtrq           , O(660F00,79,_,_,_,_,_,_  ), O(660F00,78,0,_,_,_,_,_  ), 0 , 0 , 6864, 68 , 46 , 0 ),
+     352             :   INST(F2xm1           , FpuOp              , O_FPU(00,D9F0,_)          , 0                         , 0 , 0 , 549 , 34 , 47 , 0 ),
+     353             :   INST(Fabs            , FpuOp              , O_FPU(00,D9E1,_)          , 0                         , 0 , 0 , 555 , 34 , 47 , 0 ),
+     354             :   INST(Fadd            , FpuArith           , O_FPU(00,C0C0,0)          , 0                         , 0 , 0 , 1957, 69 , 47 , 0 ),
+     355             :   INST(Faddp           , FpuRDef            , O_FPU(00,DEC0,_)          , 0                         , 0 , 0 , 560 , 70 , 47 , 0 ),
+     356             :   INST(Fbld            , X86M_Only          , O_FPU(00,00DF,4)          , 0                         , 0 , 0 , 566 , 71 , 47 , 0 ),
+     357             :   INST(Fbstp           , X86M_Only          , O_FPU(00,00DF,6)          , 0                         , 0 , 0 , 571 , 72 , 47 , 0 ),
+     358             :   INST(Fchs            , FpuOp              , O_FPU(00,D9E0,_)          , 0                         , 0 , 0 , 577 , 34 , 47 , 0 ),
+     359             :   INST(Fclex           , FpuOp              , O_FPU(9B,DBE2,_)          , 0                         , 0 , 0 , 582 , 34 , 47 , 0 ),
+     360             :   INST(Fcmovb          , FpuR               , O_FPU(00,DAC0,_)          , 0                         , 0 , 0 , 588 , 73 , 48 , 0 ),
+     361             :   INST(Fcmovbe         , FpuR               , O_FPU(00,DAD0,_)          , 0                         , 0 , 0 , 595 , 73 , 48 , 0 ),
+     362             :   INST(Fcmove          , FpuR               , O_FPU(00,DAC8,_)          , 0                         , 0 , 0 , 603 , 73 , 48 , 0 ),
+     363             :   INST(Fcmovnb         , FpuR               , O_FPU(00,DBC0,_)          , 0                         , 0 , 0 , 610 , 73 , 48 , 0 ),
+     364             :   INST(Fcmovnbe        , FpuR               , O_FPU(00,DBD0,_)          , 0                         , 0 , 0 , 618 , 73 , 48 , 0 ),
+     365             :   INST(Fcmovne         , FpuR               , O_FPU(00,DBC8,_)          , 0                         , 0 , 0 , 627 , 73 , 48 , 0 ),
+     366             :   INST(Fcmovnu         , FpuR               , O_FPU(00,DBD8,_)          , 0                         , 0 , 0 , 635 , 73 , 48 , 0 ),
+     367             :   INST(Fcmovu          , FpuR               , O_FPU(00,DAD8,_)          , 0                         , 0 , 0 , 643 , 73 , 48 , 0 ),
+     368             :   INST(Fcom            , FpuCom             , O_FPU(00,D0D0,2)          , 0                         , 0 , 0 , 650 , 74 , 47 , 0 ),
+     369             :   INST(Fcomi           , FpuR               , O_FPU(00,DBF0,_)          , 0                         , 0 , 0 , 655 , 75 , 49 , 0 ),
+     370             :   INST(Fcomip          , FpuR               , O_FPU(00,DFF0,_)          , 0                         , 0 , 0 , 661 , 75 , 49 , 0 ),
+     371             :   INST(Fcomp           , FpuCom             , O_FPU(00,D8D8,3)          , 0                         , 0 , 0 , 668 , 74 , 47 , 0 ),
+     372             :   INST(Fcompp          , FpuOp              , O_FPU(00,DED9,_)          , 0                         , 0 , 0 , 674 , 34 , 47 , 0 ),
+     373             :   INST(Fcos            , FpuOp              , O_FPU(00,D9FF,_)          , 0                         , 0 , 0 , 681 , 34 , 47 , 0 ),
+     374             :   INST(Fdecstp         , FpuOp              , O_FPU(00,D9F6,_)          , 0                         , 0 , 0 , 686 , 34 , 47 , 0 ),
+     375             :   INST(Fdiv            , FpuArith           , O_FPU(00,F0F8,6)          , 0                         , 0 , 0 , 694 , 69 , 47 , 0 ),
+     376             :   INST(Fdivp           , FpuRDef            , O_FPU(00,DEF8,_)          , 0                         , 0 , 0 , 699 , 70 , 47 , 0 ),
+     377             :   INST(Fdivr           , FpuArith           , O_FPU(00,F8F0,7)          , 0                         , 0 , 0 , 705 , 69 , 47 , 0 ),
+     378             :   INST(Fdivrp          , FpuRDef            , O_FPU(00,DEF0,_)          , 0                         , 0 , 0 , 711 , 70 , 47 , 0 ),
+     379             :   INST(Femms           , X86Op              , O(000F00,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 718 , 34 , 50 , 0 ),
+     380             :   INST(Ffree           , FpuR               , O_FPU(00,DDC0,_)          , 0                         , 0 , 0 , 724 , 73 , 47 , 0 ),
+     381             :   INST(Fiadd           , FpuM               , O_FPU(00,00DA,0)          , 0                         , 0 , 0 , 730 , 76 , 47 , 0 ),
+     382             :   INST(Ficom           , FpuM               , O_FPU(00,00DA,2)          , 0                         , 0 , 0 , 736 , 76 , 47 , 0 ),
+     383             :   INST(Ficomp          , FpuM               , O_FPU(00,00DA,3)          , 0                         , 0 , 0 , 742 , 76 , 47 , 0 ),
+     384             :   INST(Fidiv           , FpuM               , O_FPU(00,00DA,6)          , 0                         , 0 , 0 , 749 , 76 , 47 , 0 ),
+     385             :   INST(Fidivr          , FpuM               , O_FPU(00,00DA,7)          , 0                         , 0 , 0 , 755 , 76 , 47 , 0 ),
+     386             :   INST(Fild            , FpuM               , O_FPU(00,00DB,0)          , O_FPU(00,00DF,5)          , 0 , 0 , 762 , 77 , 47 , 0 ),
+     387             :   INST(Fimul           , FpuM               , O_FPU(00,00DA,1)          , 0                         , 0 , 0 , 767 , 76 , 47 , 0 ),
+     388             :   INST(Fincstp         , FpuOp              , O_FPU(00,D9F7,_)          , 0                         , 0 , 0 , 773 , 34 , 47 , 0 ),
+     389             :   INST(Finit           , FpuOp              , O_FPU(9B,DBE3,_)          , 0                         , 0 , 0 , 781 , 34 , 47 , 0 ),
+     390             :   INST(Fist            , FpuM               , O_FPU(00,00DB,2)          , 0                         , 0 , 0 , 787 , 78 , 47 , 0 ),
+     391             :   INST(Fistp           , FpuM               , O_FPU(00,00DB,3)          , O_FPU(00,00DF,7)          , 0 , 0 , 792 , 79 , 47 , 0 ),
+     392             :   INST(Fisttp          , FpuM               , O_FPU(00,00DB,1)          , O_FPU(00,00DD,1)          , 0 , 0 , 798 , 80 , 51 , 0 ),
+     393             :   INST(Fisub           , FpuM               , O_FPU(00,00DA,4)          , 0                         , 0 , 0 , 805 , 76 , 47 , 0 ),
+     394             :   INST(Fisubr          , FpuM               , O_FPU(00,00DA,5)          , 0                         , 0 , 0 , 811 , 76 , 47 , 0 ),
+     395             :   INST(Fld             , FpuFldFst          , O_FPU(00,00D9,0)          , O_FPU(00,00DB,5)          , 0 , 0 , 818 , 81 , 47 , 0 ),
+     396             :   INST(Fld1            , FpuOp              , O_FPU(00,D9E8,_)          , 0                         , 0 , 0 , 822 , 34 , 47 , 0 ),
+     397             :   INST(Fldcw           , X86M_Only          , O_FPU(00,00D9,5)          , 0                         , 0 , 0 , 827 , 82 , 47 , 0 ),
+     398             :   INST(Fldenv          , X86M_Only          , O_FPU(00,00D9,4)          , 0                         , 0 , 0 , 833 , 35 , 47 , 0 ),
+     399             :   INST(Fldl2e          , FpuOp              , O_FPU(00,D9EA,_)          , 0                         , 0 , 0 , 840 , 34 , 47 , 0 ),
+     400             :   INST(Fldl2t          , FpuOp              , O_FPU(00,D9E9,_)          , 0                         , 0 , 0 , 847 , 34 , 47 , 0 ),
+     401             :   INST(Fldlg2          , FpuOp              , O_FPU(00,D9EC,_)          , 0                         , 0 , 0 , 854 , 34 , 47 , 0 ),
+     402             :   INST(Fldln2          , FpuOp              , O_FPU(00,D9ED,_)          , 0                         , 0 , 0 , 861 , 34 , 47 , 0 ),
+     403             :   INST(Fldpi           , FpuOp              , O_FPU(00,D9EB,_)          , 0                         , 0 , 0 , 868 , 34 , 47 , 0 ),
+     404             :   INST(Fldz            , FpuOp              , O_FPU(00,D9EE,_)          , 0                         , 0 , 0 , 874 , 34 , 47 , 0 ),
+     405             :   INST(Fmul            , FpuArith           , O_FPU(00,C8C8,1)          , 0                         , 0 , 0 , 1999, 83 , 47 , 0 ),
+     406             :   INST(Fmulp           , FpuRDef            , O_FPU(00,DEC8,_)          , 0                         , 0 , 0 , 879 , 70 , 47 , 0 ),
+     407             :   INST(Fnclex          , FpuOp              , O_FPU(00,DBE2,_)          , 0                         , 0 , 0 , 885 , 34 , 47 , 0 ),
+     408             :   INST(Fninit          , FpuOp              , O_FPU(00,DBE3,_)          , 0                         , 0 , 0 , 892 , 34 , 47 , 0 ),
+     409             :   INST(Fnop            , FpuOp              , O_FPU(00,D9D0,_)          , 0                         , 0 , 0 , 899 , 34 , 47 , 0 ),
+     410             :   INST(Fnsave          , X86M_Only          , O_FPU(00,00DD,6)          , 0                         , 0 , 0 , 904 , 84 , 47 , 0 ),
+     411             :   INST(Fnstcw          , X86M_Only          , O_FPU(00,00D9,7)          , 0                         , 0 , 0 , 911 , 85 , 47 , 0 ),
+     412             :   INST(Fnstenv         , X86M_Only          , O_FPU(00,00D9,6)          , 0                         , 0 , 0 , 918 , 84 , 47 , 0 ),
+     413             :   INST(Fnstsw          , FpuStsw            , O_FPU(00,00DD,7)          , O_FPU(00,DFE0,_)          , 0 , 0 , 926 , 86 , 47 , 0 ),
+     414             :   INST(Fpatan          , FpuOp              , O_FPU(00,D9F3,_)          , 0                         , 0 , 0 , 933 , 34 , 47 , 0 ),
+     415             :   INST(Fprem           , FpuOp              , O_FPU(00,D9F8,_)          , 0                         , 0 , 0 , 940 , 34 , 47 , 0 ),
+     416             :   INST(Fprem1          , FpuOp              , O_FPU(00,D9F5,_)          , 0                         , 0 , 0 , 946 , 34 , 47 , 0 ),
+     417             :   INST(Fptan           , FpuOp              , O_FPU(00,D9F2,_)          , 0                         , 0 , 0 , 953 , 34 , 47 , 0 ),
+     418             :   INST(Frndint         , FpuOp              , O_FPU(00,D9FC,_)          , 0                         , 0 , 0 , 959 , 34 , 47 , 0 ),
+     419             :   INST(Frstor          , X86M_Only          , O_FPU(00,00DD,4)          , 0                         , 0 , 0 , 967 , 35 , 47 , 0 ),
+     420             :   INST(Fsave           , X86M_Only          , O_FPU(9B,00DD,6)          , 0                         , 0 , 0 , 974 , 84 , 47 , 0 ),
+     421             :   INST(Fscale          , FpuOp              , O_FPU(00,D9FD,_)          , 0                         , 0 , 0 , 980 , 34 , 47 , 0 ),
+     422             :   INST(Fsin            , FpuOp              , O_FPU(00,D9FE,_)          , 0                         , 0 , 0 , 987 , 34 , 47 , 0 ),
+     423             :   INST(Fsincos         , FpuOp              , O_FPU(00,D9FB,_)          , 0                         , 0 , 0 , 992 , 34 , 47 , 0 ),
+     424             :   INST(Fsqrt           , FpuOp              , O_FPU(00,D9FA,_)          , 0                         , 0 , 0 , 1000, 34 , 47 , 0 ),
+     425             :   INST(Fst             , FpuFldFst          , O_FPU(00,00D9,2)          , 0                         , 0 , 0 , 1006, 87 , 47 , 0 ),
+     426             :   INST(Fstcw           , X86M_Only          , O_FPU(9B,00D9,7)          , 0                         , 0 , 0 , 1010, 85 , 47 , 0 ),
+     427             :   INST(Fstenv          , X86M_Only          , O_FPU(9B,00D9,6)          , 0                         , 0 , 0 , 1016, 84 , 47 , 0 ),
+     428             :   INST(Fstp            , FpuFldFst          , O_FPU(00,00D9,3)          , O(000000,DB,7,_,_,_,_,_  ), 0 , 0 , 1023, 88 , 47 , 0 ),
+     429             :   INST(Fstsw           , FpuStsw            , O_FPU(9B,00DD,7)          , O_FPU(9B,DFE0,_)          , 0 , 0 , 1028, 89 , 47 , 0 ),
+     430             :   INST(Fsub            , FpuArith           , O_FPU(00,E0E8,4)          , 0                         , 0 , 0 , 2077, 69 , 47 , 0 ),
+     431             :   INST(Fsubp           , FpuRDef            , O_FPU(00,DEE8,_)          , 0                         , 0 , 0 , 1034, 70 , 47 , 0 ),
+     432             :   INST(Fsubr           , FpuArith           , O_FPU(00,E8E0,5)          , 0                         , 0 , 0 , 2083, 69 , 47 , 0 ),
+     433             :   INST(Fsubrp          , FpuRDef            , O_FPU(00,DEE0,_)          , 0                         , 0 , 0 , 1040, 70 , 47 , 0 ),
+     434             :   INST(Ftst            , FpuOp              , O_FPU(00,D9E4,_)          , 0                         , 0 , 0 , 1047, 34 , 47 , 0 ),
+     435             :   INST(Fucom           , FpuRDef            , O_FPU(00,DDE0,_)          , 0                         , 0 , 0 , 1052, 90 , 47 , 0 ),
+     436             :   INST(Fucomi          , FpuR               , O_FPU(00,DBE8,_)          , 0                         , 0 , 0 , 1058, 75 , 49 , 0 ),
+     437             :   INST(Fucomip         , FpuR               , O_FPU(00,DFE8,_)          , 0                         , 0 , 0 , 1065, 75 , 49 , 0 ),
+     438             :   INST(Fucomp          , FpuRDef            , O_FPU(00,DDE8,_)          , 0                         , 0 , 0 , 1073, 90 , 47 , 0 ),
+     439             :   INST(Fucompp         , FpuOp              , O_FPU(00,DAE9,_)          , 0                         , 0 , 0 , 1080, 34 , 47 , 0 ),
+     440             :   INST(Fwait           , X86Op              , O_FPU(00,00DB,_)          , 0                         , 0 , 0 , 1088, 34 , 47 , 0 ),
+     441             :   INST(Fxam            , FpuOp              , O_FPU(00,D9E5,_)          , 0                         , 0 , 0 , 1094, 34 , 47 , 0 ),
+     442             :   INST(Fxch            , FpuR               , O_FPU(00,D9C8,_)          , 0                         , 0 , 0 , 1099, 70 , 47 , 0 ),
+     443             :   INST(Fxrstor         , X86M_Only          , O(000F00,AE,1,_,_,_,_,_  ), 0                         , 0 , 0 , 1104, 35 , 52 , 0 ),
+     444             :   INST(Fxrstor64       , X86M_Only          , O(000F00,AE,1,_,1,_,_,_  ), 0                         , 0 , 0 , 1112, 91 , 52 , 0 ),
+     445             :   INST(Fxsave          , X86M_Only          , O(000F00,AE,0,_,_,_,_,_  ), 0                         , 0 , 0 , 1122, 84 , 53 , 0 ),
+     446             :   INST(Fxsave64        , X86M_Only          , O(000F00,AE,0,_,1,_,_,_  ), 0                         , 0 , 0 , 1129, 92 , 53 , 0 ),
+     447             :   INST(Fxtract         , FpuOp              , O_FPU(00,D9F4,_)          , 0                         , 0 , 0 , 1138, 34 , 47 , 0 ),
+     448             :   INST(Fyl2x           , FpuOp              , O_FPU(00,D9F1,_)          , 0                         , 0 , 0 , 1146, 34 , 47 , 0 ),
+     449             :   INST(Fyl2xp1         , FpuOp              , O_FPU(00,D9F9,_)          , 0                         , 0 , 0 , 1152, 34 , 47 , 0 ),
+     450             :   INST(Haddpd          , ExtRm              , O(660F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5382, 5  , 6  , 21),
+     451             :   INST(Haddps          , ExtRm              , O(F20F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5390, 5  , 6  , 21),
+     452             :   INST(Hlt             , X86Op              , O(000000,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1160, 34 , 23 , 0 ),
+     453             :   INST(Hsubpd          , ExtRm              , O(660F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5398, 5  , 6  , 22),
+     454             :   INST(Hsubps          , ExtRm              , O(F20F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5406, 5  , 6  , 22),
+     455             :   INST(Idiv            , X86M_GPB_MulDiv    , O(000000,F6,7,_,x,_,_,_  ), 0                         , 0 , 0 , 750 , 64 , 1  , 0 ),
+     456             :   INST(Imul            , X86Imul            , O(000000,F6,5,_,x,_,_,_  ), 0                         , 0 , 0 , 768 , 93 , 1  , 0 ),
+     457             :   INST(In              , X86In              , O(000000,EC,_,_,_,_,_,_  ), O(000000,E4,_,_,_,_,_,_  ), 0 , 0 , 9508, 94 , 45 , 0 ),
+     458             :   INST(Inc             , X86IncDec          , O(000000,FE,0,_,x,_,_,_  ), O(000000,40,_,_,x,_,_,_  ), 0 , 0 , 1164, 95 , 43 , 0 ),
+     459             :   INST(Ins             , X86Ins             , O(000000,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1168, 96 , 45 , 0 ),
+     460             :   INST(Insertps        , ExtRmi             , O(660F3A,21,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5542, 40 , 12 , 23),
+     461             :   INST(Insertq         , ExtInsertq         , O(F20F00,79,_,_,_,_,_,_  ), O(F20F00,78,_,_,_,_,_,_  ), 0 , 0 , 1172, 97 , 46 , 0 ),
+     462             :   INST(Int             , X86Int             , O(000000,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 963 , 98 , 45 , 0 ),
+     463             :   INST(Int3            , X86Op              , O(000000,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1180, 34 , 45 , 0 ),
+     464             :   INST(Into            , X86Op              , O(000000,CE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1185, 99 , 54 , 0 ),
+     465             :   INST(Invd            , X86Op              , O(000F00,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9463, 34 , 55 , 0 ),
+     466             :   INST(Invlpg          , X86M_Only          , O(000F00,01,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1190, 35 , 55 , 0 ),
+     467             :   INST(Invpcid         , X86Rm_NoRexW       , O(660F38,82,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1197, 100, 55 , 0 ),
+     468             :   INST(Iret            , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1205, 34 , 16 , 0 ),
+     469             :   INST(Iretd           , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1210, 34 , 16 , 0 ),
+     470             :   INST(Iretq           , X86Op              , O(000000,CF,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1216, 101, 16 , 0 ),
+     471             :   INST(Iretw           , X86Op              , O(660000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1222, 34 , 16 , 0 ),
+     472             :   INST(Ja              , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1228, 102, 56 , 0 ),
+     473             :   INST(Jae             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1231, 103, 57 , 0 ),
+     474             :   INST(Jb              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1235, 104, 57 , 0 ),
+     475             :   INST(Jbe             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1238, 105, 56 , 0 ),
+     476             :   INST(Jc              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1242, 106, 57 , 0 ),
+     477             :   INST(Je              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1245, 107, 58 , 0 ),
+     478             :   INST(Jecxz           , X86JecxzLoop       , 0                         , O(000000,E3,_,_,_,_,_,_  ), 0 , 0 , 1248, 108, 45 , 0 ),
+     479             :   INST(Jg              , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1254, 109, 59 , 0 ),
+     480             :   INST(Jge             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1257, 110, 60 , 0 ),
+     481             :   INST(Jl              , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1261, 111, 60 , 0 ),
+     482             :   INST(Jle             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1264, 112, 59 , 0 ),
+     483             :   INST(Jmp             , X86Jmp             , O(000000,FF,4,_,_,_,_,_  ), O(000000,EB,_,_,_,_,_,_  ), 0 , 0 , 1268, 113, 45 , 0 ),
+     484             :   INST(Jna             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1272, 105, 56 , 0 ),
+     485             :   INST(Jnae            , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1276, 104, 57 , 0 ),
+     486             :   INST(Jnb             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1281, 103, 57 , 0 ),
+     487             :   INST(Jnbe            , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1285, 102, 56 , 0 ),
+     488             :   INST(Jnc             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1290, 114, 57 , 0 ),
+     489             :   INST(Jne             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1294, 115, 58 , 0 ),
+     490             :   INST(Jng             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1298, 112, 59 , 0 ),
+     491             :   INST(Jnge            , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1302, 111, 60 , 0 ),
+     492             :   INST(Jnl             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1307, 110, 60 , 0 ),
+     493             :   INST(Jnle            , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1311, 109, 59 , 0 ),
+     494             :   INST(Jno             , X86Jcc             , O(000F00,81,_,_,_,_,_,_  ), O(000000,71,_,_,_,_,_,_  ), 0 , 0 , 1316, 116, 54 , 0 ),
+     495             :   INST(Jnp             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1320, 117, 61 , 0 ),
+     496             :   INST(Jns             , X86Jcc             , O(000F00,89,_,_,_,_,_,_  ), O(000000,79,_,_,_,_,_,_  ), 0 , 0 , 1324, 118, 62 , 0 ),
+     497             :   INST(Jnz             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1328, 115, 58 , 0 ),
+     498             :   INST(Jo              , X86Jcc             , O(000F00,80,_,_,_,_,_,_  ), O(000000,70,_,_,_,_,_,_  ), 0 , 0 , 1332, 119, 54 , 0 ),
+     499             :   INST(Jp              , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1335, 120, 61 , 0 ),
+     500             :   INST(Jpe             , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1338, 120, 61 , 0 ),
+     501             :   INST(Jpo             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1342, 117, 61 , 0 ),
+     502             :   INST(Js              , X86Jcc             , O(000F00,88,_,_,_,_,_,_  ), O(000000,78,_,_,_,_,_,_  ), 0 , 0 , 1346, 121, 62 , 0 ),
+     503             :   INST(Jz              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1349, 107, 58 , 0 ),
+     504             :   INST(Kaddb           , VexRvm             , V(660F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1352, 122, 63 , 0 ),
+     505             :   INST(Kaddd           , VexRvm             , V(660F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1358, 122, 64 , 0 ),
+     506             :   INST(Kaddq           , VexRvm             , V(000F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1364, 122, 64 , 0 ),
+     507             :   INST(Kaddw           , VexRvm             , V(000F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1370, 122, 63 , 0 ),
+     508             :   INST(Kandb           , VexRvm             , V(660F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1376, 122, 63 , 0 ),
+     509             :   INST(Kandd           , VexRvm             , V(660F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1382, 122, 64 , 0 ),
+     510             :   INST(Kandnb          , VexRvm             , V(660F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1388, 122, 63 , 0 ),
+     511             :   INST(Kandnd          , VexRvm             , V(660F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1395, 122, 64 , 0 ),
+     512             :   INST(Kandnq          , VexRvm             , V(000F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1402, 122, 64 , 0 ),
+     513             :   INST(Kandnw          , VexRvm             , V(000F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1409, 122, 65 , 0 ),
+     514             :   INST(Kandq           , VexRvm             , V(000F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1416, 122, 64 , 0 ),
+     515             :   INST(Kandw           , VexRvm             , V(000F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1422, 122, 65 , 0 ),
+     516             :   INST(Kmovb           , VexKmov            , V(660F00,90,_,0,0,_,_,_  ), V(660F00,92,_,0,0,_,_,_  ), 0 , 0 , 1428, 123, 63 , 0 ),
+     517             :   INST(Kmovd           , VexKmov            , V(660F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,0,_,_,_  ), 0 , 0 , 7344, 124, 64 , 0 ),
+     518             :   INST(Kmovq           , VexKmov            , V(000F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,1,_,_,_  ), 0 , 0 , 7355, 125, 64 , 0 ),
+     519             :   INST(Kmovw           , VexKmov            , V(000F00,90,_,0,0,_,_,_  ), V(000F00,92,_,0,0,_,_,_  ), 0 , 0 , 1434, 126, 65 , 0 ),
+     520             :   INST(Knotb           , VexRm              , V(660F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1440, 127, 63 , 0 ),
+     521             :   INST(Knotd           , VexRm              , V(660F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1446, 127, 64 , 0 ),
+     522             :   INST(Knotq           , VexRm              , V(000F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1452, 127, 64 , 0 ),
+     523             :   INST(Knotw           , VexRm              , V(000F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1458, 127, 65 , 0 ),
+     524             :   INST(Korb            , VexRvm             , V(660F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1464, 122, 63 , 0 ),
+     525             :   INST(Kord            , VexRvm             , V(660F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1469, 122, 64 , 0 ),
+     526             :   INST(Korq            , VexRvm             , V(000F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1474, 122, 64 , 0 ),
+     527             :   INST(Kortestb        , VexRm              , V(660F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1479, 128, 66 , 0 ),
+     528             :   INST(Kortestd        , VexRm              , V(660F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1488, 128, 67 , 0 ),
+     529             :   INST(Kortestq        , VexRm              , V(000F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1497, 128, 67 , 0 ),
+     530             :   INST(Kortestw        , VexRm              , V(000F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1506, 128, 68 , 0 ),
+     531             :   INST(Korw            , VexRvm             , V(000F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1515, 122, 65 , 0 ),
+     532             :   INST(Kshiftlb        , VexRmi             , V(660F3A,32,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1520, 129, 63 , 0 ),
+     533             :   INST(Kshiftld        , VexRmi             , V(660F3A,33,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1529, 129, 64 , 0 ),
+     534             :   INST(Kshiftlq        , VexRmi             , V(660F3A,33,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1538, 129, 64 , 0 ),
+     535             :   INST(Kshiftlw        , VexRmi             , V(660F3A,32,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1547, 129, 65 , 0 ),
+     536             :   INST(Kshiftrb        , VexRmi             , V(660F3A,30,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1556, 129, 63 , 0 ),
+     537             :   INST(Kshiftrd        , VexRmi             , V(660F3A,31,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1565, 129, 64 , 0 ),
+     538             :   INST(Kshiftrq        , VexRmi             , V(660F3A,31,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1574, 129, 64 , 0 ),
+     539             :   INST(Kshiftrw        , VexRmi             , V(660F3A,30,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1583, 129, 65 , 0 ),
+     540             :   INST(Ktestb          , VexRm              , V(660F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1592, 128, 66 , 0 ),
+     541             :   INST(Ktestd          , VexRm              , V(660F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1599, 128, 67 , 0 ),
+     542             :   INST(Ktestq          , VexRm              , V(000F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1606, 128, 67 , 0 ),
+     543             :   INST(Ktestw          , VexRm              , V(000F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1613, 128, 66 , 0 ),
+     544             :   INST(Kunpckbw        , VexRvm             , V(660F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1620, 122, 65 , 0 ),
+     545             :   INST(Kunpckdq        , VexRvm             , V(000F00,4B,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1629, 122, 64 , 0 ),
+     546             :   INST(Kunpckwd        , VexRvm             , V(000F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1638, 122, 64 , 0 ),
+     547             :   INST(Kxnorb          , VexRvm             , V(660F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1647, 122, 63 , 0 ),
+     548             :   INST(Kxnord          , VexRvm             , V(660F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1654, 122, 64 , 0 ),
+     549             :   INST(Kxnorq          , VexRvm             , V(000F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1661, 122, 64 , 0 ),
+     550             :   INST(Kxnorw          , VexRvm             , V(000F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1668, 122, 65 , 0 ),
+     551             :   INST(Kxorb           , VexRvm             , V(660F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1675, 122, 63 , 0 ),
+     552             :   INST(Kxord           , VexRvm             , V(660F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1681, 122, 64 , 0 ),
+     553             :   INST(Kxorq           , VexRvm             , V(000F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1687, 122, 64 , 0 ),
+     554             :   INST(Kxorw           , VexRvm             , V(000F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1693, 122, 65 , 0 ),
+     555             :   INST(Lahf            , X86Op              , O(000000,9F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1699, 130, 69 , 0 ),
+     556             :   INST(Lar             , X86Rm              , O(000F00,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1704, 131, 70 , 0 ),
+     557             :   INST(Lddqu           , ExtRm              , O(F20F00,F0,_,_,_,_,_,_  ), 0                         , 0 , 16, 5552, 132, 6  , 24),
+     558             :   INST(Ldmxcsr         , X86M_Only          , O(000F00,AE,2,_,_,_,_,_  ), 0                         , 0 , 0 , 5559, 133, 5  , 0 ),
+     559             :   INST(Lds             , X86Rm              , O(000000,C5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1708, 134, 45 , 0 ),
+     560             :   INST(Lea             , X86Lea             , O(000000,8D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1712, 135, 0  , 0 ),
+     561             :   INST(Leave           , X86Op              , O(000000,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1716, 34 , 45 , 0 ),
+     562             :   INST(Les             , X86Rm              , O(000000,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1722, 134, 45 , 0 ),
+     563             :   INST(Lfence          , X86Fence           , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1726, 34 , 71 , 0 ),
+     564             :   INST(Lfs             , X86Rm              , O(000F00,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1733, 136, 45 , 0 ),
+     565             :   INST(Lgdt            , X86M_Only          , O(000F00,01,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1737, 35 , 23 , 0 ),
+     566             :   INST(Lgs             , X86Rm              , O(000F00,B5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1742, 136, 45 , 0 ),
+     567             :   INST(Lidt            , X86M_Only          , O(000F00,01,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1746, 35 , 23 , 0 ),
+     568             :   INST(Lldt            , X86M               , O(000F00,00,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1751, 137, 23 , 0 ),
+     569             :   INST(Lmsw            , X86M               , O(000F00,01,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1756, 137, 23 , 0 ),
+     570             :   INST(Lods            , X86StrRm           , O(000000,AC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1761, 138, 72 , 0 ),
+     571             :   INST(Loop            , X86JecxzLoop       , 0                         , O(000000,E2,_,_,_,_,_,_  ), 0 , 0 , 1766, 139, 45 , 0 ),
+     572             :   INST(Loope           , X86JecxzLoop       , 0                         , O(000000,E1,_,_,_,_,_,_  ), 0 , 0 , 1771, 140, 58 , 0 ),
+     573             :   INST(Loopne          , X86JecxzLoop       , 0                         , O(000000,E0,_,_,_,_,_,_  ), 0 , 0 , 1777, 141, 58 , 0 ),
+     574             :   INST(Lsl             , X86Rm              , O(000F00,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1784, 142, 70 , 0 ),
+     575             :   INST(Lss             , X86Rm              , O(000F00,B2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5959, 136, 45 , 0 ),
+     576             :   INST(Ltr             , X86M               , O(000F00,00,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1788, 137, 23 , 0 ),
+     577             :   INST(Lzcnt           , X86Rm_Raw66H       , O(F30F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1792, 143, 73 , 0 ),
+     578             :   INST(Maskmovdqu      , ExtRm_ZDI          , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5568, 144, 4  , 25),
+     579             :   INST(Maskmovq        , ExtRm_ZDI          , O(000F00,F7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7352, 145, 74 , 0 ),
+     580             :   INST(Maxpd           , ExtRm              , O(660F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5602, 5  , 4  , 26),
+     581             :   INST(Maxps           , ExtRm              , O(000F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5609, 5  , 5  , 26),
+     582             :   INST(Maxsd           , ExtRm              , O(F20F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7371, 6  , 4  , 26),
+     583             :   INST(Maxss           , ExtRm              , O(F30F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5623, 7  , 5  , 26),
+     584             :   INST(Mfence          , X86Fence           , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1798, 34 , 71 , 0 ),
+     585             :   INST(Minpd           , ExtRm              , O(660F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5630, 5  , 4  , 27),
+     586             :   INST(Minps           , ExtRm              , O(000F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5637, 5  , 5  , 27),
+     587             :   INST(Minsd           , ExtRm              , O(F20F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7435, 6  , 4  , 27),
+     588             :   INST(Minss           , ExtRm              , O(F30F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5651, 7  , 5  , 27),
+     589             :   INST(Monitor         , X86Op              , O(000F01,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1805, 146, 75 , 0 ),
+     590             :   INST(Mov             , X86Mov             , 0                         , 0                         , 0 , 0 , 138 , 147, 76 , 0 ),
+     591             :   INST(Movapd          , ExtMov             , O(660F00,28,_,_,_,_,_,_  ), O(660F00,29,_,_,_,_,_,_  ), 0 , 16, 5658, 148, 4  , 28),
+     592             :   INST(Movaps          , ExtMov             , O(000F00,28,_,_,_,_,_,_  ), O(000F00,29,_,_,_,_,_,_  ), 0 , 16, 5666, 149, 5  , 28),
+     593             :   INST(Movbe           , ExtMovbe           , O(000F38,F0,_,_,x,_,_,_  ), O(000F38,F1,_,_,x,_,_,_  ), 0 , 0 , 597 , 150, 77 , 0 ),
+     594             :   INST(Movd            , ExtMovd            , O(000F00,6E,_,_,_,_,_,_  ), O(000F00,7E,_,_,_,_,_,_  ), 0 , 16, 7345, 151, 78 , 29),
+     595             :   INST(Movddup         , ExtMov             , O(F20F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5680, 49 , 6  , 29),
+     596             :   INST(Movdq2q         , ExtMov             , O(F20F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1813, 152, 4  , 0 ),
+     597             :   INST(Movdqa          , ExtMov             , O(660F00,6F,_,_,_,_,_,_  ), O(660F00,7F,_,_,_,_,_,_  ), 0 , 16, 5689, 153, 4  , 30),
+     598             :   INST(Movdqu          , ExtMov             , O(F30F00,6F,_,_,_,_,_,_  ), O(F30F00,7F,_,_,_,_,_,_  ), 0 , 16, 5572, 154, 4  , 28),
+     599             :   INST(Movhlps         , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5764, 155, 5  , 31),
+     600             :   INST(Movhpd          , ExtMov             , O(660F00,16,_,_,_,_,_,_  ), O(660F00,17,_,_,_,_,_,_  ), 8 , 8 , 5773, 156, 4  , 32),
+     601             :   INST(Movhps          , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), O(000F00,17,_,_,_,_,_,_  ), 8 , 8 , 5781, 157, 5  , 32),
+     602             :   INST(Movlhps         , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), 0                         , 8 , 8 , 5789, 158, 5  , 31),
+     603             :   INST(Movlpd          , ExtMov             , O(660F00,12,_,_,_,_,_,_  ), O(660F00,13,_,_,_,_,_,_  ), 0 , 8 , 5798, 159, 4  , 32),
+     604             :   INST(Movlps          , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), O(000F00,13,_,_,_,_,_,_  ), 0 , 8 , 5806, 160, 5  , 32),
+     605             :   INST(Movmskpd        , ExtMov             , O(660F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5814, 161, 4  , 33),
+     606             :   INST(Movmskps        , ExtMov             , O(000F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5824, 161, 5  , 33),
+     607             :   INST(Movntdq         , ExtMov             , 0                         , O(660F00,E7,_,_,_,_,_,_  ), 0 , 16, 5834, 162, 4  , 33),
+     608             :   INST(Movntdqa        , ExtMov             , O(660F38,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 5843, 132, 12 , 33),
+     609             :   INST(Movnti          , ExtMovnti          , O(000F00,C3,_,_,x,_,_,_  ), 0                         , 0 , 8 , 1821, 163, 4  , 0 ),
+     610             :   INST(Movntpd         , ExtMov             , 0                         , O(660F00,2B,_,_,_,_,_,_  ), 0 , 16, 5853, 164, 4  , 34),
+     611             :   INST(Movntps         , ExtMov             , 0                         , O(000F00,2B,_,_,_,_,_,_  ), 0 , 16, 5862, 165, 5  , 34),
+     612             :   INST(Movntq          , ExtMov             , 0                         , O(000F00,E7,_,_,_,_,_,_  ), 0 , 8 , 1828, 166, 74 , 0 ),
+     613             :   INST(Movntsd         , ExtMov             , 0                         , O(F20F00,2B,_,_,_,_,_,_  ), 0 , 8 , 1835, 167, 46 , 0 ),
+     614             :   INST(Movntss         , ExtMov             , 0                         , O(F30F00,2B,_,_,_,_,_,_  ), 0 , 4 , 1843, 168, 46 , 0 ),
+     615             :   INST(Movq            , ExtMovq            , O(000F00,6E,_,_,x,_,_,_  ), O(000F00,7E,_,_,x,_,_,_  ), 0 , 16, 7356, 169, 78 , 28),
+     616             :   INST(Movq2dq         , ExtRm              , O(F30F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 16, 1851, 170, 4  , 0 ),
+     617             :   INST(Movs            , X86StrMm           , O(000000,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 411 , 171, 72 , 0 ),
+     618             :   INST(Movsd           , ExtMov             , O(F20F00,10,_,_,_,_,_,_  ), O(F20F00,11,_,_,_,_,_,_  ), 0 , 8 , 5877, 172, 79 , 35),
+     619             :   INST(Movshdup        , ExtRm              , O(F30F00,16,_,_,_,_,_,_  ), 0                         , 0 , 16, 5884, 50 , 6  , 30),
+     620             :   INST(Movsldup        , ExtRm              , O(F30F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5894, 50 , 6  , 30),
+     621             :   INST(Movss           , ExtMov             , O(F30F00,10,_,_,_,_,_,_  ), O(F30F00,11,_,_,_,_,_,_  ), 0 , 4 , 5904, 173, 80 , 35),
+     622             :   INST(Movsx           , X86MovsxMovzx      , O(000F00,BE,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1859, 174, 0  , 0 ),
+     623             :   INST(Movsxd          , X86Rm              , O(000000,63,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1865, 175, 0  , 0 ),
+     624             :   INST(Movupd          , ExtMov             , O(660F00,10,_,_,_,_,_,_  ), O(660F00,11,_,_,_,_,_,_  ), 0 , 16, 5911, 176, 4  , 36),
+     625             :   INST(Movups          , ExtMov             , O(000F00,10,_,_,_,_,_,_  ), O(000F00,11,_,_,_,_,_,_  ), 0 , 16, 5919, 177, 5  , 36),
+     626             :   INST(Movzx           , X86MovsxMovzx      , O(000F00,B6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1872, 174, 0  , 0 ),
+     627             :   INST(Mpsadbw         , ExtRmi             , O(660F3A,42,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5927, 16 , 12 , 37),
+     628             :   INST(Mul             , X86M_GPB_MulDiv    , O(000000,F6,4,_,x,_,_,_  ), 0                         , 0 , 0 , 769 , 178, 1  , 0 ),
+     629             :   INST(Mulpd           , ExtRm              , O(660F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5936, 5  , 4  , 38),
+     630             :   INST(Mulps           , ExtRm              , O(000F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5943, 5  , 5  , 38),
+     631             :   INST(Mulsd           , ExtRm              , O(F20F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5950, 6  , 4  , 38),
+     632             :   INST(Mulss           , ExtRm              , O(F30F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5957, 7  , 5  , 38),
+     633             :   INST(Mulx            , VexRvm_ZDX_Wx      , V(F20F38,F6,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1878, 179, 81 , 0 ),
+     634             :   INST(Mwait           , X86Op              , O(000F01,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1883, 180, 75 , 0 ),
+     635             :   INST(Neg             , X86M_GPB           , O(000000,F6,3,_,x,_,_,_  ), 0                         , 0 , 0 , 1889, 181, 1  , 0 ),
+     636             :   INST(Nop             , X86Op              , O(000000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 900 , 182, 0  , 0 ),
+     637             :   INST(Not             , X86M_GPB           , O(000000,F6,2,_,x,_,_,_  ), 0                         , 0 , 0 , 1893, 181, 0  , 0 ),
+     638             :   INST(Or              , X86Arith           , O(000000,08,1,_,x,_,_,_  ), 0                         , 0 , 0 , 1109, 183, 1  , 0 ),
+     639             :   INST(Orpd            , ExtRm              , O(660F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9429, 12 , 4  , 39),
+     640             :   INST(Orps            , ExtRm              , O(000F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9436, 12 , 5  , 39),
+     641             :   INST(Out             , X86Out             , O(000000,EE,_,_,_,_,_,_  ), O(000000,E6,_,_,_,_,_,_  ), 0 , 0 , 1897, 184, 45 , 0 ),
+     642             :   INST(Outs            , X86Outs            , O(000000,6E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1901, 185, 45 , 0 ),
+     643             :   INST(Pabsb           , ExtRm_P            , O(000F38,1C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5997, 186, 82 , 40),
+     644             :   INST(Pabsd           , ExtRm_P            , O(000F38,1E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6004, 186, 82 , 40),
+     645             :   INST(Pabsw           , ExtRm_P            , O(000F38,1D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6018, 186, 82 , 41),
+     646             :   INST(Packssdw        , ExtRm_P            , O(000F00,6B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6025, 187, 78 , 42),
+     647             :   INST(Packsswb        , ExtRm_P            , O(000F00,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6035, 187, 78 , 42),
+     648             :   INST(Packusdw        , ExtRm              , O(660F38,2B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6045, 5  , 12 , 42),
+     649             :   INST(Packuswb        , ExtRm_P            , O(000F00,67,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6055, 187, 78 , 42),
+     650             :   INST(Paddb           , ExtRm_P            , O(000F00,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6065, 187, 78 , 42),
+     651             :   INST(Paddd           , ExtRm_P            , O(000F00,FE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6072, 187, 78 , 42),
+     652             :   INST(Paddq           , ExtRm_P            , O(000F00,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6079, 187, 4  , 42),
+     653             :   INST(Paddsb          , ExtRm_P            , O(000F00,EC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6086, 187, 78 , 42),
+     654             :   INST(Paddsw          , ExtRm_P            , O(000F00,ED,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6094, 187, 78 , 42),
+     655             :   INST(Paddusb         , ExtRm_P            , O(000F00,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6102, 187, 78 , 42),
+     656             :   INST(Paddusw         , ExtRm_P            , O(000F00,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6111, 187, 78 , 42),
+     657             :   INST(Paddw           , ExtRm_P            , O(000F00,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6120, 187, 78 , 42),
+     658             :   INST(Palignr         , ExtRmi_P           , O(000F3A,0F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6127, 188, 6  , 42),
+     659             :   INST(Pand            , ExtRm_P            , O(000F00,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6136, 189, 78 , 42),
+     660             :   INST(Pandn           , ExtRm_P            , O(000F00,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6149, 190, 78 , 43),
+     661             :   INST(Pause           , X86Op              , O(F30000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1906, 34 , 45 , 0 ),
+     662             :   INST(Pavgb           , ExtRm_P            , O(000F00,E0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6179, 187, 83 , 44),
+     663             :   INST(Pavgusb         , Ext3dNow           , O(000F0F,BF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1912, 191, 84 , 0 ),
+     664             :   INST(Pavgw           , ExtRm_P            , O(000F00,E3,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6186, 187, 83 , 45),
+     665             :   INST(Pblendvb        , ExtRm_XMM0         , O(660F38,10,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6202, 17 , 12 , 46),
+     666             :   INST(Pblendw         , ExtRmi             , O(660F3A,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6212, 16 , 12 , 44),
+     667             :   INST(Pclmulqdq       , ExtRmi             , O(660F3A,44,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6305, 16 , 85 , 47),
+     668             :   INST(Pcmpeqb         , ExtRm_P            , O(000F00,74,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6337, 190, 78 , 48),
+     669             :   INST(Pcmpeqd         , ExtRm_P            , O(000F00,76,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6346, 190, 78 , 48),
+     670             :   INST(Pcmpeqq         , ExtRm              , O(660F38,29,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6355, 192, 12 , 48),
+     671             :   INST(Pcmpeqw         , ExtRm_P            , O(000F00,75,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6364, 190, 78 , 48),
+     672             :   INST(Pcmpestri       , ExtRmi             , O(660F3A,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6373, 193, 86 , 49),
+     673             :   INST(Pcmpestrm       , ExtRmi             , O(660F3A,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6384, 194, 86 , 49),
+     674             :   INST(Pcmpgtb         , ExtRm_P            , O(000F00,64,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6395, 190, 78 , 48),
+     675             :   INST(Pcmpgtd         , ExtRm_P            , O(000F00,66,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6404, 190, 78 , 48),
+     676             :   INST(Pcmpgtq         , ExtRm              , O(660F38,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6413, 192, 42 , 48),
+     677             :   INST(Pcmpgtw         , ExtRm_P            , O(000F00,65,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6422, 190, 78 , 48),
+     678             :   INST(Pcmpistri       , ExtRmi             , O(660F3A,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6431, 195, 86 , 49),
+     679             :   INST(Pcmpistrm       , ExtRmi             , O(660F3A,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6442, 196, 86 , 49),
+     680             :   INST(Pcommit         , X86Op_O            , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1920, 34 , 87 , 0 ),
+     681             :   INST(Pdep            , VexRvm_Wx          , V(F20F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1928, 11 , 81 , 0 ),
+     682             :   INST(Pext            , VexRvm_Wx          , V(F30F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1933, 11 , 81 , 0 ),
+     683             :   INST(Pextrb          , ExtExtract         , O(000F3A,14,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6847, 197, 12 , 50),
+     684             :   INST(Pextrd          , ExtExtract         , O(000F3A,16,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6855, 67 , 12 , 50),
+     685             :   INST(Pextrq          , ExtExtract         , O(000F3A,16,_,_,1,_,_,_  ), 0                         , 0 , 8 , 6863, 198, 12 , 50),
+     686             :   INST(Pextrw          , ExtPextrw          , O(000F00,C5,_,_,_,_,_,_  ), O(000F3A,15,_,_,_,_,_,_  ), 0 , 8 , 6871, 199, 88 , 50),
+     687             :   INST(Pf2id           , Ext3dNow           , O(000F0F,1D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1938, 200, 84 , 0 ),
+     688             :   INST(Pf2iw           , Ext3dNow           , O(000F0F,1C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1944, 200, 89 , 0 ),
+     689             :   INST(Pfacc           , Ext3dNow           , O(000F0F,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1950, 191, 84 , 0 ),
+     690             :   INST(Pfadd           , Ext3dNow           , O(000F0F,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1956, 191, 84 , 0 ),
+     691             :   INST(Pfcmpeq         , Ext3dNow           , O(000F0F,B0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1962, 191, 84 , 0 ),
+     692             :   INST(Pfcmpge         , Ext3dNow           , O(000F0F,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1970, 191, 84 , 0 ),
+     693             :   INST(Pfcmpgt         , Ext3dNow           , O(000F0F,A0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1978, 191, 84 , 0 ),
+     694             :   INST(Pfmax           , Ext3dNow           , O(000F0F,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1986, 191, 84 , 0 ),
+     695             :   INST(Pfmin           , Ext3dNow           , O(000F0F,94,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1992, 191, 84 , 0 ),
+     696             :   INST(Pfmul           , Ext3dNow           , O(000F0F,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1998, 191, 84 , 0 ),
+     697             :   INST(Pfnacc          , Ext3dNow           , O(000F0F,8A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2004, 191, 89 , 0 ),
+     698             :   INST(Pfpnacc         , Ext3dNow           , O(000F0F,8E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2011, 191, 89 , 0 ),
+     699             :   INST(Pfrcp           , Ext3dNow           , O(000F0F,96,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2019, 200, 84 , 0 ),
+     700             :   INST(Pfrcpit1        , Ext3dNow           , O(000F0F,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2025, 191, 84 , 0 ),
+     701             :   INST(Pfrcpit2        , Ext3dNow           , O(000F0F,B6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2034, 191, 84 , 0 ),
+     702             :   INST(Pfrcpv          , Ext3dNow           , O(000F0F,86,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2043, 191, 90 , 0 ),
+     703             :   INST(Pfrsqit1        , Ext3dNow           , O(000F0F,A7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2050, 201, 84 , 0 ),
+     704             :   INST(Pfrsqrt         , Ext3dNow           , O(000F0F,97,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2059, 201, 84 , 0 ),
+     705             :   INST(Pfrsqrtv        , Ext3dNow           , O(000F0F,87,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2067, 191, 90 , 0 ),
+     706             :   INST(Pfsub           , Ext3dNow           , O(000F0F,9A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2076, 191, 84 , 0 ),
+     707             :   INST(Pfsubr          , Ext3dNow           , O(000F0F,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2082, 191, 84 , 0 ),
+     708             :   INST(Phaddd          , ExtRm_P            , O(000F38,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6950, 187, 82 , 51),
+     709             :   INST(Phaddsw         , ExtRm_P            , O(000F38,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6967, 187, 82 , 52),
+     710             :   INST(Phaddw          , ExtRm_P            , O(000F38,01,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7036, 187, 82 , 53),
+     711             :   INST(Phminposuw      , ExtRm              , O(660F38,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7062, 5  , 12 , 54),
+     712             :   INST(Phsubd          , ExtRm_P            , O(000F38,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7083, 187, 82 , 55),
+     713             :   INST(Phsubsw         , ExtRm_P            , O(000F38,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7100, 187, 82 , 56),
+     714             :   INST(Phsubw          , ExtRm_P            , O(000F38,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7109, 187, 82 , 56),
+     715             :   INST(Pi2fd           , Ext3dNow           , O(000F0F,0D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2089, 200, 84 , 0 ),
+     716             :   INST(Pi2fw           , Ext3dNow           , O(000F0F,0C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2095, 200, 89 , 0 ),
+     717             :   INST(Pinsrb          , ExtRmi             , O(660F3A,20,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7126, 202, 12 , 57),
+     718             :   INST(Pinsrd          , ExtRmi             , O(660F3A,22,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7134, 203, 12 , 57),
+     719             :   INST(Pinsrq          , ExtRmi             , O(660F3A,22,_,_,1,_,_,_  ), 0                         , 0 , 0 , 7142, 204, 12 , 57),
+     720             :   INST(Pinsrw          , ExtRmi_P           , O(000F00,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7150, 205, 83 , 55),
+     721             :   INST(Pmaddubsw       , ExtRm_P            , O(000F38,04,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7320, 187, 82 , 58),
+     722             :   INST(Pmaddwd         , ExtRm_P            , O(000F00,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7331, 187, 78 , 58),
+     723             :   INST(Pmaxsb          , ExtRm              , O(660F38,3C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7362, 12 , 12 , 59),
+     724             :   INST(Pmaxsd          , ExtRm              , O(660F38,3D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7370, 12 , 12 , 59),
+     725             :   INST(Pmaxsw          , ExtRm_P            , O(000F00,EE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7386, 189, 83 , 60),
+     726             :   INST(Pmaxub          , ExtRm_P            , O(000F00,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7394, 189, 83 , 60),
+     727             :   INST(Pmaxud          , ExtRm              , O(660F38,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7402, 12 , 12 , 60),
+     728             :   INST(Pmaxuw          , ExtRm              , O(660F38,3E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7418, 12 , 12 , 61),
+     729             :   INST(Pminsb          , ExtRm              , O(660F38,38,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7426, 12 , 12 , 61),
+     730             :   INST(Pminsd          , ExtRm              , O(660F38,39,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7434, 12 , 12 , 61),
+     731             :   INST(Pminsw          , ExtRm_P            , O(000F00,EA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7450, 189, 83 , 62),
+     732             :   INST(Pminub          , ExtRm_P            , O(000F00,DA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7458, 189, 83 , 62),
+     733             :   INST(Pminud          , ExtRm              , O(660F38,3B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7466, 12 , 12 , 62),
+     734             :   INST(Pminuw          , ExtRm              , O(660F38,3A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7482, 12 , 12 , 63),
+     735             :   INST(Pmovmskb        , ExtRm_P            , O(000F00,D7,_,_,_,_,_,_  ), 0                         , 0 , 8 , 7560, 206, 83 , 64),
+     736             :   INST(Pmovsxbd        , ExtRm              , O(660F38,21,_,_,_,_,_,_  ), 0                         , 0 , 16, 7657, 207, 12 , 14),
+     737             :   INST(Pmovsxbq        , ExtRm              , O(660F38,22,_,_,_,_,_,_  ), 0                         , 0 , 16, 7667, 208, 12 , 14),
+     738             :   INST(Pmovsxbw        , ExtRm              , O(660F38,20,_,_,_,_,_,_  ), 0                         , 0 , 16, 7677, 49 , 12 , 14),
+     739             :   INST(Pmovsxdq        , ExtRm              , O(660F38,25,_,_,_,_,_,_  ), 0                         , 0 , 16, 7687, 49 , 12 , 14),
+     740             :   INST(Pmovsxwd        , ExtRm              , O(660F38,23,_,_,_,_,_,_  ), 0                         , 0 , 16, 7697, 49 , 12 , 14),
+     741             :   INST(Pmovsxwq        , ExtRm              , O(660F38,24,_,_,_,_,_,_  ), 0                         , 0 , 16, 7707, 207, 12 , 14),
+     742             :   INST(Pmovzxbd        , ExtRm              , O(660F38,31,_,_,_,_,_,_  ), 0                         , 0 , 16, 7794, 207, 12 , 65),
+     743             :   INST(Pmovzxbq        , ExtRm              , O(660F38,32,_,_,_,_,_,_  ), 0                         , 0 , 16, 7804, 208, 12 , 65),
+     744             :   INST(Pmovzxbw        , ExtRm              , O(660F38,30,_,_,_,_,_,_  ), 0                         , 0 , 16, 7814, 49 , 12 , 65),
+     745             :   INST(Pmovzxdq        , ExtRm              , O(660F38,35,_,_,_,_,_,_  ), 0                         , 0 , 16, 7824, 49 , 12 , 65),
+     746             :   INST(Pmovzxwd        , ExtRm              , O(660F38,33,_,_,_,_,_,_  ), 0                         , 0 , 16, 7834, 49 , 12 , 65),
+     747             :   INST(Pmovzxwq        , ExtRm              , O(660F38,34,_,_,_,_,_,_  ), 0                         , 0 , 16, 7844, 207, 12 , 65),
+     748             :   INST(Pmuldq          , ExtRm              , O(660F38,28,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7854, 5  , 12 , 19),
+     749             :   INST(Pmulhrsw        , ExtRm_P            , O(000F38,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7862, 187, 82 , 19),
+     750             :   INST(Pmulhrw         , Ext3dNow           , O(000F0F,B7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2101, 191, 84 , 0 ),
+     751             :   INST(Pmulhuw         , ExtRm_P            , O(000F00,E4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7872, 187, 83 , 66),
+     752             :   INST(Pmulhw          , ExtRm_P            , O(000F00,E5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7881, 187, 78 , 66),
+     753             :   INST(Pmulld          , ExtRm              , O(660F38,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7889, 5  , 12 , 66),
+     754             :   INST(Pmullw          , ExtRm_P            , O(000F00,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7905, 187, 78 , 19),
+     755             :   INST(Pmuludq         , ExtRm_P            , O(000F00,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7928, 187, 4  , 67),
+     756             :   INST(Pop             , X86Pop             , O(000000,8F,0,_,_,_,_,_  ), O(000000,58,_,_,_,_,_,_  ), 0 , 0 , 2109, 209, 45 , 0 ),
+     757             :   INST(Popa            , X86Op              , O(660000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2113, 99 , 45 , 0 ),
+     758             :   INST(Popad           , X86Op              , O(000000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2118, 99 , 45 , 0 ),
+     759             :   INST(Popcnt          , X86Rm_Raw66H       , O(F30F00,B8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2124, 143, 91 , 0 ),
+     760             :   INST(Popf            , X86Op              , O(660000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2131, 34 , 16 , 0 ),
+     761             :   INST(Popfd           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2136, 99 , 16 , 0 ),
+     762             :   INST(Popfq           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2142, 101, 16 , 0 ),
+     763             :   INST(Por             , ExtRm_P            , O(000F00,EB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7955, 189, 78 , 68),
+     764             :   INST(Prefetch        , X86M_Only          , O(000F00,0D,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2148, 35 , 92 , 0 ),
+     765             :   INST(Prefetchnta     , X86M_Only          , O(000F00,18,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2157, 35 , 93 , 0 ),
+     766             :   INST(Prefetcht0      , X86M_Only          , O(000F00,18,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2169, 35 , 93 , 0 ),
+     767             :   INST(Prefetcht1      , X86M_Only          , O(000F00,18,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2180, 35 , 93 , 0 ),
+     768             :   INST(Prefetcht2      , X86M_Only          , O(000F00,18,3,_,_,_,_,_  ), 0                         , 0 , 0 , 2191, 35 , 93 , 0 ),
+     769             :   INST(Prefetchw       , X86M_Only          , O(000F00,0D,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2202, 35 , 94 , 0 ),
+     770             :   INST(Prefetchwt1     , X86M_Only          , O(000F00,0D,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2212, 35 , 95 , 0 ),
+     771             :   INST(Psadbw          , ExtRm_P            , O(000F00,F6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3795, 187, 83 , 69),
+     772             :   INST(Pshufb          , ExtRm_P            , O(000F38,00,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8179, 187, 82 , 70),
+     773             :   INST(Pshufd          , ExtRmi             , O(660F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8187, 210, 4  , 71),
+     774             :   INST(Pshufhw         , ExtRmi             , O(F30F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8195, 210, 4  , 71),
+     775             :   INST(Pshuflw         , ExtRmi             , O(F20F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8204, 210, 4  , 71),
+     776             :   INST(Pshufw          , ExtRmi_P           , O(000F00,70,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2224, 211, 74 , 0 ),
+     777             :   INST(Psignb          , ExtRm_P            , O(000F38,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8213, 187, 82 , 72),
+     778             :   INST(Psignd          , ExtRm_P            , O(000F38,0A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8221, 187, 82 , 72),
+     779             :   INST(Psignw          , ExtRm_P            , O(000F38,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8229, 187, 82 , 72),
+     780             :   INST(Pslld           , ExtRmRi_P          , O(000F00,F2,_,_,_,_,_,_  ), O(000F00,72,6,_,_,_,_,_  ), 0 , 0 , 8237, 212, 78 , 72),
+     781             :   INST(Pslldq          , ExtRmRi            , 0                         , O(660F00,73,7,_,_,_,_,_  ), 0 , 0 , 8244, 213, 4  , 72),
+     782             :   INST(Psllq           , ExtRmRi_P          , O(000F00,F3,_,_,_,_,_,_  ), O(000F00,73,6,_,_,_,_,_  ), 0 , 0 , 8252, 214, 78 , 72),
+     783             :   INST(Psllw           , ExtRmRi_P          , O(000F00,F1,_,_,_,_,_,_  ), O(000F00,71,6,_,_,_,_,_  ), 0 , 0 , 8283, 215, 78 , 73),
+     784             :   INST(Psrad           , ExtRmRi_P          , O(000F00,E2,_,_,_,_,_,_  ), O(000F00,72,4,_,_,_,_,_  ), 0 , 0 , 8290, 216, 78 , 73),
+     785             :   INST(Psraw           , ExtRmRi_P          , O(000F00,E1,_,_,_,_,_,_  ), O(000F00,71,4,_,_,_,_,_  ), 0 , 0 , 8328, 217, 78 , 74),
+     786             :   INST(Psrld           , ExtRmRi_P          , O(000F00,D2,_,_,_,_,_,_  ), O(000F00,72,2,_,_,_,_,_  ), 0 , 0 , 8335, 218, 78 , 74),
+     787             :   INST(Psrldq          , ExtRmRi            , 0                         , O(660F00,73,3,_,_,_,_,_  ), 0 , 0 , 8342, 219, 4  , 74),
+     788             :   INST(Psrlq           , ExtRmRi_P          , O(000F00,D3,_,_,_,_,_,_  ), O(000F00,73,2,_,_,_,_,_  ), 0 , 0 , 8350, 220, 78 , 74),
+     789             :   INST(Psrlw           , ExtRmRi_P          , O(000F00,D1,_,_,_,_,_,_  ), O(000F00,71,2,_,_,_,_,_  ), 0 , 0 , 8381, 221, 78 , 75),
+     790             :   INST(Psubb           , ExtRm_P            , O(000F00,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8388, 190, 78 , 75),
+     791             :   INST(Psubd           , ExtRm_P            , O(000F00,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8395, 190, 78 , 75),
+     792             :   INST(Psubq           , ExtRm_P            , O(000F00,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8402, 190, 4  , 75),
+     793             :   INST(Psubsb          , ExtRm_P            , O(000F00,E8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8409, 190, 78 , 75),
+     794             :   INST(Psubsw          , ExtRm_P            , O(000F00,E9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8417, 190, 78 , 75),
+     795             :   INST(Psubusb         , ExtRm_P            , O(000F00,D8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8425, 190, 78 , 75),
+     796             :   INST(Psubusw         , ExtRm_P            , O(000F00,D9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8434, 190, 78 , 75),
+     797             :   INST(Psubw           , ExtRm_P            , O(000F00,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8443, 190, 78 , 75),
+     798             :   INST(Pswapd          , Ext3dNow           , O(000F0F,BB,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2231, 200, 89 , 0 ),
+     799             :   INST(Ptest           , ExtRm              , O(660F38,17,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8472, 222, 96 , 76),
+     800             :   INST(Punpckhbw       , ExtRm_P            , O(000F00,68,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8555, 187, 78 , 77),
+     801             :   INST(Punpckhdq       , ExtRm_P            , O(000F00,6A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8566, 187, 78 , 77),
+     802             :   INST(Punpckhqdq      , ExtRm              , O(660F00,6D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8577, 5  , 4  , 77),
+     803             :   INST(Punpckhwd       , ExtRm_P            , O(000F00,69,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8589, 187, 78 , 77),
+     804             :   INST(Punpcklbw       , ExtRm_P            , O(000F00,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8600, 187, 78 , 77),
+     805             :   INST(Punpckldq       , ExtRm_P            , O(000F00,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8611, 187, 78 , 77),
+     806             :   INST(Punpcklqdq      , ExtRm              , O(660F00,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8622, 5  , 4  , 77),
+     807             :   INST(Punpcklwd       , ExtRm_P            , O(000F00,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8634, 187, 78 , 77),
+     808             :   INST(Push            , X86Push            , O(000000,FF,6,_,_,_,_,_  ), O(000000,50,_,_,_,_,_,_  ), 0 , 0 , 2238, 223, 45 , 0 ),
+     809             :   INST(Pusha           , X86Op              , O(660000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2243, 99 , 45 , 0 ),
+     810             :   INST(Pushad          , X86Op              , O(000000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2249, 99 , 45 , 0 ),
+     811             :   INST(Pushf           , X86Op              , O(660000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2256, 34 , 45 , 0 ),
+     812             :   INST(Pushfd          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2262, 99 , 45 , 0 ),
+     813             :   INST(Pushfq          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2269, 101, 45 , 0 ),
+     814             :   INST(Pxor            , ExtRm_P            , O(000F00,EF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8645, 190, 78 , 78),
+     815             :   INST(Rcl             , X86Rot             , O(000000,D0,2,_,x,_,_,_  ), 0                         , 0 , 0 , 2276, 224, 97 , 0 ),
+     816             :   INST(Rcpps           , ExtRm              , O(000F00,53,_,_,_,_,_,_  ), 0                         , 0 , 16, 8773, 50 , 5  , 79),
+     817             :   INST(Rcpss           , ExtRm              , O(F30F00,53,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8780, 225, 5  , 80),
+     818             :   INST(Rcr             , X86Rot             , O(000000,D0,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2280, 224, 97 , 0 ),
+     819             :   INST(Rdfsbase        , X86M               , O(F30F00,AE,0,_,x,_,_,_  ), 0                         , 0 , 8 , 2284, 226, 98 , 0 ),
+     820             :   INST(Rdgsbase        , X86M               , O(F30F00,AE,1,_,x,_,_,_  ), 0                         , 0 , 8 , 2293, 226, 98 , 0 ),
+     821             :   INST(Rdmsr           , X86Op              , O(000F00,32,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2302, 227, 99 , 0 ),
+     822             :   INST(Rdpmc           , X86Op              , O(000F00,33,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2308, 227, 23 , 0 ),
+     823             :   INST(Rdrand          , X86M               , O(000F00,C7,6,_,x,_,_,_  ), 0                         , 0 , 8 , 2314, 228, 100, 0 ),
+     824             :   INST(Rdseed          , X86M               , O(000F00,C7,7,_,x,_,_,_  ), 0                         , 0 , 8 , 2321, 228, 101, 0 ),
+     825             :   INST(Rdtsc           , X86Op              , O(000F00,31,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2328, 229, 102, 0 ),
+     826             :   INST(Rdtscp          , X86Op              , O(000F01,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2334, 230, 103, 0 ),
+     827             :   INST(Ret             , X86Ret             , O(000000,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2748, 231, 45 , 0 ),
+     828             :   INST(Rol             , X86Rot             , O(000000,D0,0,_,x,_,_,_  ), 0                         , 0 , 0 , 2341, 224, 97 , 0 ),
+     829             :   INST(Ror             , X86Rot             , O(000000,D0,1,_,x,_,_,_  ), 0                         , 0 , 0 , 2345, 224, 97 , 0 ),
+     830             :   INST(Rorx            , VexRmi_Wx          , V(F20F3A,F0,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2349, 232, 81 , 0 ),
+     831             :   INST(Roundpd         , ExtRmi             , O(660F3A,09,_,_,_,_,_,_  ), 0                         , 0 , 16, 8875, 210, 12 , 81),
+     832             :   INST(Roundps         , ExtRmi             , O(660F3A,08,_,_,_,_,_,_  ), 0                         , 0 , 16, 8884, 210, 12 , 81),
+     833             :   INST(Roundsd         , ExtRmi             , O(660F3A,0B,_,_,_,_,_,_  ), 0                         , 0 , 8 , 8893, 233, 12 , 82),
+     834             :   INST(Roundss         , ExtRmi             , O(660F3A,0A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8902, 234, 12 , 82),
+     835             :   INST(Rsm             , X86Op              , O(000F00,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2354, 99 , 16 , 0 ),
+     836             :   INST(Rsqrtps         , ExtRm              , O(000F00,52,_,_,_,_,_,_  ), 0                         , 0 , 16, 8999, 50 , 5  , 3 ),
+     837             :   INST(Rsqrtss         , ExtRm              , O(F30F00,52,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9008, 225, 5  , 2 ),
+     838             :   INST(Sahf            , X86Op              , O(000000,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2358, 235, 104, 0 ),
+     839             :   INST(Sal             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2363, 224, 1  , 0 ),
+     840             :   INST(Sar             , X86Rot             , O(000000,D0,7,_,x,_,_,_  ), 0                         , 0 , 0 , 2367, 224, 1  , 0 ),
+     841             :   INST(Sarx            , VexRmv_Wx          , V(F30F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2371, 14 , 81 , 0 ),
+     842             :   INST(Sbb             , X86Arith           , O(000000,18,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2376, 3  , 2  , 0 ),
+     843             :   INST(Scas            , X86StrRm           , O(000000,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2380, 236, 35 , 0 ),
+     844             :   INST(Seta            , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2385, 237, 105, 0 ),
+     845             :   INST(Setae           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2390, 237, 106, 0 ),
+     846             :   INST(Setb            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2396, 237, 106, 0 ),
+     847             :   INST(Setbe           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2401, 237, 105, 0 ),
+     848             :   INST(Setc            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2407, 237, 106, 0 ),
+     849             :   INST(Sete            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2412, 237, 107, 0 ),
+     850             :   INST(Setg            , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2417, 237, 108, 0 ),
+     851             :   INST(Setge           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2422, 237, 109, 0 ),
+     852             :   INST(Setl            , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2428, 237, 109, 0 ),
+     853             :   INST(Setle           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2433, 237, 108, 0 ),
+     854             :   INST(Setna           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2439, 237, 105, 0 ),
+     855             :   INST(Setnae          , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2445, 237, 106, 0 ),
+     856             :   INST(Setnb           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2452, 237, 106, 0 ),
+     857             :   INST(Setnbe          , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2458, 237, 105, 0 ),
+     858             :   INST(Setnc           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2465, 237, 106, 0 ),
+     859             :   INST(Setne           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2471, 237, 107, 0 ),
+     860             :   INST(Setng           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2477, 237, 108, 0 ),
+     861             :   INST(Setnge          , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2483, 237, 109, 0 ),
+     862             :   INST(Setnl           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2490, 237, 109, 0 ),
+     863             :   INST(Setnle          , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2496, 237, 108, 0 ),
+     864             :   INST(Setno           , X86Set             , O(000F00,91,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2503, 237, 110, 0 ),
+     865             :   INST(Setnp           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2509, 237, 111, 0 ),
+     866             :   INST(Setns           , X86Set             , O(000F00,99,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2515, 237, 112, 0 ),
+     867             :   INST(Setnz           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2521, 237, 107, 0 ),
+     868             :   INST(Seto            , X86Set             , O(000F00,90,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2527, 237, 110, 0 ),
+     869             :   INST(Setp            , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2532, 237, 111, 0 ),
+     870             :   INST(Setpe           , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2537, 237, 111, 0 ),
+     871             :   INST(Setpo           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2543, 237, 111, 0 ),
+     872             :   INST(Sets            , X86Set             , O(000F00,98,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2549, 237, 112, 0 ),
+     873             :   INST(Setz            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2554, 237, 107, 0 ),
+     874             :   INST(Sfence          , X86Fence           , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 2559, 34 , 113, 0 ),
+     875             :   INST(Sgdt            , X86M_Only          , O(000F00,01,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2566, 84 , 45 , 0 ),
+     876             :   INST(Sha1msg1        , ExtRm              , O(000F38,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2571, 5  , 114, 0 ),
+     877             :   INST(Sha1msg2        , ExtRm              , O(000F38,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2580, 5  , 114, 0 ),
+     878             :   INST(Sha1nexte       , ExtRm              , O(000F38,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2589, 5  , 114, 0 ),
+     879             :   INST(Sha1rnds4       , ExtRmi             , O(000F3A,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2599, 16 , 114, 0 ),
+     880             :   INST(Sha256msg1      , ExtRm              , O(000F38,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2609, 5  , 114, 0 ),
+     881             :   INST(Sha256msg2      , ExtRm              , O(000F38,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2620, 5  , 114, 0 ),
+     882             :   INST(Sha256rnds2     , ExtRm_XMM0         , O(000F38,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2631, 17 , 114, 0 ),
+     883             :   INST(Shl             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2643, 224, 1  , 0 ),
+     884             :   INST(Shld            , X86ShldShrd        , O(000F00,A4,_,_,x,_,_,_  ), 0                         , 0 , 0 , 8159, 238, 1  , 0 ),
+     885             :   INST(Shlx            , VexRmv_Wx          , V(660F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2647, 14 , 81 , 0 ),
+     886             :   INST(Shr             , X86Rot             , O(000000,D0,5,_,x,_,_,_  ), 0                         , 0 , 0 , 2652, 224, 1  , 0 ),
+     887             :   INST(Shrd            , X86ShldShrd        , O(000F00,AC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2656, 238, 1  , 0 ),
+     888             :   INST(Shrx            , VexRmv_Wx          , V(F20F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2661, 14 , 81 , 0 ),
+     889             :   INST(Shufpd          , ExtRmi             , O(660F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9269, 16 , 4  , 83),
+     890             :   INST(Shufps          , ExtRmi             , O(000F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9277, 16 , 5  , 83),
+     891             :   INST(Sidt            , X86M_Only          , O(000F00,01,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2666, 84 , 45 , 0 ),
+     892             :   INST(Sldt            , X86M               , O(000F00,00,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2671, 239, 45 , 0 ),
+     893             :   INST(Smsw            , X86M               , O(000F00,01,4,_,_,_,_,_  ), 0                         , 0 , 0 , 2676, 239, 45 , 0 ),
+     894             :   INST(Sqrtpd          , ExtRm              , O(660F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9285, 50 , 4  , 84),
+     895             :   INST(Sqrtps          , ExtRm              , O(000F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9000, 50 , 5  , 84),
+     896             :   INST(Sqrtsd          , ExtRm              , O(F20F00,51,_,_,_,_,_,_  ), 0                         , 0 , 8 , 9301, 240, 4  , 85),
+     897             :   INST(Sqrtss          , ExtRm              , O(F30F00,51,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9009, 225, 5  , 85),
+     898             :   INST(Stac            , X86Op              , O(000F01,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2681, 34 , 17 , 0 ),
+     899             :   INST(Stc             , X86Op              , O(000000,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2686, 34 , 18 , 0 ),
+     900             :   INST(Std             , X86Op              , O(000000,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6242, 34 , 19 , 0 ),
+     901             :   INST(Sti             , X86Op              , O(000000,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2690, 34 , 22 , 0 ),
+     902             :   INST(Stmxcsr         , X86M_Only          , O(000F00,AE,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9317, 241, 5  , 0 ),
+     903             :   INST(Stos            , X86StrMr           , O(000000,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2694, 242, 72 , 0 ),
+     904             :   INST(Str             , X86M               , O(000F00,00,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2699, 239, 45 , 0 ),
+     905             :   INST(Sub             , X86Arith           , O(000000,28,5,_,x,_,_,_  ), 0                         , 0 , 0 , 807 , 243, 1  , 0 ),
+     906             :   INST(Subpd           , ExtRm              , O(660F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4361, 5  , 4  , 86),
+     907             :   INST(Subps           , ExtRm              , O(000F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4373, 5  , 5  , 86),
+     908             :   INST(Subsd           , ExtRm              , O(F20F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5049, 6  , 4  , 86),
+     909             :   INST(Subss           , ExtRm              , O(F30F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5059, 7  , 5  , 86),
+     910             :   INST(Swapgs          , X86Op              , O(000F01,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2703, 101, 23 , 0 ),
+     911             :   INST(Syscall         , X86Op              , O(000F00,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2710, 101, 45 , 0 ),
+     912             :   INST(Sysenter        , X86Op              , O(000F00,34,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2718, 34 , 45 , 0 ),
+     913             :   INST(Sysexit         , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2727, 34 , 23 , 0 ),
+     914             :   INST(Sysexit64       , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2735, 34 , 23 , 0 ),
+     915             :   INST(Sysret          , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2745, 101, 23 , 0 ),
+     916             :   INST(Sysret64        , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2752, 101, 23 , 0 ),
+     917             :   INST(T1mskc          , VexVm_Wx           , V(XOP_M9,01,7,0,x,_,_,_  ), 0                         , 0 , 0 , 2761, 15 , 11 , 0 ),
+     918             :   INST(Test            , X86Test            , O(000000,84,_,_,x,_,_,_  ), O(000000,F6,_,_,x,_,_,_  ), 0 , 0 , 8473, 244, 1  , 0 ),
+     919             :   INST(Tzcnt           , X86Rm_Raw66H       , O(F30F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2768, 143, 9  , 0 ),
+     920             :   INST(Tzmsk           , VexVm_Wx           , V(XOP_M9,01,4,0,x,_,_,_  ), 0                         , 0 , 0 , 2774, 15 , 11 , 0 ),
+     921             :   INST(Ucomisd         , ExtRm              , O(660F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9370, 44 , 39 , 15),
+     922             :   INST(Ucomiss         , ExtRm              , O(000F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9379, 45 , 40 , 15),
+     923             :   INST(Ud2             , X86Op              , O(000F00,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2780, 34 , 0  , 0 ),
+     924             :   INST(Unpckhpd        , ExtRm              , O(660F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9388, 5  , 4  , 13),
+     925             :   INST(Unpckhps        , ExtRm              , O(000F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9398, 5  , 5  , 13),
+     926             :   INST(Unpcklpd        , ExtRm              , O(660F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9408, 5  , 4  , 13),
+     927             :   INST(Unpcklps        , ExtRm              , O(000F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9418, 5  , 5  , 13),
+     928             :   INST(V4fmaddps       , VexRm_T1_4X        , V(F20F38,9A,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2784, 245, 115, 0 ),
+     929             :   INST(V4fnmaddps      , VexRm_T1_4X        , V(F20F38,AA,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2794, 245, 115, 0 ),
+     930             :   INST(Vaddpd          , VexRvm_Lx          , V(660F00,58,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2805, 246, 116, 1 ),
+     931             :   INST(Vaddps          , VexRvm_Lx          , V(000F00,58,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2812, 247, 116, 1 ),
+     932             :   INST(Vaddsd          , VexRvm             , V(F20F00,58,_,I,I,1,3,T1S), 0                         , 0 , 0 , 2819, 248, 117, 1 ),
+     933             :   INST(Vaddss          , VexRvm             , V(F30F00,58,_,I,I,0,2,T1S), 0                         , 0 , 0 , 2826, 249, 117, 1 ),
+     934             :   INST(Vaddsubpd       , VexRvm_Lx          , V(660F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2833, 250, 118, 1 ),
+     935             :   INST(Vaddsubps       , VexRvm_Lx          , V(F20F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2843, 250, 118, 1 ),
+     936             :   INST(Vaesdec         , VexRvm             , V(660F38,DE,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2853, 251, 119, 2 ),
+     937             :   INST(Vaesdeclast     , VexRvm             , V(660F38,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2861, 251, 119, 2 ),
+     938             :   INST(Vaesenc         , VexRvm             , V(660F38,DC,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2873, 251, 119, 2 ),
+     939             :   INST(Vaesenclast     , VexRvm             , V(660F38,DD,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2881, 251, 119, 2 ),
+     940             :   INST(Vaesimc         , VexRm              , V(660F38,DB,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2893, 252, 119, 3 ),
+     941             :   INST(Vaeskeygenassist, VexRmi             , V(660F3A,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2901, 253, 119, 3 ),
+     942             :   INST(Valignd         , VexRvmi_Lx         , V(660F3A,03,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2918, 254, 120, 0 ),
+     943             :   INST(Valignq         , VexRvmi_Lx         , V(660F3A,03,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2926, 255, 120, 0 ),
+     944             :   INST(Vandnpd         , VexRvm_Lx          , V(660F00,55,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2934, 256, 121, 2 ),
+     945             :   INST(Vandnps         , VexRvm_Lx          , V(000F00,55,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2942, 257, 121, 2 ),
+     946             :   INST(Vandpd          , VexRvm_Lx          , V(660F00,54,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2950, 258, 121, 2 ),
+     947             :   INST(Vandps          , VexRvm_Lx          , V(000F00,54,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2957, 259, 121, 2 ),
+     948             :   INST(Vblendmb        , VexRvm_Lx          , V(660F38,66,_,x,_,0,4,FVM), 0                         , 0 , 0 , 2964, 260, 122, 0 ),
+     949             :   INST(Vblendmd        , VexRvm_Lx          , V(660F38,64,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2973, 261, 120, 0 ),
+     950             :   INST(Vblendmpd       , VexRvm_Lx          , V(660F38,65,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2982, 262, 120, 0 ),
+     951             :   INST(Vblendmps       , VexRvm_Lx          , V(660F38,65,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2992, 261, 120, 0 ),
+     952             :   INST(Vblendmq        , VexRvm_Lx          , V(660F38,64,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3002, 262, 120, 0 ),
+     953             :   INST(Vblendmw        , VexRvm_Lx          , V(660F38,66,_,x,_,1,4,FVM), 0                         , 0 , 0 , 3011, 260, 122, 0 ),
+     954             :   INST(Vblendpd        , VexRvmi_Lx         , V(660F3A,0D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3020, 263, 118, 4 ),
+     955             :   INST(Vblendps        , VexRvmi_Lx         , V(660F3A,0C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3029, 263, 118, 4 ),
+     956             :   INST(Vblendvpd       , VexRvmr_Lx         , V(660F3A,4B,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3038, 264, 118, 5 ),
+     957             :   INST(Vblendvps       , VexRvmr_Lx         , V(660F3A,4A,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3048, 264, 118, 5 ),
+     958             :   INST(Vbroadcastf128  , VexRm              , V(660F38,1A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3058, 265, 118, 0 ),
+     959             :   INST(Vbroadcastf32x2 , VexRm_Lx           , V(660F38,19,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3073, 266, 123, 0 ),
+     960             :   INST(Vbroadcastf32x4 , VexRm_Lx           , V(660F38,1A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3089, 267, 65 , 0 ),
+     961             :   INST(Vbroadcastf32x8 , VexRm              , V(660F38,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3105, 268, 63 , 0 ),
+     962             :   INST(Vbroadcastf64x2 , VexRm_Lx           , V(660F38,1A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3121, 267, 123, 0 ),
+     963             :   INST(Vbroadcastf64x4 , VexRm              , V(660F38,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3137, 268, 65 , 0 ),
+     964             :   INST(Vbroadcasti128  , VexRm              , V(660F38,5A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3153, 265, 124, 0 ),
+     965             :   INST(Vbroadcasti32x2 , VexRm_Lx           , V(660F38,59,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3168, 269, 123, 0 ),
+     966             :   INST(Vbroadcasti32x4 , VexRm_Lx           , V(660F38,5A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3184, 266, 120, 0 ),
+     967             :   INST(Vbroadcasti32x8 , VexRm              , V(660F38,5B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3200, 270, 63 , 0 ),
+     968             :   INST(Vbroadcasti64x2 , VexRm_Lx           , V(660F38,5A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3216, 266, 123, 0 ),
+     969             :   INST(Vbroadcasti64x4 , VexRm              , V(660F38,5B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3232, 270, 65 , 0 ),
+     970             :   INST(Vbroadcastsd    , VexRm_Lx           , V(660F38,19,_,x,0,1,3,T1S), 0                         , 0 , 0 , 3248, 271, 125, 0 ),
+     971             :   INST(Vbroadcastss    , VexRm_Lx           , V(660F38,18,_,x,0,0,2,T1S), 0                         , 0 , 0 , 3261, 272, 125, 0 ),
+     972             :   INST(Vcmppd          , VexRvmi_Lx         , V(660F00,C2,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3274, 273, 116, 6 ),
+     973             :   INST(Vcmpps          , VexRvmi_Lx         , V(000F00,C2,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3281, 274, 116, 6 ),
+     974             :   INST(Vcmpsd          , VexRvmi            , V(F20F00,C2,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3288, 275, 117, 7 ),
+     975             :   INST(Vcmpss          , VexRvmi            , V(F30F00,C2,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3295, 276, 117, 7 ),
+     976             :   INST(Vcomisd         , VexRm              , V(660F00,2F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3302, 277, 126, 8 ),
+     977             :   INST(Vcomiss         , VexRm              , V(000F00,2F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3310, 278, 126, 8 ),
+     978             :   INST(Vcompresspd     , VexMr_Lx           , V(660F38,8A,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3318, 279, 120, 0 ),
+     979             :   INST(Vcompressps     , VexMr_Lx           , V(660F38,8A,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3330, 279, 120, 0 ),
+     980             :   INST(Vcvtdq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,I,0,3,HV ), 0                         , 0 , 0 , 3342, 280, 116, 9 ),
+     981             :   INST(Vcvtdq2ps       , VexRm_Lx           , V(000F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3352, 281, 116, 9 ),
+     982             :   INST(Vcvtpd2dq       , VexRm_Lx           , V(F20F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3362, 282, 116, 9 ),
+     983             :   INST(Vcvtpd2ps       , VexRm_Lx           , V(660F00,5A,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3372, 283, 116, 10),
+     984             :   INST(Vcvtpd2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3382, 284, 123, 0 ),
+     985             :   INST(Vcvtpd2udq      , VexRm_Lx           , V(000F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3392, 285, 120, 0 ),
+     986             :   INST(Vcvtpd2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3403, 284, 123, 0 ),
+     987             :   INST(Vcvtph2ps       , VexRm_Lx           , V(660F38,13,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3414, 286, 127, 0 ),
+     988             :   INST(Vcvtps2dq       , VexRm_Lx           , V(660F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3424, 281, 116, 8 ),
+     989             :   INST(Vcvtps2pd       , VexRm_Lx           , V(000F00,5A,_,x,I,0,4,HV ), 0                         , 0 , 0 , 3434, 287, 116, 8 ),
+     990             :   INST(Vcvtps2ph       , VexMri_Lx          , V(660F3A,1D,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3444, 288, 127, 0 ),
+     991             :   INST(Vcvtps2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3454, 289, 123, 0 ),
+     992             :   INST(Vcvtps2udq      , VexRm_Lx           , V(000F00,79,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3464, 290, 120, 0 ),
+     993             :   INST(Vcvtps2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3475, 289, 123, 0 ),
+     994             :   INST(Vcvtqq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3486, 284, 123, 0 ),
+     995             :   INST(Vcvtqq2ps       , VexRm_Lx           , V(000F00,5B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3496, 285, 123, 0 ),
+     996             :   INST(Vcvtsd2si       , VexRm_Wx           , V(F20F00,2D,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3506, 291, 117, 11),
+     997             :   INST(Vcvtsd2ss       , VexRvm             , V(F20F00,5A,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3516, 248, 117, 12),
+     998             :   INST(Vcvtsd2usi      , VexRm_Wx           , V(F20F00,79,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3526, 292, 65 , 0 ),
+     999             :   INST(Vcvtsi2sd       , VexRvm_Wx          , V(F20F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3537, 293, 117, 13),
+    1000             :   INST(Vcvtsi2ss       , VexRvm_Wx          , V(F30F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3547, 293, 117, 13),
+    1001             :   INST(Vcvtss2sd       , VexRvm             , V(F30F00,5A,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3557, 294, 117, 13),
+    1002             :   INST(Vcvtss2si       , VexRm_Wx           , V(F30F00,2D,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3567, 295, 117, 14),
+    1003             :   INST(Vcvtss2usi      , VexRm_Wx           , V(F30F00,79,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3577, 296, 65 , 0 ),
+    1004             :   INST(Vcvttpd2dq      , VexRm_Lx           , V(660F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3588, 297, 116, 15),
+    1005             :   INST(Vcvttpd2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3599, 298, 120, 0 ),
+    1006             :   INST(Vcvttpd2udq     , VexRm_Lx           , V(000F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3610, 299, 120, 0 ),
+    1007             :   INST(Vcvttpd2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3622, 298, 123, 0 ),
+    1008             :   INST(Vcvttps2dq      , VexRm_Lx           , V(F30F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3634, 300, 116, 16),
+    1009             :   INST(Vcvttps2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3645, 301, 123, 0 ),
+    1010             :   INST(Vcvttps2udq     , VexRm_Lx           , V(000F00,78,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3656, 302, 120, 0 ),
+    1011             :   INST(Vcvttps2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3668, 301, 123, 0 ),
+    1012             :   INST(Vcvttsd2si      , VexRm_Wx           , V(F20F00,2C,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3680, 303, 117, 17),
+    1013             :   INST(Vcvttsd2usi     , VexRm_Wx           , V(F20F00,78,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3691, 304, 65 , 0 ),
+    1014             :   INST(Vcvttss2si      , VexRm_Wx           , V(F30F00,2C,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3703, 305, 117, 18),
+    1015             :   INST(Vcvttss2usi     , VexRm_Wx           , V(F30F00,78,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3714, 306, 65 , 0 ),
+    1016             :   INST(Vcvtudq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3726, 307, 120, 0 ),
+    1017             :   INST(Vcvtudq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3737, 290, 120, 0 ),
+    1018             :   INST(Vcvtuqq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3748, 284, 123, 0 ),
+    1019             :   INST(Vcvtuqq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3759, 285, 123, 0 ),
+    1020             :   INST(Vcvtusi2sd      , VexRvm_Wx          , V(F20F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3770, 308, 65 , 0 ),
+    1021             :   INST(Vcvtusi2ss      , VexRvm_Wx          , V(F30F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3781, 308, 65 , 0 ),
+    1022             :   INST(Vdbpsadbw       , VexRvmi_Lx         , V(660F3A,42,_,x,_,0,4,FVM), 0                         , 0 , 0 , 3792, 309, 122, 0 ),
+    1023             :   INST(Vdivpd          , VexRvm_Lx          , V(660F00,5E,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3802, 246, 116, 19),
+    1024             :   INST(Vdivps          , VexRvm_Lx          , V(000F00,5E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3809, 247, 116, 19),
+    1025             :   INST(Vdivsd          , VexRvm             , V(F20F00,5E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3816, 248, 117, 19),
+    1026             :   INST(Vdivss          , VexRvm             , V(F30F00,5E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3823, 249, 117, 19),
+    1027             :   INST(Vdppd           , VexRvmi_Lx         , V(660F3A,41,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3830, 310, 118, 19),
+    1028             :   INST(Vdpps           , VexRvmi_Lx         , V(660F3A,40,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3836, 263, 118, 19),
+    1029             :   INST(Verr            , X86M               , O(000F00,00,4,_,_,_,_,_  ), 0                         , 0 , 0 , 3842, 137, 70 , 0 ),
+    1030             :   INST(Verw            , X86M               , O(000F00,00,5,_,_,_,_,_  ), 0                         , 0 , 0 , 3847, 137, 70 , 0 ),
+    1031             :   INST(Vexp2pd         , VexRm              , V(660F38,C8,_,2,_,1,4,FV ), 0                         , 0 , 0 , 3852, 311, 128, 0 ),
+    1032             :   INST(Vexp2ps         , VexRm              , V(660F38,C8,_,2,_,0,4,FV ), 0                         , 0 , 0 , 3860, 312, 128, 0 ),
+    1033             :   INST(Vexpandpd       , VexRm_Lx           , V(660F38,88,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3868, 313, 120, 0 ),
+    1034             :   INST(Vexpandps       , VexRm_Lx           , V(660F38,88,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3878, 313, 120, 0 ),
+    1035             :   INST(Vextractf128    , VexMri             , V(660F3A,19,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3888, 314, 118, 0 ),
+    1036             :   INST(Vextractf32x4   , VexMri_Lx          , V(660F3A,19,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3901, 315, 120, 0 ),
+    1037             :   INST(Vextractf32x8   , VexMri             , V(660F3A,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3915, 316, 63 , 0 ),
+    1038             :   INST(Vextractf64x2   , VexMri_Lx          , V(660F3A,19,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3929, 315, 123, 0 ),
+    1039             :   INST(Vextractf64x4   , VexMri             , V(660F3A,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3943, 316, 65 , 0 ),
+    1040             :   INST(Vextracti128    , VexMri             , V(660F3A,39,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3957, 314, 124, 0 ),
+    1041             :   INST(Vextracti32x4   , VexMri_Lx          , V(660F3A,39,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3970, 315, 120, 0 ),
+    1042             :   INST(Vextracti32x8   , VexMri             , V(660F3A,3B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3984, 316, 63 , 0 ),
+    1043             :   INST(Vextracti64x2   , VexMri_Lx          , V(660F3A,39,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3998, 315, 123, 0 ),
+    1044             :   INST(Vextracti64x4   , VexMri             , V(660F3A,3B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 4012, 316, 65 , 0 ),
+    1045             :   INST(Vextractps      , VexMri             , V(660F3A,17,_,0,I,I,2,T1S), 0                         , 0 , 0 , 4026, 317, 117, 20),
+    1046             :   INST(Vfixupimmpd     , VexRvmi_Lx         , V(660F3A,54,_,x,_,1,4,FV ), 0                         , 0 , 0 , 4037, 318, 120, 0 ),
+    1047             :   INST(Vfixupimmps     , VexRvmi_Lx         , V(660F3A,54,_,x,_,0,4,FV ), 0                         , 0 , 0 , 4049, 319, 120, 0 ),
+    1048             :   INST(Vfixupimmsd     , VexRvmi            , V(660F3A,55,_,I,_,1,3,T1S), 0                         , 0 , 0 , 4061, 320, 65 , 0 ),
+    1049             :   INST(Vfixupimmss     , VexRvmi            , V(660F3A,55,_,I,_,0,2,T1S), 0                         , 0 , 0 , 4073, 321, 65 , 0 ),
+    1050             :   INST(Vfmadd132pd     , VexRvm_Lx          , V(660F38,98,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4085, 322, 129, 0 ),
+    1051             :   INST(Vfmadd132ps     , VexRvm_Lx          , V(660F38,98,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4097, 323, 129, 0 ),
+    1052             :   INST(Vfmadd132sd     , VexRvm             , V(660F38,99,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4109, 324, 130, 0 ),
+    1053             :   INST(Vfmadd132ss     , VexRvm             , V(660F38,99,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4121, 325, 130, 0 ),
+    1054             :   INST(Vfmadd213pd     , VexRvm_Lx          , V(660F38,A8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4133, 322, 129, 0 ),
+    1055             :   INST(Vfmadd213ps     , VexRvm_Lx          , V(660F38,A8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4145, 323, 129, 0 ),
+    1056             :   INST(Vfmadd213sd     , VexRvm             , V(660F38,A9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4157, 324, 130, 0 ),
+    1057             :   INST(Vfmadd213ss     , VexRvm             , V(660F38,A9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4169, 325, 130, 0 ),
+    1058             :   INST(Vfmadd231pd     , VexRvm_Lx          , V(660F38,B8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4181, 322, 129, 0 ),
+    1059             :   INST(Vfmadd231ps     , VexRvm_Lx          , V(660F38,B8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4193, 323, 129, 0 ),
+    1060             :   INST(Vfmadd231sd     , VexRvm             , V(660F38,B9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4205, 324, 130, 0 ),
+    1061             :   INST(Vfmadd231ss     , VexRvm             , V(660F38,B9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4217, 325, 130, 0 ),
+    1062             :   INST(Vfmaddpd        , Fma4_Lx            , V(660F3A,69,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4229, 326, 131, 0 ),
+    1063             :   INST(Vfmaddps        , Fma4_Lx            , V(660F3A,68,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4238, 326, 131, 0 ),
+    1064             :   INST(Vfmaddsd        , Fma4               , V(660F3A,6B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4247, 327, 131, 0 ),
+    1065             :   INST(Vfmaddss        , Fma4               , V(660F3A,6A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4256, 328, 131, 0 ),
+    1066             :   INST(Vfmaddsub132pd  , VexRvm_Lx          , V(660F38,96,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4265, 322, 129, 0 ),
+    1067             :   INST(Vfmaddsub132ps  , VexRvm_Lx          , V(660F38,96,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4280, 323, 129, 0 ),
+    1068             :   INST(Vfmaddsub213pd  , VexRvm_Lx          , V(660F38,A6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4295, 322, 129, 0 ),
+    1069             :   INST(Vfmaddsub213ps  , VexRvm_Lx          , V(660F38,A6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4310, 323, 129, 0 ),
+    1070             :   INST(Vfmaddsub231pd  , VexRvm_Lx          , V(660F38,B6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4325, 322, 129, 0 ),
+    1071             :   INST(Vfmaddsub231ps  , VexRvm_Lx          , V(660F38,B6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4340, 323, 129, 0 ),
+    1072             :   INST(Vfmaddsubpd     , Fma4_Lx            , V(660F3A,5D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4355, 326, 131, 0 ),
+    1073             :   INST(Vfmaddsubps     , Fma4_Lx            , V(660F3A,5C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4367, 326, 131, 0 ),
+    1074             :   INST(Vfmsub132pd     , VexRvm_Lx          , V(660F38,9A,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4379, 322, 129, 0 ),
+    1075             :   INST(Vfmsub132ps     , VexRvm_Lx          , V(660F38,9A,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4391, 323, 129, 0 ),
+    1076             :   INST(Vfmsub132sd     , VexRvm             , V(660F38,9B,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4403, 324, 130, 0 ),
+    1077             :   INST(Vfmsub132ss     , VexRvm             , V(660F38,9B,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4415, 325, 130, 0 ),
+    1078             :   INST(Vfmsub213pd     , VexRvm_Lx          , V(660F38,AA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4427, 322, 129, 0 ),
+    1079             :   INST(Vfmsub213ps     , VexRvm_Lx          , V(660F38,AA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4439, 323, 129, 0 ),
+    1080             :   INST(Vfmsub213sd     , VexRvm             , V(660F38,AB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4451, 324, 130, 0 ),
+    1081             :   INST(Vfmsub213ss     , VexRvm             , V(660F38,AB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4463, 325, 130, 0 ),
+    1082             :   INST(Vfmsub231pd     , VexRvm_Lx          , V(660F38,BA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4475, 322, 129, 0 ),
+    1083             :   INST(Vfmsub231ps     , VexRvm_Lx          , V(660F38,BA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4487, 323, 129, 0 ),
+    1084             :   INST(Vfmsub231sd     , VexRvm             , V(660F38,BB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4499, 324, 130, 0 ),
+    1085             :   INST(Vfmsub231ss     , VexRvm             , V(660F38,BB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4511, 325, 130, 0 ),
+    1086             :   INST(Vfmsubadd132pd  , VexRvm_Lx          , V(660F38,97,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4523, 322, 129, 0 ),
+    1087             :   INST(Vfmsubadd132ps  , VexRvm_Lx          , V(660F38,97,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4538, 323, 129, 0 ),
+    1088             :   INST(Vfmsubadd213pd  , VexRvm_Lx          , V(660F38,A7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4553, 322, 129, 0 ),
+    1089             :   INST(Vfmsubadd213ps  , VexRvm_Lx          , V(660F38,A7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4568, 323, 129, 0 ),
+    1090             :   INST(Vfmsubadd231pd  , VexRvm_Lx          , V(660F38,B7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4583, 322, 129, 0 ),
+    1091             :   INST(Vfmsubadd231ps  , VexRvm_Lx          , V(660F38,B7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4598, 323, 129, 0 ),
+    1092             :   INST(Vfmsubaddpd     , Fma4_Lx            , V(660F3A,5F,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4613, 326, 131, 0 ),
+    1093             :   INST(Vfmsubaddps     , Fma4_Lx            , V(660F3A,5E,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4625, 326, 131, 0 ),
+    1094             :   INST(Vfmsubpd        , Fma4_Lx            , V(660F3A,6D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4637, 326, 131, 0 ),
+    1095             :   INST(Vfmsubps        , Fma4_Lx            , V(660F3A,6C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4646, 326, 131, 0 ),
+    1096             :   INST(Vfmsubsd        , Fma4               , V(660F3A,6F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4655, 327, 131, 0 ),
+    1097             :   INST(Vfmsubss        , Fma4               , V(660F3A,6E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4664, 328, 131, 0 ),
+    1098             :   INST(Vfnmadd132pd    , VexRvm_Lx          , V(660F38,9C,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4673, 322, 129, 0 ),
+    1099             :   INST(Vfnmadd132ps    , VexRvm_Lx          , V(660F38,9C,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4686, 323, 129, 0 ),
+    1100             :   INST(Vfnmadd132sd    , VexRvm             , V(660F38,9D,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4699, 324, 130, 0 ),
+    1101             :   INST(Vfnmadd132ss    , VexRvm             , V(660F38,9D,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4712, 325, 130, 0 ),
+    1102             :   INST(Vfnmadd213pd    , VexRvm_Lx          , V(660F38,AC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4725, 322, 129, 0 ),
+    1103             :   INST(Vfnmadd213ps    , VexRvm_Lx          , V(660F38,AC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4738, 323, 129, 0 ),
+    1104             :   INST(Vfnmadd213sd    , VexRvm             , V(660F38,AD,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4751, 324, 130, 0 ),
+    1105             :   INST(Vfnmadd213ss    , VexRvm             , V(660F38,AD,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4764, 325, 130, 0 ),
+    1106             :   INST(Vfnmadd231pd    , VexRvm_Lx          , V(660F38,BC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4777, 322, 129, 0 ),
+    1107             :   INST(Vfnmadd231ps    , VexRvm_Lx          , V(660F38,BC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4790, 323, 129, 0 ),
+    1108             :   INST(Vfnmadd231sd    , VexRvm             , V(660F38,BC,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4803, 324, 130, 0 ),
+    1109             :   INST(Vfnmadd231ss    , VexRvm             , V(660F38,BC,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4816, 325, 130, 0 ),
+    1110             :   INST(Vfnmaddpd       , Fma4_Lx            , V(660F3A,79,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4829, 326, 131, 0 ),
+    1111             :   INST(Vfnmaddps       , Fma4_Lx            , V(660F3A,78,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4839, 326, 131, 0 ),
+    1112             :   INST(Vfnmaddsd       , Fma4               , V(660F3A,7B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4849, 327, 131, 0 ),
+    1113             :   INST(Vfnmaddss       , Fma4               , V(660F3A,7A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4859, 328, 131, 0 ),
+    1114             :   INST(Vfnmsub132pd    , VexRvm_Lx          , V(660F38,9E,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4869, 322, 129, 0 ),
+    1115             :   INST(Vfnmsub132ps    , VexRvm_Lx          , V(660F38,9E,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4882, 323, 129, 0 ),
+    1116             :   INST(Vfnmsub132sd    , VexRvm             , V(660F38,9F,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4895, 324, 130, 0 ),
+    1117             :   INST(Vfnmsub132ss    , VexRvm             , V(660F38,9F,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4908, 325, 130, 0 ),
+    1118             :   INST(Vfnmsub213pd    , VexRvm_Lx          , V(660F38,AE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4921, 322, 129, 0 ),
+    1119             :   INST(Vfnmsub213ps    , VexRvm_Lx          , V(660F38,AE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4934, 323, 129, 0 ),
+    1120             :   INST(Vfnmsub213sd    , VexRvm             , V(660F38,AF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4947, 324, 130, 0 ),
+    1121             :   INST(Vfnmsub213ss    , VexRvm             , V(660F38,AF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4960, 325, 130, 0 ),
+    1122             :   INST(Vfnmsub231pd    , VexRvm_Lx          , V(660F38,BE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4973, 322, 129, 0 ),
+    1123             :   INST(Vfnmsub231ps    , VexRvm_Lx          , V(660F38,BE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4986, 323, 129, 0 ),
+    1124             :   INST(Vfnmsub231sd    , VexRvm             , V(660F38,BF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4999, 324, 130, 0 ),
+    1125             :   INST(Vfnmsub231ss    , VexRvm             , V(660F38,BF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 5012, 325, 130, 0 ),
+    1126             :   INST(Vfnmsubpd       , Fma4_Lx            , V(660F3A,7D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5025, 326, 131, 0 ),
+    1127             :   INST(Vfnmsubps       , Fma4_Lx            , V(660F3A,7C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5035, 326, 131, 0 ),
+    1128             :   INST(Vfnmsubsd       , Fma4               , V(660F3A,7F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5045, 327, 131, 0 ),
+    1129             :   INST(Vfnmsubss       , Fma4               , V(660F3A,7E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5055, 328, 131, 0 ),
+    1130             :   INST(Vfpclasspd      , VexRmi_Lx          , V(660F3A,66,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5065, 329, 123, 0 ),
+    1131             :   INST(Vfpclassps      , VexRmi_Lx          , V(660F3A,66,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5076, 330, 123, 0 ),
+    1132             :   INST(Vfpclasssd      , VexRmi_Lx          , V(660F3A,67,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5087, 331, 63 , 0 ),
+    1133             :   INST(Vfpclassss      , VexRmi_Lx          , V(660F3A,67,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5098, 332, 63 , 0 ),
+    1134             :   INST(Vfrczpd         , VexRm_Lx           , V(XOP_M9,81,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5109, 333, 132, 0 ),
+    1135             :   INST(Vfrczps         , VexRm_Lx           , V(XOP_M9,80,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5117, 333, 132, 0 ),
+    1136             :   INST(Vfrczsd         , VexRm              , V(XOP_M9,83,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5125, 334, 132, 0 ),
+    1137             :   INST(Vfrczss         , VexRm              , V(XOP_M9,82,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5133, 335, 132, 0 ),
+    1138             :   INST(Vgatherdpd      , VexRmvRm_VM        , V(660F38,92,_,x,1,_,_,_  ), V(660F38,92,_,x,_,1,3,T1S), 0 , 0 , 5141, 336, 133, 0 ),
+    1139             :   INST(Vgatherdps      , VexRmvRm_VM        , V(660F38,92,_,x,0,_,_,_  ), V(660F38,92,_,x,_,0,2,T1S), 0 , 0 , 5152, 337, 133, 0 ),
+    1140             :   INST(Vgatherpf0dpd   , VexM_VM            , V(660F38,C6,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5163, 338, 134, 0 ),
+    1141             :   INST(Vgatherpf0dps   , VexM_VM            , V(660F38,C6,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5177, 339, 134, 0 ),
+    1142             :   INST(Vgatherpf0qpd   , VexM_VM            , V(660F38,C7,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5191, 340, 134, 0 ),
+    1143             :   INST(Vgatherpf0qps   , VexM_VM            , V(660F38,C7,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5205, 340, 134, 0 ),
+    1144             :   INST(Vgatherpf1dpd   , VexM_VM            , V(660F38,C6,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5219, 338, 134, 0 ),
+    1145             :   INST(Vgatherpf1dps   , VexM_VM            , V(660F38,C6,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5233, 339, 134, 0 ),
+    1146             :   INST(Vgatherpf1qpd   , VexM_VM            , V(660F38,C7,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5247, 340, 134, 0 ),
+    1147             :   INST(Vgatherpf1qps   , VexM_VM            , V(660F38,C7,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5261, 340, 134, 0 ),
+    1148             :   INST(Vgatherqpd      , VexRmvRm_VM        , V(660F38,93,_,x,1,_,_,_  ), V(660F38,93,_,x,_,1,3,T1S), 0 , 0 , 5275, 341, 133, 0 ),
+    1149             :   INST(Vgatherqps      , VexRmvRm_VM        , V(660F38,93,_,x,0,_,_,_  ), V(660F38,93,_,x,_,0,2,T1S), 0 , 0 , 5286, 342, 133, 0 ),
+    1150             :   INST(Vgetexppd       , VexRm_Lx           , V(660F38,42,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5297, 298, 120, 0 ),
+    1151             :   INST(Vgetexpps       , VexRm_Lx           , V(660F38,42,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5307, 302, 120, 0 ),
+    1152             :   INST(Vgetexpsd       , VexRm              , V(660F38,43,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5317, 343, 65 , 0 ),
+    1153             :   INST(Vgetexpss       , VexRm              , V(660F38,43,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5327, 344, 65 , 0 ),
+    1154             :   INST(Vgetmantpd      , VexRmi_Lx          , V(660F3A,26,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5337, 345, 120, 0 ),
+    1155             :   INST(Vgetmantps      , VexRmi_Lx          , V(660F3A,26,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5348, 346, 120, 0 ),
+    1156             :   INST(Vgetmantsd      , VexRmi             , V(660F3A,27,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5359, 347, 65 , 0 ),
+    1157             :   INST(Vgetmantss      , VexRmi             , V(660F3A,27,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5370, 348, 65 , 0 ),
+    1158             :   INST(Vhaddpd         , VexRvm_Lx          , V(660F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5381, 250, 118, 21),
+    1159             :   INST(Vhaddps         , VexRvm_Lx          , V(F20F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5389, 250, 118, 21),
+    1160             :   INST(Vhsubpd         , VexRvm_Lx          , V(660F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5397, 250, 118, 22),
+    1161             :   INST(Vhsubps         , VexRvm_Lx          , V(F20F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5405, 250, 118, 22),
+    1162             :   INST(Vinsertf128     , VexRvmi            , V(660F3A,18,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5413, 349, 118, 0 ),
+    1163             :   INST(Vinsertf32x4    , VexRvmi_Lx         , V(660F3A,18,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5425, 350, 120, 0 ),
+    1164             :   INST(Vinsertf32x8    , VexRvmi            , V(660F3A,1A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5438, 351, 63 , 0 ),
+    1165             :   INST(Vinsertf64x2    , VexRvmi_Lx         , V(660F3A,18,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5451, 350, 123, 0 ),
+    1166             :   INST(Vinsertf64x4    , VexRvmi            , V(660F3A,1A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5464, 351, 65 , 0 ),
+    1167             :   INST(Vinserti128     , VexRvmi            , V(660F3A,38,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5477, 349, 124, 0 ),
+    1168             :   INST(Vinserti32x4    , VexRvmi_Lx         , V(660F3A,38,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5489, 350, 120, 0 ),
+    1169             :   INST(Vinserti32x8    , VexRvmi            , V(660F3A,3A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5502, 351, 63 , 0 ),
+    1170             :   INST(Vinserti64x2    , VexRvmi_Lx         , V(660F3A,38,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5515, 350, 123, 0 ),
+    1171             :   INST(Vinserti64x4    , VexRvmi            , V(660F3A,3A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5528, 351, 65 , 0 ),
+    1172             :   INST(Vinsertps       , VexRvmi            , V(660F3A,21,_,0,I,0,2,T1S), 0                         , 0 , 0 , 5541, 352, 117, 23),
+    1173             :   INST(Vlddqu          , VexRm_Lx           , V(F20F00,F0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5551, 353, 118, 24),
+    1174             :   INST(Vldmxcsr        , VexM               , V(000F00,AE,2,0,I,_,_,_  ), 0                         , 0 , 0 , 5558, 354, 118, 0 ),
+    1175             :   INST(Vmaskmovdqu     , VexRm_ZDI          , V(660F00,F7,_,0,I,_,_,_  ), 0                         , 0 , 0 , 5567, 355, 118, 25),
+    1176             :   INST(Vmaskmovpd      , VexRvmMvr_Lx       , V(660F38,2D,_,x,0,_,_,_  ), V(660F38,2F,_,x,0,_,_,_  ), 0 , 0 , 5579, 356, 118, 0 ),
+    1177             :   INST(Vmaskmovps      , VexRvmMvr_Lx       , V(660F38,2C,_,x,0,_,_,_  ), V(660F38,2E,_,x,0,_,_,_  ), 0 , 0 , 5590, 357, 118, 0 ),
+    1178             :   INST(Vmaxpd          , VexRvm_Lx          , V(660F00,5F,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5601, 358, 116, 26),
+    1179             :   INST(Vmaxps          , VexRvm_Lx          , V(000F00,5F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5608, 359, 116, 26),
+    1180             :   INST(Vmaxsd          , VexRvm             , V(F20F00,5F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5615, 360, 116, 26),
+    1181             :   INST(Vmaxss          , VexRvm             , V(F30F00,5F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5622, 294, 116, 26),
+    1182             :   INST(Vminpd          , VexRvm_Lx          , V(660F00,5D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5629, 358, 116, 27),
+    1183             :   INST(Vminps          , VexRvm_Lx          , V(000F00,5D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5636, 359, 116, 27),
+    1184             :   INST(Vminsd          , VexRvm             , V(F20F00,5D,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5643, 360, 116, 27),
+    1185             :   INST(Vminss          , VexRvm             , V(F30F00,5D,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5650, 294, 116, 27),
+    1186             :   INST(Vmovapd         , VexRmMr_Lx         , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 0 , 0 , 5657, 361, 116, 28),
+    1187             :   INST(Vmovaps         , VexRmMr_Lx         , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 0 , 0 , 5665, 362, 116, 28),
+    1188             :   INST(Vmovd           , VexMovdMovq        , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 0 , 0 , 5673, 363, 117, 29),
+    1189             :   INST(Vmovddup        , VexRm_Lx           , V(F20F00,12,_,x,I,1,3,DUP), 0                         , 0 , 0 , 5679, 364, 116, 29),
+    1190             :   INST(Vmovdqa         , VexRmMr_Lx         , V(660F00,6F,_,x,I,_,_,_  ), V(660F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5688, 365, 118, 30),
+    1191             :   INST(Vmovdqa32       , VexRmMr_Lx         , V(660F00,6F,_,x,_,0,4,FVM), V(660F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5696, 366, 120, 0 ),
+    1192             :   INST(Vmovdqa64       , VexRmMr_Lx         , V(660F00,6F,_,x,_,1,4,FVM), V(660F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5706, 367, 120, 0 ),
+    1193             :   INST(Vmovdqu         , VexRmMr_Lx         , V(F30F00,6F,_,x,I,_,_,_  ), V(F30F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5716, 368, 118, 28),
+    1194             :   INST(Vmovdqu16       , VexRmMr_Lx         , V(F20F00,6F,_,x,_,1,4,FVM), V(F20F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5724, 369, 122, 0 ),
+    1195             :   INST(Vmovdqu32       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,0,4,FVM), V(F30F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5734, 370, 120, 0 ),
+    1196             :   INST(Vmovdqu64       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,1,4,FVM), V(F30F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5744, 371, 120, 0 ),
+    1197             :   INST(Vmovdqu8        , VexRmMr_Lx         , V(F20F00,6F,_,x,_,0,4,FVM), V(F20F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5754, 372, 122, 0 ),
+    1198             :   INST(Vmovhlps        , VexRvm             , V(000F00,12,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5763, 373, 117, 31),
+    1199             :   INST(Vmovhpd         , VexRvmMr           , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 0 , 0 , 5772, 374, 117, 32),
+    1200             :   INST(Vmovhps         , VexRvmMr           , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 0 , 0 , 5780, 375, 117, 32),
+    1201             :   INST(Vmovlhps        , VexRvm             , V(000F00,16,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5788, 373, 117, 31),
+    1202             :   INST(Vmovlpd         , VexRvmMr           , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 0 , 0 , 5797, 376, 117, 32),
+    1203             :   INST(Vmovlps         , VexRvmMr           , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 0 , 0 , 5805, 377, 117, 32),
+    1204             :   INST(Vmovmskpd       , VexRm_Lx           , V(660F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5813, 378, 118, 33),
+    1205             :   INST(Vmovmskps       , VexRm_Lx           , V(000F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5823, 378, 118, 33),
+    1206             :   INST(Vmovntdq        , VexMr_Lx           , V(660F00,E7,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5833, 379, 116, 33),
+    1207             :   INST(Vmovntdqa       , VexRm_Lx           , V(660F38,2A,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5842, 380, 125, 33),
+    1208             :   INST(Vmovntpd        , VexMr_Lx           , V(660F00,2B,_,x,I,1,4,FVM), 0                         , 0 , 0 , 5852, 379, 116, 34),
+    1209             :   INST(Vmovntps        , VexMr_Lx           , V(000F00,2B,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5861, 379, 116, 34),
+    1210             :   INST(Vmovq           , VexMovdMovq        , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 0 , 0 , 5870, 381, 117, 28),
+    1211             :   INST(Vmovsd          , VexMovssMovsd      , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 0 , 0 , 5876, 382, 117, 35),
+    1212             :   INST(Vmovshdup       , VexRm_Lx           , V(F30F00,16,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5883, 383, 116, 30),
+    1213             :   INST(Vmovsldup       , VexRm_Lx           , V(F30F00,12,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5893, 383, 116, 30),
+    1214             :   INST(Vmovss          , VexMovssMovsd      , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 0 , 0 , 5903, 384, 117, 35),
+    1215             :   INST(Vmovupd         , VexRmMr_Lx         , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 0 , 0 , 5910, 385, 116, 36),
+    1216             :   INST(Vmovups         , VexRmMr_Lx         , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 0 , 0 , 5918, 386, 116, 36),
+    1217             :   INST(Vmpsadbw        , VexRvmi_Lx         , V(660F3A,42,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5926, 263, 135, 37),
+    1218             :   INST(Vmulpd          , VexRvm_Lx          , V(660F00,59,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5935, 246, 116, 38),
+    1219             :   INST(Vmulps          , VexRvm_Lx          , V(000F00,59,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5942, 247, 116, 38),
+    1220             :   INST(Vmulsd          , VexRvm_Lx          , V(F20F00,59,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5949, 248, 117, 38),
+    1221             :   INST(Vmulss          , VexRvm_Lx          , V(F30F00,59,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5956, 249, 117, 38),
+    1222             :   INST(Vorpd           , VexRvm_Lx          , V(660F00,56,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5963, 258, 121, 39),
+    1223             :   INST(Vorps           , VexRvm_Lx          , V(000F00,56,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5969, 259, 116, 39),
+    1224             :   INST(Vp4dpwssd       , VexRm_T1_4X        , V(F20F38,52,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5975, 387, 136, 0 ),
+    1225             :   INST(Vp4dpwssds      , VexRm_T1_4X        , V(F20F38,53,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5985, 387, 136, 0 ),
+    1226             :   INST(Vpabsb          , VexRm_Lx           , V(660F38,1C,_,x,I,_,4,FVM), 0                         , 0 , 0 , 5996, 383, 137, 40),
+    1227             :   INST(Vpabsd          , VexRm_Lx           , V(660F38,1E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6003, 383, 125, 40),
+    1228             :   INST(Vpabsq          , VexRm_Lx           , V(660F38,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6010, 313, 120, 0 ),
+    1229             :   INST(Vpabsw          , VexRm_Lx           , V(660F38,1D,_,x,I,_,4,FVM), 0                         , 0 , 0 , 6017, 383, 137, 41),
+    1230             :   INST(Vpackssdw       , VexRvm_Lx          , V(660F00,6B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6024, 257, 137, 42),
+    1231             :   INST(Vpacksswb       , VexRvm_Lx          , V(660F00,63,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6034, 388, 137, 42),
+    1232             :   INST(Vpackusdw       , VexRvm_Lx          , V(660F38,2B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6044, 257, 137, 42),
+    1233             :   INST(Vpackuswb       , VexRvm_Lx          , V(660F00,67,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6054, 388, 137, 42),
+    1234             :   INST(Vpaddb          , VexRvm_Lx          , V(660F00,FC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6064, 388, 137, 42),
+    1235             :   INST(Vpaddd          , VexRvm_Lx          , V(660F00,FE,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6071, 257, 125, 42),
+    1236             :   INST(Vpaddq          , VexRvm_Lx          , V(660F00,D4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 6078, 256, 125, 42),
+    1237             :   INST(Vpaddsb         , VexRvm_Lx          , V(660F00,EC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6085, 388, 137, 42),
+    1238             :   INST(Vpaddsw         , VexRvm_Lx          , V(660F00,ED,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6093, 388, 137, 42),
+    1239             :   INST(Vpaddusb        , VexRvm_Lx          , V(660F00,DC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6101, 388, 137, 42),
+    1240             :   INST(Vpaddusw        , VexRvm_Lx          , V(660F00,DD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6110, 388, 137, 42),
+    1241             :   INST(Vpaddw          , VexRvm_Lx          , V(660F00,FD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6119, 388, 137, 42),
+    1242             :   INST(Vpalignr        , VexRvmi_Lx         , V(660F3A,0F,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6126, 389, 137, 42),
+    1243             :   INST(Vpand           , VexRvm_Lx          , V(660F00,DB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6135, 390, 135, 42),
+    1244             :   INST(Vpandd          , VexRvm_Lx          , V(660F00,DB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6141, 391, 120, 0 ),
+    1245             :   INST(Vpandn          , VexRvm_Lx          , V(660F00,DF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6148, 392, 135, 43),
+    1246             :   INST(Vpandnd         , VexRvm_Lx          , V(660F00,DF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6155, 393, 120, 0 ),
+    1247             :   INST(Vpandnq         , VexRvm_Lx          , V(660F00,DF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6163, 394, 120, 0 ),
+    1248             :   INST(Vpandq          , VexRvm_Lx          , V(660F00,DB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6171, 395, 120, 0 ),
+    1249             :   INST(Vpavgb          , VexRvm_Lx          , V(660F00,E0,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6178, 388, 137, 44),
+    1250             :   INST(Vpavgw          , VexRvm_Lx          , V(660F00,E3,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6185, 388, 137, 45),
+    1251             :   INST(Vpblendd        , VexRvmi_Lx         , V(660F3A,02,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6192, 263, 124, 0 ),
+    1252             :   INST(Vpblendvb       , VexRvmr            , V(660F3A,4C,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6201, 264, 135, 46),
+    1253             :   INST(Vpblendw        , VexRvmi_Lx         , V(660F3A,0E,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6211, 263, 135, 44),
+    1254             :   INST(Vpbroadcastb    , VexRm_Lx           , V(660F38,78,_,x,0,0,0,T1S), 0                         , 0 , 0 , 6220, 396, 138, 0 ),
+    1255             :   INST(Vpbroadcastd    , VexRm_Lx           , V(660F38,58,_,x,0,0,2,T1S), 0                         , 0 , 0 , 6233, 397, 133, 0 ),
+    1256             :   INST(Vpbroadcastmb2d , VexRm_Lx           , V(F30F38,3A,_,x,_,0,_,_  ), 0                         , 0 , 0 , 6246, 398, 139, 0 ),
+    1257             :   INST(Vpbroadcastmb2q , VexRm_Lx           , V(F30F38,2A,_,x,_,1,_,_  ), 0                         , 0 , 0 , 6262, 398, 139, 0 ),
+    1258             :   INST(Vpbroadcastq    , VexRm_Lx           , V(660F38,59,_,x,0,1,3,T1S), 0                         , 0 , 0 , 6278, 399, 133, 0 ),
+    1259             :   INST(Vpbroadcastw    , VexRm_Lx           , V(660F38,79,_,x,0,0,1,T1S), 0                         , 0 , 0 , 6291, 400, 138, 0 ),
+    1260             :   INST(Vpclmulqdq      , VexRvmi            , V(660F3A,44,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6304, 310, 140, 47),
+    1261             :   INST(Vpcmov          , VexRvrmRvmr_Lx     , V(XOP_M8,A2,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6315, 326, 132, 0 ),
+    1262             :   INST(Vpcmpb          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6322, 401, 122, 0 ),
+    1263             :   INST(Vpcmpd          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6329, 402, 120, 0 ),
+    1264             :   INST(Vpcmpeqb        , VexRvm_Lx          , V(660F00,74,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6336, 403, 137, 48),
+    1265             :   INST(Vpcmpeqd        , VexRvm_Lx          , V(660F00,76,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6345, 404, 125, 48),
+    1266             :   INST(Vpcmpeqq        , VexRvm_Lx          , V(660F38,29,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6354, 405, 125, 48),
+    1267             :   INST(Vpcmpeqw        , VexRvm_Lx          , V(660F00,75,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6363, 403, 137, 48),
+    1268             :   INST(Vpcmpestri      , VexRmi             , V(660F3A,61,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6372, 406, 141, 49),
+    1269             :   INST(Vpcmpestrm      , VexRmi             , V(660F3A,60,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6383, 407, 141, 49),
+    1270             :   INST(Vpcmpgtb        , VexRvm_Lx          , V(660F00,64,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6394, 403, 137, 48),
+    1271             :   INST(Vpcmpgtd        , VexRvm_Lx          , V(660F00,66,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6403, 404, 125, 48),
+    1272             :   INST(Vpcmpgtq        , VexRvm_Lx          , V(660F38,37,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6412, 405, 125, 48),
+    1273             :   INST(Vpcmpgtw        , VexRvm_Lx          , V(660F00,65,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6421, 403, 137, 48),
+    1274             :   INST(Vpcmpistri      , VexRmi             , V(660F3A,63,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6430, 408, 141, 49),
+    1275             :   INST(Vpcmpistrm      , VexRmi             , V(660F3A,62,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6441, 409, 141, 49),
+    1276             :   INST(Vpcmpq          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6452, 410, 120, 0 ),
+    1277             :   INST(Vpcmpub         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6459, 401, 122, 0 ),
+    1278             :   INST(Vpcmpud         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6467, 402, 120, 0 ),
+    1279             :   INST(Vpcmpuq         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6475, 410, 120, 0 ),
+    1280             :   INST(Vpcmpuw         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6483, 410, 122, 0 ),
+    1281             :   INST(Vpcmpw          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6491, 410, 122, 0 ),
+    1282             :   INST(Vpcomb          , VexRvmi            , V(XOP_M8,CC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6498, 310, 132, 0 ),
+    1283             :   INST(Vpcomd          , VexRvmi            , V(XOP_M8,CE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6505, 310, 132, 0 ),
+    1284             :   INST(Vpcompressd     , VexMr_Lx           , V(660F38,8B,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6512, 279, 120, 0 ),
+    1285             :   INST(Vpcompressq     , VexMr_Lx           , V(660F38,8B,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6524, 279, 120, 0 ),
+    1286             :   INST(Vpcomq          , VexRvmi            , V(XOP_M8,CF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6536, 310, 132, 0 ),
+    1287             :   INST(Vpcomub         , VexRvmi            , V(XOP_M8,EC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6543, 310, 132, 0 ),
+    1288             :   INST(Vpcomud         , VexRvmi            , V(XOP_M8,EE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6551, 310, 132, 0 ),
+    1289             :   INST(Vpcomuq         , VexRvmi            , V(XOP_M8,EF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6559, 310, 132, 0 ),
+    1290             :   INST(Vpcomuw         , VexRvmi            , V(XOP_M8,ED,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6567, 310, 132, 0 ),
+    1291             :   INST(Vpcomw          , VexRvmi            , V(XOP_M8,CD,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6575, 310, 132, 0 ),
+    1292             :   INST(Vpconflictd     , VexRm_Lx           , V(660F38,C4,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6582, 411, 139, 0 ),
+    1293             :   INST(Vpconflictq     , VexRm_Lx           , V(660F38,C4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6594, 411, 139, 0 ),
+    1294             :   INST(Vperm2f128      , VexRvmi            , V(660F3A,06,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6606, 412, 118, 0 ),
+    1295             :   INST(Vperm2i128      , VexRvmi            , V(660F3A,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6617, 412, 124, 0 ),
+    1296             :   INST(Vpermb          , VexRvm_Lx          , V(660F38,8D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6628, 260, 142, 0 ),
+    1297             :   INST(Vpermd          , VexRvm_Lx          , V(660F38,36,_,x,0,0,4,FV ), 0                         , 0 , 0 , 6635, 413, 133, 0 ),
+    1298             :   INST(Vpermi2b        , VexRvm_Lx          , V(660F38,75,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6642, 260, 142, 0 ),
+    1299             :   INST(Vpermi2d        , VexRvm_Lx          , V(660F38,76,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6651, 414, 120, 0 ),
+    1300             :   INST(Vpermi2pd       , VexRvm_Lx          , V(660F38,77,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6660, 262, 120, 0 ),
+    1301             :   INST(Vpermi2ps       , VexRvm_Lx          , V(660F38,77,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6670, 261, 120, 0 ),
+    1302             :   INST(Vpermi2q        , VexRvm_Lx          , V(660F38,76,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6680, 415, 120, 0 ),
+    1303             :   INST(Vpermi2w        , VexRvm_Lx          , V(660F38,75,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6689, 416, 122, 0 ),
+    1304             :   INST(Vpermil2pd      , VexRvrmiRvmri_Lx   , V(660F3A,49,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6698, 417, 132, 0 ),
+    1305             :   INST(Vpermil2ps      , VexRvrmiRvmri_Lx   , V(660F3A,48,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6709, 417, 132, 0 ),
+    1306             :   INST(Vpermilpd       , VexRvmRmi_Lx       , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 0 , 0 , 6720, 418, 116, 0 ),
+    1307             :   INST(Vpermilps       , VexRvmRmi_Lx       , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 0 , 0 , 6730, 419, 116, 0 ),
+    1308             :   INST(Vpermpd         , VexRmi             , V(660F3A,01,_,1,1,_,_,_  ), 0                         , 0 , 0 , 6740, 420, 124, 0 ),
+    1309             :   INST(Vpermps         , VexRvm             , V(660F38,16,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6748, 421, 124, 0 ),
+    1310             :   INST(Vpermq          , VexRvmRmi_Lx       , V(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 0 , 0 , 6756, 422, 133, 0 ),
+    1311             :   INST(Vpermt2b        , VexRvm_Lx          , V(660F38,7D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6763, 260, 142, 0 ),
+    1312             :   INST(Vpermt2d        , VexRvm_Lx          , V(660F38,7E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6772, 414, 120, 0 ),
+    1313             :   INST(Vpermt2pd       , VexRvm_Lx          , V(660F38,7F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6781, 415, 120, 0 ),
+    1314             :   INST(Vpermt2ps       , VexRvm_Lx          , V(660F38,7F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6791, 414, 120, 0 ),
+    1315             :   INST(Vpermt2q        , VexRvm_Lx          , V(660F38,7E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6801, 415, 120, 0 ),
+    1316             :   INST(Vpermt2w        , VexRvm_Lx          , V(660F38,7D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6810, 416, 122, 0 ),
+    1317             :   INST(Vpermw          , VexRvm_Lx          , V(660F38,8D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6819, 260, 122, 0 ),
+    1318             :   INST(Vpexpandd       , VexRm_Lx           , V(660F38,89,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6826, 313, 120, 0 ),
+    1319             :   INST(Vpexpandq       , VexRm_Lx           , V(660F38,89,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6836, 313, 120, 0 ),
+    1320             :   INST(Vpextrb         , VexMri             , V(660F3A,14,_,0,0,I,0,T1S), 0                         , 0 , 0 , 6846, 423, 143, 50),
+    1321             :   INST(Vpextrd         , VexMri             , V(660F3A,16,_,0,0,0,2,T1S), 0                         , 0 , 0 , 6854, 317, 144, 50),
+    1322             :   INST(Vpextrq         , VexMri             , V(660F3A,16,_,0,1,1,3,T1S), 0                         , 0 , 0 , 6862, 424, 144, 50),
+    1323             :   INST(Vpextrw         , VexMri             , V(660F3A,15,_,0,0,I,1,T1S), 0                         , 0 , 0 , 6870, 425, 143, 50),
+    1324             :   INST(Vpgatherdd      , VexRmvRm_VM        , V(660F38,90,_,x,0,_,_,_  ), V(660F38,90,_,x,_,0,2,T1S), 0 , 0 , 6878, 426, 133, 0 ),
+    1325             :   INST(Vpgatherdq      , VexRmvRm_VM        , V(660F38,90,_,x,1,_,_,_  ), V(660F38,90,_,x,_,1,3,T1S), 0 , 0 , 6889, 427, 133, 0 ),
+    1326             :   INST(Vpgatherqd      , VexRmvRm_VM        , V(660F38,91,_,x,0,_,_,_  ), V(660F38,91,_,x,_,0,2,T1S), 0 , 0 , 6900, 428, 133, 0 ),
+    1327             :   INST(Vpgatherqq      , VexRmvRm_VM        , V(660F38,91,_,x,1,_,_,_  ), V(660F38,91,_,x,_,1,3,T1S), 0 , 0 , 6911, 429, 133, 0 ),
+    1328             :   INST(Vphaddbd        , VexRm              , V(XOP_M9,C2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6922, 252, 132, 0 ),
+    1329             :   INST(Vphaddbq        , VexRm              , V(XOP_M9,C3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6931, 252, 132, 0 ),
+    1330             :   INST(Vphaddbw        , VexRm              , V(XOP_M9,C1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6940, 252, 132, 0 ),
+    1331             :   INST(Vphaddd         , VexRvm_Lx          , V(660F38,02,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6949, 250, 135, 51),
+    1332             :   INST(Vphadddq        , VexRm              , V(XOP_M9,CB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6957, 252, 132, 0 ),
+    1333             :   INST(Vphaddsw        , VexRvm_Lx          , V(660F38,03,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6966, 250, 135, 52),
+    1334             :   INST(Vphaddubd       , VexRm              , V(XOP_M9,D2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6975, 252, 132, 0 ),
+    1335             :   INST(Vphaddubq       , VexRm              , V(XOP_M9,D3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6985, 252, 132, 0 ),
+    1336             :   INST(Vphaddubw       , VexRm              , V(XOP_M9,D1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6995, 252, 132, 0 ),
+    1337             :   INST(Vphaddudq       , VexRm              , V(XOP_M9,DB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7005, 252, 132, 0 ),
+    1338             :   INST(Vphadduwd       , VexRm              , V(XOP_M9,D6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7015, 252, 132, 0 ),
+    1339             :   INST(Vphadduwq       , VexRm              , V(XOP_M9,D7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7025, 252, 132, 0 ),
+    1340             :   INST(Vphaddw         , VexRvm_Lx          , V(660F38,01,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7035, 250, 135, 53),
+    1341             :   INST(Vphaddwd        , VexRm              , V(XOP_M9,C6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7043, 252, 132, 0 ),
+    1342             :   INST(Vphaddwq        , VexRm              , V(XOP_M9,C7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7052, 252, 132, 0 ),
+    1343             :   INST(Vphminposuw     , VexRm              , V(660F38,41,_,0,I,_,_,_  ), 0                         , 0 , 0 , 7061, 252, 118, 54),
+    1344             :   INST(Vphsubbw        , VexRm              , V(XOP_M9,E1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7073, 252, 132, 0 ),
+    1345             :   INST(Vphsubd         , VexRvm_Lx          , V(660F38,06,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7082, 250, 135, 55),
+    1346             :   INST(Vphsubdq        , VexRm              , V(XOP_M9,E3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7090, 252, 132, 0 ),
+    1347             :   INST(Vphsubsw        , VexRvm_Lx          , V(660F38,07,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7099, 250, 135, 56),
+    1348             :   INST(Vphsubw         , VexRvm_Lx          , V(660F38,05,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7108, 250, 135, 56),
+    1349             :   INST(Vphsubwd        , VexRm              , V(XOP_M9,E2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7116, 252, 132, 0 ),
+    1350             :   INST(Vpinsrb         , VexRvmi            , V(660F3A,20,_,0,0,I,0,T1S), 0                         , 0 , 0 , 7125, 430, 143, 57),
+    1351             :   INST(Vpinsrd         , VexRvmi            , V(660F3A,22,_,0,0,0,2,T1S), 0                         , 0 , 0 , 7133, 431, 144, 57),
+    1352             :   INST(Vpinsrq         , VexRvmi            , V(660F3A,22,_,0,1,1,3,T1S), 0                         , 0 , 0 , 7141, 432, 144, 57),
+    1353             :   INST(Vpinsrw         , VexRvmi            , V(660F00,C4,_,0,0,I,1,T1S), 0                         , 0 , 0 , 7149, 433, 143, 55),
+    1354             :   INST(Vplzcntd        , VexRm_Lx           , V(660F38,44,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7157, 411, 139, 0 ),
+    1355             :   INST(Vplzcntq        , VexRm_Lx           , V(660F38,44,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7166, 434, 139, 0 ),
+    1356             :   INST(Vpmacsdd        , VexRvmr            , V(XOP_M8,9E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7175, 435, 132, 0 ),
+    1357             :   INST(Vpmacsdqh       , VexRvmr            , V(XOP_M8,9F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7184, 435, 132, 0 ),
+    1358             :   INST(Vpmacsdql       , VexRvmr            , V(XOP_M8,97,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7194, 435, 132, 0 ),
+    1359             :   INST(Vpmacssdd       , VexRvmr            , V(XOP_M8,8E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7204, 435, 132, 0 ),
+    1360             :   INST(Vpmacssdqh      , VexRvmr            , V(XOP_M8,8F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7214, 435, 132, 0 ),
+    1361             :   INST(Vpmacssdql      , VexRvmr            , V(XOP_M8,87,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7225, 435, 132, 0 ),
+    1362             :   INST(Vpmacsswd       , VexRvmr            , V(XOP_M8,86,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7236, 435, 132, 0 ),
+    1363             :   INST(Vpmacssww       , VexRvmr            , V(XOP_M8,85,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7246, 435, 132, 0 ),
+    1364             :   INST(Vpmacswd        , VexRvmr            , V(XOP_M8,96,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7256, 435, 132, 0 ),
+    1365             :   INST(Vpmacsww        , VexRvmr            , V(XOP_M8,95,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7265, 435, 132, 0 ),
+    1366             :   INST(Vpmadcsswd      , VexRvmr            , V(XOP_M8,A6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7274, 435, 132, 0 ),
+    1367             :   INST(Vpmadcswd       , VexRvmr            , V(XOP_M8,B6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7285, 435, 132, 0 ),
+    1368             :   INST(Vpmadd52huq     , VexRvm_Lx          , V(660F38,B5,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7295, 262, 145, 0 ),
+    1369             :   INST(Vpmadd52luq     , VexRvm_Lx          , V(660F38,B4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7307, 262, 145, 0 ),
+    1370             :   INST(Vpmaddubsw      , VexRvm_Lx          , V(660F38,04,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7319, 388, 137, 58),
+    1371             :   INST(Vpmaddwd        , VexRvm_Lx          , V(660F00,F5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7330, 388, 137, 58),
+    1372             :   INST(Vpmaskmovd      , VexRvmMvr_Lx       , V(660F38,8C,_,x,0,_,_,_  ), V(660F38,8E,_,x,0,_,_,_  ), 0 , 0 , 7339, 436, 124, 0 ),
+    1373             :   INST(Vpmaskmovq      , VexRvmMvr_Lx       , V(660F38,8C,_,x,1,_,_,_  ), V(660F38,8E,_,x,1,_,_,_  ), 0 , 0 , 7350, 437, 124, 0 ),
+    1374             :   INST(Vpmaxsb         , VexRvm_Lx          , V(660F38,3C,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7361, 438, 137, 59),
+    1375             :   INST(Vpmaxsd         , VexRvm_Lx          , V(660F38,3D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7369, 259, 125, 59),
+    1376             :   INST(Vpmaxsq         , VexRvm_Lx          , V(660F38,3D,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7377, 262, 120, 0 ),
+    1377             :   INST(Vpmaxsw         , VexRvm_Lx          , V(660F00,EE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7385, 438, 137, 60),
+    1378             :   INST(Vpmaxub         , VexRvm_Lx          , V(660F00,DE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7393, 438, 137, 60),
+    1379             :   INST(Vpmaxud         , VexRvm_Lx          , V(660F38,3F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7401, 259, 125, 60),
+    1380             :   INST(Vpmaxuq         , VexRvm_Lx          , V(660F38,3F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7409, 262, 120, 0 ),
+    1381             :   INST(Vpmaxuw         , VexRvm_Lx          , V(660F38,3E,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7417, 438, 137, 61),
+    1382             :   INST(Vpminsb         , VexRvm_Lx          , V(660F38,38,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7425, 438, 137, 61),
+    1383             :   INST(Vpminsd         , VexRvm_Lx          , V(660F38,39,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7433, 259, 125, 61),
+    1384             :   INST(Vpminsq         , VexRvm_Lx          , V(660F38,39,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7441, 262, 120, 0 ),
+    1385             :   INST(Vpminsw         , VexRvm_Lx          , V(660F00,EA,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7449, 438, 137, 62),
+    1386             :   INST(Vpminub         , VexRvm_Lx          , V(660F00,DA,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7457, 438, 137, 62),
+    1387             :   INST(Vpminud         , VexRvm_Lx          , V(660F38,3B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7465, 259, 125, 62),
+    1388             :   INST(Vpminuq         , VexRvm_Lx          , V(660F38,3B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7473, 262, 120, 0 ),
+    1389             :   INST(Vpminuw         , VexRvm_Lx          , V(660F38,3A,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7481, 438, 137, 63),
+    1390             :   INST(Vpmovb2m        , VexRm_Lx           , V(F30F38,29,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7489, 439, 122, 0 ),
+    1391             :   INST(Vpmovd2m        , VexRm_Lx           , V(F30F38,39,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7498, 439, 123, 0 ),
+    1392             :   INST(Vpmovdb         , VexMr_Lx           , V(F30F38,31,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7507, 440, 120, 0 ),
+    1393             :   INST(Vpmovdw         , VexMr_Lx           , V(F30F38,33,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7515, 441, 120, 0 ),
+    1394             :   INST(Vpmovm2b        , VexRm_Lx           , V(F30F38,28,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7523, 398, 122, 0 ),
+    1395             :   INST(Vpmovm2d        , VexRm_Lx           , V(F30F38,38,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7532, 398, 123, 0 ),
+    1396             :   INST(Vpmovm2q        , VexRm_Lx           , V(F30F38,38,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7541, 398, 123, 0 ),
+    1397             :   INST(Vpmovm2w        , VexRm_Lx           , V(F30F38,28,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7550, 398, 122, 0 ),
+    1398             :   INST(Vpmovmskb       , VexRm_Lx           , V(660F00,D7,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7559, 378, 135, 64),
+    1399             :   INST(Vpmovq2m        , VexRm_Lx           , V(F30F38,39,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7569, 439, 123, 0 ),
+    1400             :   INST(Vpmovqb         , VexMr_Lx           , V(F30F38,32,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7578, 442, 120, 0 ),
+    1401             :   INST(Vpmovqd         , VexMr_Lx           , V(F30F38,35,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7586, 441, 120, 0 ),
+    1402             :   INST(Vpmovqw         , VexMr_Lx           , V(F30F38,34,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7594, 440, 120, 0 ),
+    1403             :   INST(Vpmovsdb        , VexMr_Lx           , V(F30F38,21,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7602, 440, 120, 0 ),
+    1404             :   INST(Vpmovsdw        , VexMr_Lx           , V(F30F38,23,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7611, 441, 120, 0 ),
+    1405             :   INST(Vpmovsqb        , VexMr_Lx           , V(F30F38,22,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7620, 442, 120, 0 ),
+    1406             :   INST(Vpmovsqd        , VexMr_Lx           , V(F30F38,25,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7629, 441, 120, 0 ),
+    1407             :   INST(Vpmovsqw        , VexMr_Lx           , V(F30F38,24,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7638, 440, 120, 0 ),
+    1408             :   INST(Vpmovswb        , VexMr_Lx           , V(F30F38,20,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7647, 441, 122, 0 ),
+    1409             :   INST(Vpmovsxbd       , VexRm_Lx           , V(660F38,21,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7656, 443, 125, 14),
+    1410             :   INST(Vpmovsxbq       , VexRm_Lx           , V(660F38,22,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7666, 444, 125, 14),
+    1411             :   INST(Vpmovsxbw       , VexRm_Lx           , V(660F38,20,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7676, 445, 137, 14),
+    1412             :   INST(Vpmovsxdq       , VexRm_Lx           , V(660F38,25,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7686, 446, 125, 14),
+    1413             :   INST(Vpmovsxwd       , VexRm_Lx           , V(660F38,23,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7696, 445, 125, 14),
+    1414             :   INST(Vpmovsxwq       , VexRm_Lx           , V(660F38,24,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7706, 443, 125, 14),
+    1415             :   INST(Vpmovusdb       , VexMr_Lx           , V(F30F38,11,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7716, 440, 120, 0 ),
+    1416             :   INST(Vpmovusdw       , VexMr_Lx           , V(F30F38,13,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7726, 441, 120, 0 ),
+    1417             :   INST(Vpmovusqb       , VexMr_Lx           , V(F30F38,12,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7736, 442, 120, 0 ),
+    1418             :   INST(Vpmovusqd       , VexMr_Lx           , V(F30F38,15,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7746, 441, 120, 0 ),
+    1419             :   INST(Vpmovusqw       , VexMr_Lx           , V(F30F38,14,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7756, 440, 120, 0 ),
+    1420             :   INST(Vpmovuswb       , VexMr_Lx           , V(F30F38,10,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7766, 441, 122, 0 ),
+    1421             :   INST(Vpmovw2m        , VexRm_Lx           , V(F30F38,29,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7776, 439, 122, 0 ),
+    1422             :   INST(Vpmovwb         , VexMr_Lx           , V(F30F38,30,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7785, 441, 122, 0 ),
+    1423             :   INST(Vpmovzxbd       , VexRm_Lx           , V(660F38,31,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7793, 443, 125, 65),
+    1424             :   INST(Vpmovzxbq       , VexRm_Lx           , V(660F38,32,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7803, 444, 125, 65),
+    1425             :   INST(Vpmovzxbw       , VexRm_Lx           , V(660F38,30,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7813, 445, 137, 65),
+    1426             :   INST(Vpmovzxdq       , VexRm_Lx           , V(660F38,35,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7823, 446, 125, 65),
+    1427             :   INST(Vpmovzxwd       , VexRm_Lx           , V(660F38,33,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7833, 445, 125, 65),
+    1428             :   INST(Vpmovzxwq       , VexRm_Lx           , V(660F38,34,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7843, 443, 125, 65),
+    1429             :   INST(Vpmuldq         , VexRvm_Lx          , V(660F38,28,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7853, 256, 125, 19),
+    1430             :   INST(Vpmulhrsw       , VexRvm_Lx          , V(660F38,0B,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7861, 388, 137, 19),
+    1431             :   INST(Vpmulhuw        , VexRvm_Lx          , V(660F00,E4,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7871, 388, 137, 66),
+    1432             :   INST(Vpmulhw         , VexRvm_Lx          , V(660F00,E5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7880, 388, 137, 66),
+    1433             :   INST(Vpmulld         , VexRvm_Lx          , V(660F38,40,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7888, 257, 125, 66),
+    1434             :   INST(Vpmullq         , VexRvm_Lx          , V(660F38,40,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7896, 262, 123, 0 ),
+    1435             :   INST(Vpmullw         , VexRvm_Lx          , V(660F00,D5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7904, 388, 137, 19),
+    1436             :   INST(Vpmultishiftqb  , VexRvm_Lx          , V(660F38,83,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7912, 262, 142, 0 ),
+    1437             :   INST(Vpmuludq        , VexRvm_Lx          , V(660F00,F4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7927, 256, 125, 67),
+    1438             :   INST(Vpopcntd        , VexRm              , V(660F38,55,_,2,_,0,4,FVM), 0                         , 0 , 0 , 7936, 447, 146, 0 ),
+    1439             :   INST(Vpopcntq        , VexRm              , V(660F38,55,_,2,_,1,4,FVM), 0                         , 0 , 0 , 7945, 448, 146, 0 ),
+    1440             :   INST(Vpor            , VexRvm_Lx          , V(660F00,EB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7954, 390, 135, 68),
+    1441             :   INST(Vpord           , VexRvm_Lx          , V(660F00,EB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7959, 391, 120, 0 ),
+    1442             :   INST(Vporq           , VexRvm_Lx          , V(660F00,EB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7965, 395, 120, 0 ),
+    1443             :   INST(Vpperm          , VexRvrmRvmr        , V(XOP_M8,A3,_,0,x,_,_,_  ), 0                         , 0 , 0 , 7971, 449, 132, 0 ),
+    1444             :   INST(Vprold          , VexVmi_Lx          , V(660F00,72,1,x,_,0,4,FV ), 0                         , 0 , 0 , 7978, 450, 120, 0 ),
+    1445             :   INST(Vprolq          , VexVmi_Lx          , V(660F00,72,1,x,_,1,4,FV ), 0                         , 0 , 0 , 7985, 451, 120, 0 ),
+    1446             :   INST(Vprolvd         , VexRvm_Lx          , V(660F38,15,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7992, 261, 120, 0 ),
+    1447             :   INST(Vprolvq         , VexRvm_Lx          , V(660F38,15,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8000, 262, 120, 0 ),
+    1448             :   INST(Vprord          , VexVmi_Lx          , V(660F00,72,0,x,_,0,4,FV ), 0                         , 0 , 0 , 8008, 450, 120, 0 ),
+    1449             :   INST(Vprorq          , VexVmi_Lx          , V(660F00,72,0,x,_,1,4,FV ), 0                         , 0 , 0 , 8015, 451, 120, 0 ),
+    1450             :   INST(Vprorvd         , VexRvm_Lx          , V(660F38,14,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8022, 261, 120, 0 ),
+    1451             :   INST(Vprorvq         , VexRvm_Lx          , V(660F38,14,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8030, 262, 120, 0 ),
+    1452             :   INST(Vprotb          , VexRvmRmvRmi       , V(XOP_M9,90,_,0,x,_,_,_  ), V(XOP_M8,C0,_,0,x,_,_,_  ), 0 , 0 , 8038, 452, 132, 0 ),
+    1453             :   INST(Vprotd          , VexRvmRmvRmi       , V(XOP_M9,92,_,0,x,_,_,_  ), V(XOP_M8,C2,_,0,x,_,_,_  ), 0 , 0 , 8045, 453, 132, 0 ),
+    1454             :   INST(Vprotq          , VexRvmRmvRmi       , V(XOP_M9,93,_,0,x,_,_,_  ), V(XOP_M8,C3,_,0,x,_,_,_  ), 0 , 0 , 8052, 454, 132, 0 ),
+    1455             :   INST(Vprotw          , VexRvmRmvRmi       , V(XOP_M9,91,_,0,x,_,_,_  ), V(XOP_M8,C1,_,0,x,_,_,_  ), 0 , 0 , 8059, 455, 132, 0 ),
+    1456             :   INST(Vpsadbw         , VexRvm_Lx          , V(660F00,F6,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8066, 456, 137, 69),
+    1457             :   INST(Vpscatterdd     , VexMr_VM           , V(660F38,A0,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8074, 457, 120, 0 ),
+    1458             :   INST(Vpscatterdq     , VexMr_VM           , V(660F38,A0,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8086, 457, 120, 0 ),
+    1459             :   INST(Vpscatterqd     , VexMr_VM           , V(660F38,A1,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8098, 458, 120, 0 ),
+    1460             :   INST(Vpscatterqq     , VexMr_VM           , V(660F38,A1,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8110, 459, 120, 0 ),
+    1461             :   INST(Vpshab          , VexRvmRmv          , V(XOP_M9,98,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8122, 460, 132, 0 ),
+    1462             :   INST(Vpshad          , VexRvmRmv          , V(XOP_M9,9A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8129, 460, 132, 0 ),
+    1463             :   INST(Vpshaq          , VexRvmRmv          , V(XOP_M9,9B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8136, 460, 132, 0 ),
+    1464             :   INST(Vpshaw          , VexRvmRmv          , V(XOP_M9,99,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8143, 460, 132, 0 ),
+    1465             :   INST(Vpshlb          , VexRvmRmv          , V(XOP_M9,94,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8150, 460, 132, 0 ),
+    1466             :   INST(Vpshld          , VexRvmRmv          , V(XOP_M9,96,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8157, 460, 132, 0 ),
+    1467             :   INST(Vpshlq          , VexRvmRmv          , V(XOP_M9,97,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8164, 460, 132, 0 ),
+    1468             :   INST(Vpshlw          , VexRvmRmv          , V(XOP_M9,95,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8171, 460, 132, 0 ),
+    1469             :   INST(Vpshufb         , VexRvm_Lx          , V(660F38,00,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8178, 388, 137, 70),
+    1470             :   INST(Vpshufd         , VexRmi_Lx          , V(660F00,70,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8186, 461, 125, 71),
+    1471             :   INST(Vpshufhw        , VexRmi_Lx          , V(F30F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8194, 462, 137, 71),
+    1472             :   INST(Vpshuflw        , VexRmi_Lx          , V(F20F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8203, 462, 137, 71),
+    1473             :   INST(Vpsignb         , VexRvm_Lx          , V(660F38,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8212, 250, 135, 72),
+    1474             :   INST(Vpsignd         , VexRvm_Lx          , V(660F38,0A,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8220, 250, 135, 72),
+    1475             :   INST(Vpsignw         , VexRvm_Lx          , V(660F38,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8228, 250, 135, 72),
+    1476             :   INST(Vpslld          , VexRvmVmi_Lx       , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 0 , 0 , 8236, 463, 125, 72),
+    1477             :   INST(Vpslldq         , VexEvexVmi_Lx      , V(660F00,73,7,x,I,I,4,FVM), 0                         , 0 , 0 , 8243, 464, 137, 72),
+    1478             :   INST(Vpsllq          , VexRvmVmi_Lx       , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 0 , 0 , 8251, 465, 125, 72),
+    1479             :   INST(Vpsllvd         , VexRvm_Lx          , V(660F38,47,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8258, 257, 133, 0 ),
+    1480             :   INST(Vpsllvq         , VexRvm_Lx          , V(660F38,47,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8266, 256, 133, 0 ),
+    1481             :   INST(Vpsllvw         , VexRvm_Lx          , V(660F38,12,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8274, 260, 122, 0 ),
+    1482             :   INST(Vpsllw          , VexRvmVmi_Lx       , V(660F00,F1,_,x,I,I,4,FVM), V(660F00,71,6,x,I,I,4,FVM), 0 , 0 , 8282, 466, 137, 73),
+    1483             :   INST(Vpsrad          , VexRvmVmi_Lx       , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 0 , 0 , 8289, 467, 125, 73),
+    1484             :   INST(Vpsraq          , VexRvmVmi_Lx       , V(660F00,E2,_,x,_,1,4,128), V(660F00,72,4,x,_,1,4,FV ), 0 , 0 , 8296, 468, 120, 0 ),
+    1485             :   INST(Vpsravd         , VexRvm_Lx          , V(660F38,46,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8303, 257, 133, 0 ),
+    1486             :   INST(Vpsravq         , VexRvm_Lx          , V(660F38,46,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8311, 262, 120, 0 ),
+    1487             :   INST(Vpsravw         , VexRvm_Lx          , V(660F38,11,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8319, 260, 122, 0 ),
+    1488             :   INST(Vpsraw          , VexRvmVmi_Lx       , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 0 , 0 , 8327, 469, 137, 74),
+    1489             :   INST(Vpsrld          , VexRvmVmi_Lx       , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 0 , 0 , 8334, 470, 125, 74),
+    1490             :   INST(Vpsrldq         , VexEvexVmi_Lx      , V(660F00,73,3,x,I,I,4,FVM), 0                         , 0 , 0 , 8341, 464, 137, 74),
+    1491             :   INST(Vpsrlq          , VexRvmVmi_Lx       , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 0 , 0 , 8349, 471, 125, 74),
+    1492             :   INST(Vpsrlvd         , VexRvm_Lx          , V(660F38,45,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8356, 257, 133, 0 ),
+    1493             :   INST(Vpsrlvq         , VexRvm_Lx          , V(660F38,45,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8364, 256, 133, 0 ),
+    1494             :   INST(Vpsrlvw         , VexRvm_Lx          , V(660F38,10,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8372, 260, 122, 0 ),
+    1495             :   INST(Vpsrlw          , VexRvmVmi_Lx       , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 0 , 0 , 8380, 472, 137, 75),
+    1496             :   INST(Vpsubb          , VexRvm_Lx          , V(660F00,F8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8387, 473, 137, 75),
+    1497             :   INST(Vpsubd          , VexRvm_Lx          , V(660F00,FA,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8394, 474, 125, 75),
+    1498             :   INST(Vpsubq          , VexRvm_Lx          , V(660F00,FB,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8401, 475, 125, 75),
+    1499             :   INST(Vpsubsb         , VexRvm_Lx          , V(660F00,E8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8408, 473, 137, 75),
+    1500             :   INST(Vpsubsw         , VexRvm_Lx          , V(660F00,E9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8416, 473, 137, 75),
+    1501             :   INST(Vpsubusb        , VexRvm_Lx          , V(660F00,D8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8424, 473, 137, 75),
+    1502             :   INST(Vpsubusw        , VexRvm_Lx          , V(660F00,D9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8433, 473, 137, 75),
+    1503             :   INST(Vpsubw          , VexRvm_Lx          , V(660F00,F9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8442, 473, 137, 75),
+    1504             :   INST(Vpternlogd      , VexRvmi_Lx         , V(660F3A,25,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8449, 476, 120, 0 ),
+    1505             :   INST(Vpternlogq      , VexRvmi_Lx         , V(660F3A,25,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8460, 477, 120, 0 ),
+    1506             :   INST(Vptest          , VexRm_Lx           , V(660F38,17,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8471, 478, 141, 76),
+    1507             :   INST(Vptestmb        , VexRvm_Lx          , V(660F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8478, 479, 122, 0 ),
+    1508             :   INST(Vptestmd        , VexRvm_Lx          , V(660F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8487, 480, 120, 0 ),
+    1509             :   INST(Vptestmq        , VexRvm_Lx          , V(660F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8496, 481, 120, 0 ),
+    1510             :   INST(Vptestmw        , VexRvm_Lx          , V(660F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8505, 479, 122, 0 ),
+    1511             :   INST(Vptestnmb       , VexRvm_Lx          , V(F30F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8514, 479, 122, 0 ),
+    1512             :   INST(Vptestnmd       , VexRvm_Lx          , V(F30F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8524, 480, 120, 0 ),
+    1513             :   INST(Vptestnmq       , VexRvm_Lx          , V(F30F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8534, 481, 120, 0 ),
+    1514             :   INST(Vptestnmw       , VexRvm_Lx          , V(F30F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8544, 479, 122, 0 ),
+    1515             :   INST(Vpunpckhbw      , VexRvm_Lx          , V(660F00,68,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8554, 388, 137, 77),
+    1516             :   INST(Vpunpckhdq      , VexRvm_Lx          , V(660F00,6A,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8565, 257, 125, 77),
+    1517             :   INST(Vpunpckhqdq     , VexRvm_Lx          , V(660F00,6D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8576, 256, 125, 77),
+    1518             :   INST(Vpunpckhwd      , VexRvm_Lx          , V(660F00,69,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8588, 388, 137, 77),
+    1519             :   INST(Vpunpcklbw      , VexRvm_Lx          , V(660F00,60,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8599, 388, 137, 77),
+    1520             :   INST(Vpunpckldq      , VexRvm_Lx          , V(660F00,62,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8610, 257, 125, 77),
+    1521             :   INST(Vpunpcklqdq     , VexRvm_Lx          , V(660F00,6C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8621, 256, 125, 77),
+    1522             :   INST(Vpunpcklwd      , VexRvm_Lx          , V(660F00,61,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8633, 388, 137, 77),
+    1523             :   INST(Vpxor           , VexRvm_Lx          , V(660F00,EF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8644, 392, 135, 78),
+    1524             :   INST(Vpxord          , VexRvm_Lx          , V(660F00,EF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8650, 393, 120, 0 ),
+    1525             :   INST(Vpxorq          , VexRvm_Lx          , V(660F00,EF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8657, 394, 120, 0 ),
+    1526             :   INST(Vrangepd        , VexRvmi_Lx         , V(660F3A,50,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8664, 482, 123, 0 ),
+    1527             :   INST(Vrangeps        , VexRvmi_Lx         , V(660F3A,50,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8673, 483, 123, 0 ),
+    1528             :   INST(Vrangesd        , VexRvmi            , V(660F3A,51,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8682, 484, 63 , 0 ),
+    1529             :   INST(Vrangess        , VexRvmi            , V(660F3A,51,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8691, 485, 63 , 0 ),
+    1530             :   INST(Vrcp14pd        , VexRm_Lx           , V(660F38,4C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8700, 434, 120, 0 ),
+    1531             :   INST(Vrcp14ps        , VexRm_Lx           , V(660F38,4C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8709, 411, 120, 0 ),
+    1532             :   INST(Vrcp14sd        , VexRvm             , V(660F38,4D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8718, 486, 65 , 0 ),
+    1533             :   INST(Vrcp14ss        , VexRvm             , V(660F38,4D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8727, 487, 65 , 0 ),
+    1534             :   INST(Vrcp28pd        , VexRm              , V(660F38,CA,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8736, 311, 128, 0 ),
+    1535             :   INST(Vrcp28ps        , VexRm              , V(660F38,CA,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8745, 312, 128, 0 ),
+    1536             :   INST(Vrcp28sd        , VexRvm             , V(660F38,CB,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8754, 488, 128, 0 ),
+    1537             :   INST(Vrcp28ss        , VexRvm             , V(660F38,CB,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8763, 489, 128, 0 ),
+    1538             :   INST(Vrcpps          , VexRm_Lx           , V(000F00,53,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8772, 333, 118, 79),
+    1539             :   INST(Vrcpss          , VexRvm             , V(F30F00,53,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8779, 490, 118, 80),
+    1540             :   INST(Vreducepd       , VexRmi_Lx          , V(660F3A,56,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8786, 451, 123, 0 ),
+    1541             :   INST(Vreduceps       , VexRmi_Lx          , V(660F3A,56,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8796, 450, 123, 0 ),
+    1542             :   INST(Vreducesd       , VexRvmi            , V(660F3A,57,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8806, 491, 63 , 0 ),
+    1543             :   INST(Vreducess       , VexRvmi            , V(660F3A,57,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8816, 492, 63 , 0 ),
+    1544             :   INST(Vrndscalepd     , VexRmi_Lx          , V(660F3A,09,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8826, 345, 120, 0 ),
+    1545             :   INST(Vrndscaleps     , VexRmi_Lx          , V(660F3A,08,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8838, 346, 120, 0 ),
+    1546             :   INST(Vrndscalesd     , VexRvmi            , V(660F3A,0B,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8850, 484, 65 , 0 ),
+    1547             :   INST(Vrndscaless     , VexRvmi            , V(660F3A,0A,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8862, 485, 65 , 0 ),
+    1548             :   INST(Vroundpd        , VexRmi_Lx          , V(660F3A,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8874, 493, 118, 81),
+    1549             :   INST(Vroundps        , VexRmi_Lx          , V(660F3A,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8883, 493, 118, 81),
+    1550             :   INST(Vroundsd        , VexRvmi            , V(660F3A,0B,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8892, 494, 118, 82),
+    1551             :   INST(Vroundss        , VexRvmi            , V(660F3A,0A,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8901, 495, 118, 82),
+    1552             :   INST(Vrsqrt14pd      , VexRm_Lx           , V(660F38,4E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8910, 434, 120, 0 ),
+    1553             :   INST(Vrsqrt14ps      , VexRm_Lx           , V(660F38,4E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8921, 411, 120, 0 ),
+    1554             :   INST(Vrsqrt14sd      , VexRvm             , V(660F38,4F,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8932, 486, 65 , 0 ),
+    1555             :   INST(Vrsqrt14ss      , VexRvm             , V(660F38,4F,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8943, 487, 65 , 0 ),
+    1556             :   INST(Vrsqrt28pd      , VexRm              , V(660F38,CC,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8954, 311, 128, 0 ),
+    1557             :   INST(Vrsqrt28ps      , VexRm              , V(660F38,CC,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8965, 312, 128, 0 ),
+    1558             :   INST(Vrsqrt28sd      , VexRvm             , V(660F38,CD,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8976, 488, 128, 0 ),
+    1559             :   INST(Vrsqrt28ss      , VexRvm             , V(660F38,CD,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8987, 489, 128, 0 ),
+    1560             :   INST(Vrsqrtps        , VexRm_Lx           , V(000F00,52,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8998, 333, 118, 3 ),
+    1561             :   INST(Vrsqrtss        , VexRvm             , V(F30F00,52,_,I,I,_,_,_  ), 0                         , 0 , 0 , 9007, 490, 118, 2 ),
+    1562             :   INST(Vscalefpd       , VexRvm_Lx          , V(660F38,2C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9016, 496, 120, 0 ),
+    1563             :   INST(Vscalefps       , VexRvm_Lx          , V(660F38,2C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9026, 497, 120, 0 ),
+    1564             :   INST(Vscalefsd       , VexRvm             , V(660F38,2D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 9036, 498, 65 , 0 ),
+    1565             :   INST(Vscalefss       , VexRvm             , V(660F38,2D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 9046, 499, 65 , 0 ),
+    1566             :   INST(Vscatterdpd     , VexMr_Lx           , V(660F38,A2,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9056, 500, 120, 0 ),
+    1567             :   INST(Vscatterdps     , VexMr_Lx           , V(660F38,A2,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9068, 457, 120, 0 ),
+    1568             :   INST(Vscatterpf0dpd  , VexM_VM            , V(660F38,C6,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9080, 338, 134, 0 ),
+    1569             :   INST(Vscatterpf0dps  , VexM_VM            , V(660F38,C6,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9095, 339, 134, 0 ),
+    1570             :   INST(Vscatterpf0qpd  , VexM_VM            , V(660F38,C7,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9110, 340, 134, 0 ),
+    1571             :   INST(Vscatterpf0qps  , VexM_VM            , V(660F38,C7,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9125, 340, 134, 0 ),
+    1572             :   INST(Vscatterpf1dpd  , VexM_VM            , V(660F38,C6,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9140, 338, 134, 0 ),
+    1573             :   INST(Vscatterpf1dps  , VexM_VM            , V(660F38,C6,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9155, 339, 134, 0 ),
+    1574             :   INST(Vscatterpf1qpd  , VexM_VM            , V(660F38,C7,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9170, 340, 134, 0 ),
+    1575             :   INST(Vscatterpf1qps  , VexM_VM            , V(660F38,C7,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9185, 340, 134, 0 ),
+    1576             :   INST(Vscatterqpd     , VexMr_Lx           , V(660F38,A3,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9200, 459, 120, 0 ),
+    1577             :   INST(Vscatterqps     , VexMr_Lx           , V(660F38,A3,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9212, 458, 120, 0 ),
+    1578             :   INST(Vshuff32x4      , VexRvmi_Lx         , V(660F3A,23,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9224, 501, 120, 0 ),
+    1579             :   INST(Vshuff64x2      , VexRvmi_Lx         , V(660F3A,23,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9235, 502, 120, 0 ),
+    1580             :   INST(Vshufi32x4      , VexRvmi_Lx         , V(660F3A,43,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9246, 501, 120, 0 ),
+    1581             :   INST(Vshufi64x2      , VexRvmi_Lx         , V(660F3A,43,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9257, 502, 120, 0 ),
+    1582             :   INST(Vshufpd         , VexRvmi_Lx         , V(660F00,C6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9268, 503, 116, 83),
+    1583             :   INST(Vshufps         , VexRvmi_Lx         , V(000F00,C6,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9276, 504, 116, 83),
+    1584             :   INST(Vsqrtpd         , VexRm_Lx           , V(660F00,51,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9284, 505, 116, 84),
+    1585             :   INST(Vsqrtps         , VexRm_Lx           , V(000F00,51,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9292, 281, 116, 84),
+    1586             :   INST(Vsqrtsd         , VexRvm             , V(F20F00,51,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9300, 248, 117, 85),
+    1587             :   INST(Vsqrtss         , VexRvm             , V(F30F00,51,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9308, 249, 117, 85),
+    1588             :   INST(Vstmxcsr        , VexM               , V(000F00,AE,3,0,I,_,_,_  ), 0                         , 0 , 0 , 9316, 506, 118, 0 ),
+    1589             :   INST(Vsubpd          , VexRvm_Lx          , V(660F00,5C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9325, 246, 116, 86),
+    1590             :   INST(Vsubps          , VexRvm_Lx          , V(000F00,5C,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9332, 247, 116, 86),
+    1591             :   INST(Vsubsd          , VexRvm             , V(F20F00,5C,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9339, 248, 117, 86),
+    1592             :   INST(Vsubss          , VexRvm             , V(F30F00,5C,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9346, 249, 117, 86),
+    1593             :   INST(Vtestpd         , VexRm_Lx           , V(660F38,0F,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9353, 478, 141, 0 ),
+    1594             :   INST(Vtestps         , VexRm_Lx           , V(660F38,0E,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9361, 478, 141, 0 ),
+    1595             :   INST(Vucomisd        , VexRm              , V(660F00,2E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9369, 277, 126, 15),
+    1596             :   INST(Vucomiss        , VexRm              , V(000F00,2E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9378, 278, 126, 15),
+    1597             :   INST(Vunpckhpd       , VexRvm_Lx          , V(660F00,15,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9387, 256, 116, 13),
+    1598             :   INST(Vunpckhps       , VexRvm_Lx          , V(000F00,15,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9397, 257, 116, 13),
+    1599             :   INST(Vunpcklpd       , VexRvm_Lx          , V(660F00,14,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9407, 256, 116, 13),
+    1600             :   INST(Vunpcklps       , VexRvm_Lx          , V(000F00,14,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9417, 257, 116, 13),
+    1601             :   INST(Vxorpd          , VexRvm_Lx          , V(660F00,57,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9427, 475, 121, 87),
+    1602             :   INST(Vxorps          , VexRvm_Lx          , V(000F00,57,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9434, 474, 121, 87),
+    1603             :   INST(Vzeroall        , VexOp              , V(000F00,77,_,1,I,_,_,_  ), 0                         , 0 , 0 , 9441, 507, 118, 0 ),
+    1604             :   INST(Vzeroupper      , VexOp              , V(000F00,77,_,0,I,_,_,_  ), 0                         , 0 , 0 , 9450, 507, 118, 0 ),
+    1605             :   INST(Wbinvd          , X86Op              , O(000F00,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9461, 34 , 23 , 0 ),
+    1606             :   INST(Wrfsbase        , X86M               , O(F30F00,AE,2,_,x,_,_,_  ), 0                         , 0 , 0 , 9468, 508, 98 , 0 ),
+    1607             :   INST(Wrgsbase        , X86M               , O(F30F00,AE,3,_,x,_,_,_  ), 0                         , 0 , 0 , 9477, 508, 98 , 0 ),
+    1608             :   INST(Wrmsr           , X86Op              , O(000F00,30,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9486, 509, 147, 0 ),
+    1609             :   INST(Xabort          , X86Op_O_I8         , O(000000,C6,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9492, 98 , 148, 0 ),
+    1610             :   INST(Xadd            , X86Xadd            , O(000F00,C0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 9499, 510, 36 , 0 ),
+    1611             :   INST(Xbegin          , X86JmpRel          , O(000000,C7,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9504, 511, 148, 0 ),
+    1612             :   INST(Xchg            , X86Xchg            , O(000000,86,_,_,x,_,_,_  ), 0                         , 0 , 0 , 434 , 512, 0  , 0 ),
+    1613             :   INST(Xend            , X86Op              , O(000F01,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9511, 34 , 148, 0 ),
+    1614             :   INST(Xgetbv          , X86Op              , O(000F01,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9516, 227, 149, 0 ),
+    1615             :   INST(Xlatb           , X86Op              , O(000000,D7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9523, 34 , 45 , 0 ),
+    1616             :   INST(Xor             , X86Arith           , O(000000,30,6,_,x,_,_,_  ), 0                         , 0 , 0 , 8646, 243, 1  , 0 ),
+    1617             :   INST(Xorpd           , ExtRm              , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9428, 192, 4  , 87),
+    1618             :   INST(Xorps           , ExtRm              , O(000F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9435, 192, 5  , 87),
+    1619             :   INST(Xrstor          , X86M_Only          , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1105, 513, 149, 0 ),
+    1620             :   INST(Xrstor64        , X86M_Only          , O(000F00,AE,5,_,1,_,_,_  ), 0                         , 0 , 0 , 1113, 514, 149, 0 ),
+    1621             :   INST(Xrstors         , X86M_Only          , O(000F00,C7,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9529, 513, 150, 0 ),
+    1622             :   INST(Xrstors64       , X86M_Only          , O(000F00,C7,3,_,1,_,_,_  ), 0                         , 0 , 0 , 9537, 514, 150, 0 ),
+    1623             :   INST(Xsave           , X86M_Only          , O(000F00,AE,4,_,_,_,_,_  ), 0                         , 0 , 0 , 1123, 515, 149, 0 ),
+    1624             :   INST(Xsave64         , X86M_Only          , O(000F00,AE,4,_,1,_,_,_  ), 0                         , 0 , 0 , 1130, 516, 149, 0 ),
+    1625             :   INST(Xsavec          , X86M_Only          , O(000F00,C7,4,_,_,_,_,_  ), 0                         , 0 , 0 , 9547, 515, 151, 0 ),
+    1626             :   INST(Xsavec64        , X86M_Only          , O(000F00,C7,4,_,1,_,_,_  ), 0                         , 0 , 0 , 9554, 516, 151, 0 ),
+    1627             :   INST(Xsaveopt        , X86M_Only          , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 9563, 515, 152, 0 ),
+    1628             :   INST(Xsaveopt64      , X86M_Only          , O(000F00,AE,6,_,1,_,_,_  ), 0                         , 0 , 0 , 9572, 516, 152, 0 ),
+    1629             :   INST(Xsaves          , X86M_Only          , O(000F00,C7,5,_,_,_,_,_  ), 0                         , 0 , 0 , 9583, 515, 150, 0 ),
+    1630             :   INST(Xsaves64        , X86M_Only          , O(000F00,C7,5,_,1,_,_,_  ), 0                         , 0 , 0 , 9590, 516, 150, 0 ),
+    1631             :   INST(Xsetbv          , X86Op              , O(000F01,D1,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9599, 509, 153, 0 ),
+    1632             :   INST(Xtest           , X86Op              , O(000F01,D6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9606, 34 , 154, 0 )
+    1633             :   // ${instData:End}
+    1634             : };
+    1635             : #undef NAME_DATA_INDEX
+    1636             : #undef INST
+    1637             : 
+    1638             : // ${altOpCodeData:Begin}
+    1639             : // ------------------- Automatically generated, do not edit -------------------
+    1640             : const uint32_t X86InstDB::altOpCodeData[] = {
+    1641             :   0                         , // #0
+    1642             :   O(660F00,1B,_,_,_,_,_,_  ), // #1
+    1643             :   O(000F00,BA,4,_,x,_,_,_  ), // #2
+    1644             :   O(000F00,BA,7,_,x,_,_,_  ), // #3
+    1645             :   O(000F00,BA,6,_,x,_,_,_  ), // #4
+    1646             :   O(000F00,BA,5,_,x,_,_,_  ), // #5
+    1647             :   O(000000,48,_,_,x,_,_,_  ), // #6
+    1648             :   O(660F00,78,0,_,_,_,_,_  ), // #7
+    1649             :   O_FPU(00,00DF,5)          , // #8
+    1650             :   O_FPU(00,00DF,7)          , // #9
+    1651             :   O_FPU(00,00DD,1)          , // #10
+    1652             :   O_FPU(00,00DB,5)          , // #11
+    1653             :   O_FPU(00,DFE0,_)          , // #12
+    1654             :   O(000000,DB,7,_,_,_,_,_  ), // #13
+    1655             :   O_FPU(9B,DFE0,_)          , // #14
+    1656             :   O(000000,E4,_,_,_,_,_,_  ), // #15
+    1657             :   O(000000,40,_,_,x,_,_,_  ), // #16
+    1658             :   O(F20F00,78,_,_,_,_,_,_  ), // #17
+    1659             :   O(000000,77,_,_,_,_,_,_  ), // #18
+    1660             :   O(000000,73,_,_,_,_,_,_  ), // #19
+    1661             :   O(000000,72,_,_,_,_,_,_  ), // #20
+    1662             :   O(000000,76,_,_,_,_,_,_  ), // #21
+    1663             :   O(000000,74,_,_,_,_,_,_  ), // #22
+    1664             :   O(000000,E3,_,_,_,_,_,_  ), // #23
+    1665             :   O(000000,7F,_,_,_,_,_,_  ), // #24
+    1666             :   O(000000,7D,_,_,_,_,_,_  ), // #25
+    1667             :   O(000000,7C,_,_,_,_,_,_  ), // #26
+    1668             :   O(000000,7E,_,_,_,_,_,_  ), // #27
+    1669             :   O(000000,EB,_,_,_,_,_,_  ), // #28
+    1670             :   O(000000,75,_,_,_,_,_,_  ), // #29
+    1671             :   O(000000,71,_,_,_,_,_,_  ), // #30
+    1672             :   O(000000,7B,_,_,_,_,_,_  ), // #31
+    1673             :   O(000000,79,_,_,_,_,_,_  ), // #32
+    1674             :   O(000000,70,_,_,_,_,_,_  ), // #33
+    1675             :   O(000000,7A,_,_,_,_,_,_  ), // #34
+    1676             :   O(000000,78,_,_,_,_,_,_  ), // #35
+    1677             :   V(660F00,92,_,0,0,_,_,_  ), // #36
+    1678             :   V(F20F00,92,_,0,0,_,_,_  ), // #37
+    1679             :   V(F20F00,92,_,0,1,_,_,_  ), // #38
+    1680             :   V(000F00,92,_,0,0,_,_,_  ), // #39
+    1681             :   O(000000,E2,_,_,_,_,_,_  ), // #40
+    1682             :   O(000000,E1,_,_,_,_,_,_  ), // #41
+    1683             :   O(000000,E0,_,_,_,_,_,_  ), // #42
+    1684             :   O(660F00,29,_,_,_,_,_,_  ), // #43
+    1685             :   O(000F00,29,_,_,_,_,_,_  ), // #44
+    1686             :   O(000F38,F1,_,_,x,_,_,_  ), // #45
+    1687             :   O(000F00,7E,_,_,_,_,_,_  ), // #46
+    1688             :   O(660F00,7F,_,_,_,_,_,_  ), // #47
+    1689             :   O(F30F00,7F,_,_,_,_,_,_  ), // #48
+    1690             :   O(660F00,17,_,_,_,_,_,_  ), // #49
+    1691             :   O(000F00,17,_,_,_,_,_,_  ), // #50
+    1692             :   O(660F00,13,_,_,_,_,_,_  ), // #51
+    1693             :   O(000F00,13,_,_,_,_,_,_  ), // #52
+    1694             :   O(660F00,E7,_,_,_,_,_,_  ), // #53
+    1695             :   O(660F00,2B,_,_,_,_,_,_  ), // #54
+    1696             :   O(000F00,2B,_,_,_,_,_,_  ), // #55
+    1697             :   O(000F00,E7,_,_,_,_,_,_  ), // #56
+    1698             :   O(F20F00,2B,_,_,_,_,_,_  ), // #57
+    1699             :   O(F30F00,2B,_,_,_,_,_,_  ), // #58
+    1700             :   O(000F00,7E,_,_,x,_,_,_  ), // #59
+    1701             :   O(F20F00,11,_,_,_,_,_,_  ), // #60
+    1702             :   O(F30F00,11,_,_,_,_,_,_  ), // #61
+    1703             :   O(660F00,11,_,_,_,_,_,_  ), // #62
+    1704             :   O(000F00,11,_,_,_,_,_,_  ), // #63
+    1705             :   O(000000,E6,_,_,_,_,_,_  ), // #64
+    1706             :   O(000F3A,15,_,_,_,_,_,_  ), // #65
+    1707             :   O(000000,58,_,_,_,_,_,_  ), // #66
+    1708             :   O(000F00,72,6,_,_,_,_,_  ), // #67
+    1709             :   O(660F00,73,7,_,_,_,_,_  ), // #68
+    1710             :   O(000F00,73,6,_,_,_,_,_  ), // #69
+    1711             :   O(000F00,71,6,_,_,_,_,_  ), // #70
+    1712             :   O(000F00,72,4,_,_,_,_,_  ), // #71
+    1713             :   O(000F00,71,4,_,_,_,_,_  ), // #72
+    1714             :   O(000F00,72,2,_,_,_,_,_  ), // #73
+    1715             :   O(660F00,73,3,_,_,_,_,_  ), // #74
+    1716             :   O(000F00,73,2,_,_,_,_,_  ), // #75
+    1717             :   O(000F00,71,2,_,_,_,_,_  ), // #76
+    1718             :   O(000000,50,_,_,_,_,_,_  ), // #77
+    1719             :   O(000000,F6,_,_,x,_,_,_  ), // #78
+    1720             :   V(660F38,92,_,x,_,1,3,T1S), // #79
+    1721             :   V(660F38,92,_,x,_,0,2,T1S), // #80
+    1722             :   V(660F38,93,_,x,_,1,3,T1S), // #81
+    1723             :   V(660F38,93,_,x,_,0,2,T1S), // #82
+    1724             :   V(660F38,2F,_,x,0,_,_,_  ), // #83
+    1725             :   V(660F38,2E,_,x,0,_,_,_  ), // #84
+    1726             :   V(660F00,29,_,x,I,1,4,FVM), // #85
+    1727             :   V(000F00,29,_,x,I,0,4,FVM), // #86
+    1728             :   V(660F00,7E,_,0,0,0,2,T1S), // #87
+    1729             :   V(660F00,7F,_,x,I,_,_,_  ), // #88
+    1730             :   V(660F00,7F,_,x,_,0,4,FVM), // #89
+    1731             :   V(660F00,7F,_,x,_,1,4,FVM), // #90
+    1732             :   V(F30F00,7F,_,x,I,_,_,_  ), // #91
+    1733             :   V(F20F00,7F,_,x,_,1,4,FVM), // #92
+    1734             :   V(F30F00,7F,_,x,_,0,4,FVM), // #93
+    1735             :   V(F30F00,7F,_,x,_,1,4,FVM), // #94
+    1736             :   V(F20F00,7F,_,x,_,0,4,FVM), // #95
+    1737             :   V(660F00,17,_,0,I,1,3,T1S), // #96
+    1738             :   V(000F00,17,_,0,I,0,3,T2 ), // #97
+    1739             :   V(660F00,13,_,0,I,1,3,T1S), // #98
+    1740             :   V(000F00,13,_,0,I,0,3,T2 ), // #99
+    1741             :   V(660F00,7E,_,0,I,1,3,T1S), // #100
+    1742             :   V(F20F00,11,_,I,I,1,3,T1S), // #101
+    1743             :   V(F30F00,11,_,I,I,0,2,T1S), // #102
+    1744             :   V(660F00,11,_,x,I,1,4,FVM), // #103
+    1745             :   V(000F00,11,_,x,I,0,4,FVM), // #104
+    1746             :   V(660F3A,05,_,x,0,1,4,FV ), // #105
+    1747             :   V(660F3A,04,_,x,0,0,4,FV ), // #106
+    1748             :   V(660F3A,00,_,x,1,1,4,FV ), // #107
+    1749             :   V(660F38,90,_,x,_,0,2,T1S), // #108
+    1750             :   V(660F38,90,_,x,_,1,3,T1S), // #109
+    1751             :   V(660F38,91,_,x,_,0,2,T1S), // #110
+    1752             :   V(660F38,91,_,x,_,1,3,T1S), // #111
+    1753             :   V(660F38,8E,_,x,0,_,_,_  ), // #112
+    1754             :   V(660F38,8E,_,x,1,_,_,_  ), // #113
+    1755             :   V(XOP_M8,C0,_,0,x,_,_,_  ), // #114
+    1756             :   V(XOP_M8,C2,_,0,x,_,_,_  ), // #115
+    1757             :   V(XOP_M8,C3,_,0,x,_,_,_  ), // #116
+    1758             :   V(XOP_M8,C1,_,0,x,_,_,_  ), // #117
+    1759             :   V(660F00,72,6,x,I,0,4,FV ), // #118
+    1760             :   V(660F00,73,6,x,I,1,4,FV ), // #119
+    1761             :   V(660F00,71,6,x,I,I,4,FVM), // #120
+    1762             :   V(660F00,72,4,x,I,0,4,FV ), // #121
+    1763             :   V(660F00,72,4,x,_,1,4,FV ), // #122
+    1764             :   V(660F00,71,4,x,I,I,4,FVM), // #123
+    1765             :   V(660F00,72,2,x,I,0,4,FV ), // #124
+    1766             :   V(660F00,73,2,x,I,1,4,FV ), // #125
+    1767             :   V(660F00,71,2,x,I,I,4,FVM)  // #126
+    1768             : };
+    1769             : // ----------------------------------------------------------------------------
+    1770             : // ${altOpCodeData:End}
+    1771             : 
+    1772             : #undef O_FPU
+    1773             : #undef O
+    1774             : #undef V
+    1775             : 
+    1776             : // ${commonData:Begin}
+    1777             : // ------------------- Automatically generated, do not edit -------------------
+    1778             : #define F(VAL) X86Inst::kFlag##VAL
+    1779             : #define JUMP_TYPE(VAL) Inst::kJumpType##VAL
+    1780             : #define SINGLE_REG(VAL) X86Inst::kSingleReg##VAL
+    1781             : const X86Inst::CommonData X86InstDB::commonData[] = {
+    1782             :   { F(UseR)                                               , 0  , 0  , 0  , 0  , 0 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #0
+    1783             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 383, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #1
+    1784             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 384, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #2
+    1785             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #3
+    1786             :   { F(UseX)                                               , 0  , 0  , 0  , 25 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #4
+    1787             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #5
+    1788             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 385, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #6
+    1789             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 386, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #7
+    1790             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #8
+    1791             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #9
+    1792             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 39 , 11, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #10
+    1793             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 273, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #11
+    1794             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #12
+    1795             :   { F(UseX)                                               , 0  , 0  , 0  , 387, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #13
+    1796             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 275, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #14
+    1797             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 184, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #15
+    1798             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 338, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #16
+    1799             :   { F(UseX)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 388, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #17
+    1800             :   { F(UseR)                                               , 0  , 0  , 0  , 277, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #18
+    1801             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 389, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #19
+    1802             :   { F(UseW)                                               , 0  , 0  , 0  , 390, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #20
+    1803             :   { F(UseW)                                               , 0  , 0  , 1  , 279, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #21
+    1804             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 391, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #22
+    1805             :   { F(UseR)                                               , 0  , 0  , 0  , 281, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #23
+    1806             :   { F(UseX)                                               , 0  , 0  , 0  , 24 , 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #24
+    1807             :   { F(UseX)                                               , 0  , 0  , 0  , 392, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #25
+    1808             :   { F(UseR)                                               , 0  , 0  , 2  , 126, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #26
+    1809             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 3  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #27
+    1810             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 4  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #28
+    1811             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 5  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #29
+    1812             :   { F(UseR)                                               , 0  , 0  , 0  , 283, 2 , JUMP_TYPE(Call)       , SINGLE_REG(None), 0 }, // #30
+    1813             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 393, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #31
+    1814             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 394, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #32
+    1815             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 395, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #33
+    1816             :   { F(UseR)                                               , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #34
+    1817             :   { F(UseR)                                               , 0  , 0  , 0  , 396, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #35
+    1818             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 397, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #36
+    1819             :   { F(UseR)                                               , 0  , 0  , 0  , 27 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #37
+    1820             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 398, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #38
+    1821             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 399, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #39
+    1822             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 400, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #40
+    1823             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 134, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #41
+    1824             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 401, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #42
+    1825             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 402, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #43
+    1826             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #44
+    1827             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #45
+    1828             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 405, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #46
+    1829             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 406, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #47
+    1830             :   { F(UseX)                                               , 0  , 0  , 0  , 285, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #48
+    1831             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #49
+    1832             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #50
+    1833             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 407, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #51
+    1834             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #52
+    1835             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #53
+    1836             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 409, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #54
+    1837             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #55
+    1838             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #56
+    1839             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #57
+    1840             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #58
+    1841             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #59
+    1842             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #60
+    1843             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 413, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #61
+    1844             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 414, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #62
+    1845             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 6  , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #63
+    1846             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 138, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #64
+    1847             :   { F(UseR)|F(Mmx)                                        , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #65
+    1848             :   { F(UseR)                                               , 0  , 0  , 0  , 415, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #66
+    1849             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #67
+    1850             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 7  , 289, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #68
+    1851             :   { F(UseA)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 174, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #69
+    1852             :   { F(UseX)                                               , 0  , 0  , 0  , 291, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #70
+    1853             :   { F(UseR)|F(FpuM80)                                     , 0  , 0  , 0  , 417, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #71
+    1854             :   { F(UseW)|F(FpuM80)                                     , 0  , 0  , 0  , 418, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #72
+    1855             :   { F(UseX)                                               , 0  , 0  , 0  , 292, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #73
+    1856             :   { F(UseR)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 293, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #74
+    1857             :   { F(UseR)                                               , 0  , 0  , 0  , 296, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #75
+    1858             :   { F(UseR)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 419, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #76
+    1859             :   { F(UseR)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 8  , 420, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #77
+    1860             :   { F(UseW)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 421, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #78
+    1861             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 9  , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #79
+    1862             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 10 , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #80
+    1863             :   { F(UseR)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 11 , 423, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #81
+    1864             :   { F(UseR)|F(FpuM16)                                     , 0  , 0  , 0  , 424, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #82
+    1865             :   { F(UseX)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 177, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #83
+    1866             :   { F(UseW)                                               , 0  , 0  , 0  , 425, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #84
+    1867             :   { F(UseW)|F(FpuM16)                                     , 0  , 0  , 0  , 426, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #85
+    1868             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 12 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #86
+    1869             :   { F(UseW)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 428, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #87
+    1870             :   { F(UseW)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 13 , 429, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #88
+    1871             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 14 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #89
+    1872             :   { F(UseR)                                               , 0  , 0  , 0  , 295, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #90
+    1873             :   { F(UseR)                                               , 0  , 0  , 0  , 430, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #91
+    1874             :   { F(UseW)                                               , 0  , 0  , 0  , 431, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #92
+    1875             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 10, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #93
+    1876             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 15 , 432, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #94
+    1877             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 16 , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #95
+    1878             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 433, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #96
+    1879             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 17 , 297, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #97
+    1880             :   { F(UseR)                                               , 0  , 0  , 0  , 434, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #98
+    1881             :   { F(UseR)                                               , 0  , 0  , 0  , 435, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #99
+    1882             :   { F(UseR)                                               , 0  , 0  , 0  , 299, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #100
+    1883             :   { F(UseR)                                               , 0  , 0  , 0  , 436, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #101
+    1884             :   { F(UseR)                                               , 0  , 0  , 18 , 437, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #102
+    1885             :   { F(UseR)                                               , 0  , 0  , 19 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #103
+    1886             :   { F(UseR)                                               , 0  , 0  , 20 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #104
+    1887             :   { F(UseR)                                               , 0  , 0  , 21 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #105
+    1888             :   { F(UseR)                                               , 0  , 0  , 20 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #106
+    1889             :   { F(UseR)                                               , 0  , 0  , 22 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #107
+    1890             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 23 , 301, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #108
+    1891             :   { F(UseR)                                               , 0  , 0  , 24 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #109
+    1892             :   { F(UseR)                                               , 0  , 0  , 25 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #110
+    1893             :   { F(UseR)                                               , 0  , 0  , 26 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #111
+    1894             :   { F(UseR)                                               , 0  , 0  , 27 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #112
+    1895             :   { F(UseR)                                               , 0  , 0  , 28 , 303, 2 , JUMP_TYPE(Direct)     , SINGLE_REG(None), 0 }, // #113
+    1896             :   { F(UseR)                                               , 0  , 0  , 19 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #114
+    1897             :   { F(UseR)                                               , 0  , 0  , 29 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #115
+    1898             :   { F(UseR)                                               , 0  , 0  , 30 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #116
+    1899             :   { F(UseR)                                               , 0  , 0  , 31 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #117
+    1900             :   { F(UseR)                                               , 0  , 0  , 32 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #118
+    1901             :   { F(UseR)                                               , 0  , 0  , 33 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #119
+    1902             :   { F(UseR)                                               , 0  , 0  , 34 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #120
+    1903             :   { F(UseR)                                               , 0  , 0  , 35 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #121
+    1904             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 439, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #122
+    1905             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 36 , 305, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #123
+    1906             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 37 , 307, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #124
+    1907             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 38 , 309, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #125
+    1908             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 39 , 311, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #126
+    1909             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 440, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #127
+    1910             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 441, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #128
+    1911             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 442, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #129
+    1912             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 443, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #130
+    1913             :   { F(UseW)                                               , 0  , 0  , 0  , 313, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #131
+    1914             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 228, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #132
+    1915             :   { F(UseR)                                               , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #133
+    1916             :   { F(UseX)                                               , 0  , 0  , 0  , 315, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #134
+    1917             :   { F(UseW)                                               , 0  , 0  , 0  , 445, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #135
+    1918             :   { F(UseX)                                               , 0  , 0  , 0  , 180, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #136
+    1919             :   { F(UseR)                                               , 0  , 0  , 0  , 446, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #137
+    1920             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 447, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #138
+    1921             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 40 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #139
+    1922             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 41 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #140
+    1923             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 42 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #141
+    1924             :   { F(UseW)                                               , 0  , 0  , 0  , 319, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #142
+    1925             :   { F(UseW)                                               , 0  , 0  , 0  , 183, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #143
+    1926             :   { F(UseX)|F(FixedRM)|F(Vec)                             , 0  , 0  , 0  , 448, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #144
+    1927             :   { F(UseX)|F(FixedRM)|F(Mmx)                             , 0  , 0  , 0  , 449, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #145
+    1928             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 450, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #146
+    1929             :   { F(UseW)|F(XRelease)                                   , 0  , 0  , 0  , 0  , 15, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #147
+    1930             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 43 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #148
+    1931             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 44 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #149
+    1932             :   { F(UseW)                                               , 0  , 0  , 45 , 75 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #150
+    1933             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 46 , 321, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #151
+    1934             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 451, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #152
+    1935             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 47 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #153
+    1936             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 48 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #154
+    1937             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #155
+    1938             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 49 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #156
+    1939             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 50 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #157
+    1940             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #158
+    1941             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 51 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #159
+    1942             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 52 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #160
+    1943             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 453, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #161
+    1944             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 53 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #162
+    1945             :   { F(UseW)                                               , 0  , 8  , 0  , 79 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #163
+    1946             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 54 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #164
+    1947             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 55 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #165
+    1948             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 56 , 454, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #166
+    1949             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 57 , 234, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #167
+    1950             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 58 , 237, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #168
+    1951             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 59 , 81 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #169
+    1952             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 455, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #170
+    1953             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 456, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #171
+    1954             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 60 , 323, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #172
+    1955             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 61 , 325, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #173
+    1956             :   { F(UseW)                                               , 0  , 0  , 0  , 327, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #174
+    1957             :   { F(UseW)                                               , 0  , 0  , 0  , 457, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #175
+    1958             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 62 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #176
+    1959             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 63 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #177
+    1960             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #178
+    1961             :   { F(UseW)|F(FixedReg)|F(Vex)                            , 0  , 0  , 0  , 329, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #179
+    1962             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 458, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #180
+    1963             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 288, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #181
+    1964             :   { F(UseR)                                               , 0  , 0  , 0  , 331, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #182
+    1965             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #183
+    1966             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 64 , 459, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #184
+    1967             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 460, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #185
+    1968             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 333, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #186
+    1969             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #187
+    1970             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 337, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #188
+    1971             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #189
+    1972             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #190
+    1973             :   { F(UseX)|F(Mmx)                                        , 0  , 0  , 0  , 335, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #191
+    1974             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #192
+    1975             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #193
+    1976             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #194
+    1977             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #195
+    1978             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #196
+    1979             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #197
+    1980             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #198
+    1981             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 65 , 339, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #199
+    1982             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #200
+    1983             :   { F(UseW)|F(Mmx)                                        , 0  , 0  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #201
+    1984             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 467, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #202
+    1985             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 468, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #203
+    1986             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 469, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #204
+    1987             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 470, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #205
+    1988             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 471, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #206
+    1989             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #207
+    1990             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 258, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #208
+    1991             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 66 , 142, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #209
+    1992             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #210
+    1993             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 472, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #211
+    1994             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 67 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #212
+    1995             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 68 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #213
+    1996             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 69 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #214
+    1997             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 70 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #215
+    1998             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 71 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #216
+    1999             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 72 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #217
+    2000             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 73 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #218
+    2001             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 74 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #219
+    2002             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 75 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #220
+    2003             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 76 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #221
+    2004             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 379, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #222
+    2005             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 77 , 146, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #223
+    2006             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 474, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #224
+    2007             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #225
+    2008             :   { F(UseW)                                               , 0  , 8  , 0  , 475, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #226
+    2009             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 476, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #227
+    2010             :   { F(UseW)                                               , 0  , 8  , 0  , 477, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #228
+    2011             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 478, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #229
+    2012             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 479, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #230
+    2013             :   { F(UseR)                                               , 0  , 0  , 0  , 343, 2 , JUMP_TYPE(Return)     , SINGLE_REG(None), 0 }, // #231
+    2014             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 345, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #232
+    2015             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #233
+    2016             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #234
+    2017             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 482, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #235
+    2018             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 483, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #236
+    2019             :   { F(UseW)                                               , 0  , 1  , 0  , 484, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #237
+    2020             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 186, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #238
+    2021             :   { F(UseW)                                               , 0  , 0  , 0  , 485, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #239
+    2022             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #240
+    2023             :   { F(UseW)                                               , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #241
+    2024             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 487, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #242
+    2025             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #243
+    2026             :   { F(UseR)                                               , 0  , 0  , 78 , 68 , 7 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #244
+    2027             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 488, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #245
+    2028             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #246
+    2029             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #247
+    2030             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #248
+    2031             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #249
+    2032             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #250
+    2033             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 93 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #251
+    2034             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #252
+    2035             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #253
+    2036             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #254
+    2037             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #255
+    2038             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #256
+    2039             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #257
+    2040             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #258
+    2041             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #259
+    2042             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #260
+    2043             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #261
+    2044             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #262
+    2045             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #263
+    2046             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 347, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #264
+    2047             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 491, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #265
+    2048             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #266
+    2049             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 493, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #267
+    2050             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 494, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #268
+    2051             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 495, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #269
+    2052             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 260, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #270
+    2053             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #271
+    2054             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #272
+    2055             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #273
+    2056             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #274
+    2057             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 496, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #275
+    2058             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 497, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #276
+    2059             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #277
+    2060             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #278
+    2061             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 198, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #279
+    2062             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #280
+    2063             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #281
+    2064             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #282
+    2065             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 207, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #283
+    2066             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #284
+    2067             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #285
+    2068             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #286
+    2069             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #287
+    2070             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 210, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #288
+    2071             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #289
+    2072             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #290
+    2073             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #291
+    2074             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #292
+    2075             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #293
+    2076             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #294
+    2077             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #295
+    2078             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #296
+    2079             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #297
+    2080             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #298
+    2081             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #299
+    2082             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #300
+    2083             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #301
+    2084             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #302
+    2085             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #303
+    2086             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #304
+    2087             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #305
+    2088             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #306
+    2089             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #307
+    2090             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #308
+    2091             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #309
+    2092             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #310
+    2093             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #311
+    2094             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #312
+    2095             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #313
+    2096             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 211, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #314
+    2097             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 499, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #315
+    2098             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 212, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #316
+    2099             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #317
+    2100             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #318
+    2101             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #319
+    2102             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 500, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #320
+    2103             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 501, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #321
+    2104             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #322
+    2105             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #323
+    2106             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 502, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #324
+    2107             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 503, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #325
+    2108             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #326
+    2109             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 351, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #327
+    2110             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 353, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #328
+    2111             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #329
+    2112             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #330
+    2113             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 505, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #331
+    2114             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 506, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #332
+    2115             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 204, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #333
+    2116             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #334
+    2117             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #335
+    2118             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 79 , 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #336
+    2119             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 80 , 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #337
+    2120             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 507, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #338
+    2121             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 508, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #339
+    2122             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 509, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #340
+    2123             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 81 , 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #341
+    2124             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 82 , 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #342
+    2125             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #343
+    2126             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #344
+    2127             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #345
+    2128             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #346
+    2129             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #347
+    2130             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #348
+    2131             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 355, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #349
+    2132             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 355, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #350
+    2133             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 510, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #351
+    2134             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #352
+    2135             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 228, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #353
+    2136             :   { F(UseR)|F(Vex)                                        , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #354
+    2137             :   { F(UseR)|F(FixedRM)|F(Vec)|F(Vex)                      , 0  , 0  , 0  , 512, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #355
+    2138             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 83 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #356
+    2139             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 84 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #357
+    2140             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #358
+    2141             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #359
+    2142             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #360
+    2143             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 85 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #361
+    2144             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 86 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #362
+    2145             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 87 , 357, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #363
+    2146             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 222, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #364
+    2147             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 88 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #365
+    2148             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 89 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #366
+    2149             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 90 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #367
+    2150             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 91 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #368
+    2151             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 92 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #369
+    2152             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 93 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #370
+    2153             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 94 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #371
+    2154             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 95 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #372
+    2155             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 236, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #373
+    2156             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 96 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #374
+    2157             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 97 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #375
+    2158             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 98 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #376
+    2159             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 99 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #377
+    2160             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 513, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #378
+    2161             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 225, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #379
+    2162             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 228, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #380
+    2163             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 100, 231, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #381
+    2164             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 101, 234, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #382
+    2165             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #383
+    2166             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 102, 237, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #384
+    2167             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 103, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #385
+    2168             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 104, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #386
+    2169             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 514, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #387
+    2170             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #388
+    2171             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #389
+    2172             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #390
+    2173             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #391
+    2174             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #392
+    2175             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #393
+    2176             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #394
+    2177             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #395
+    2178             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 361, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #396
+    2179             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #397
+    2180             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 515, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #398
+    2181             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 516, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #399
+    2182             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 365, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #400
+    2183             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #401
+    2184             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #402
+    2185             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K)              , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #403
+    2186             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B32)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #404
+    2187             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B64)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #405
+    2188             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #406
+    2189             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #407
+    2190             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #408
+    2191             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #409
+    2192             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #410
+    2193             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #411
+    2194             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 193, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #412
+    2195             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 167, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #413
+    2196             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #414
+    2197             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #415
+    2198             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #416
+    2199             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 162, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #417
+    2200             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 105, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #418
+    2201             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 106, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #419
+    2202             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 96 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #420
+    2203             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 95 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #421
+    2204             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 107, 166, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #422
+    2205             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #423
+    2206             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #424
+    2207             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 340, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #425
+    2208             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 108, 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #426
+    2209             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 109, 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #427
+    2210             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 110, 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #428
+    2211             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 111, 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #429
+    2212             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 367, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #430
+    2213             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 369, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #431
+    2214             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 371, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #432
+    2215             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 517, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #433
+    2216             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #434
+    2217             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 151, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #435
+    2218             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 112, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #436
+    2219             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 113, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #437
+    2220             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #438
+    2221             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 518, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #439
+    2222             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 246, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #440
+    2223             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 249, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #441
+    2224             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 252, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #442
+    2225             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 255, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #443
+    2226             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 258, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #444
+    2227             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #445
+    2228             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 261, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #446
+    2229             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #447
+    2230             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #448
+    2231             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #449
+    2232             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #450
+    2233             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #451
+    2234             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 114, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #452
+    2235             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 115, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #453
+    2236             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 116, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #454
+    2237             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 117, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #455
+    2238             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #456
+    2239             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 264, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #457
+    2240             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 375, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #458
+    2241             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 267, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #459
+    2242             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 377, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #460
+    2243             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #461
+    2244             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #462
+    2245             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 118, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #463
+    2246             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #464
+    2247             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 119, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #465
+    2248             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 120, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #466
+    2249             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 121, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #467
+    2250             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 122, 105, 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #468
+    2251             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 123, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #469
+    2252             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 124, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #470
+    2253             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 125, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #471
+    2254             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 126, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #472
+    2255             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #473
+    2256             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #474
+    2257             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #475
+    2258             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #476
+    2259             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #477
+    2260             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 379, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #478
+    2261             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #479
+    2262             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #480
+    2263             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #481
+    2264             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #482
+    2265             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #483
+    2266             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #484
+    2267             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #485
+    2268             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #486
+    2269             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #487
+    2270             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #488
+    2271             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #489
+    2272             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #490
+    2273             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #491
+    2274             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #492
+    2275             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 101, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #493
+    2276             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #494
+    2277             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #495
+    2278             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #496
+    2279             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #497
+    2280             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #498
+    2281             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #499
+    2282             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 381, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #500
+    2283             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #501
+    2284             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #502
+    2285             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #503
+    2286             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #504
+    2287             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #505
+    2288             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #506
+    2289             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #507
+    2290             :   { F(UseR)                                               , 0  , 0  , 0  , 520, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #508
+    2291             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 521, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #509
+    2292             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)|F(XRelease)      , 0  , 0  , 0  , 170, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #510
+    2293             :   { F(UseR)                                               , 0  , 0  , 0  , 522, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #511
+    2294             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)                  , 0  , 0  , 0  , 60 , 8 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #512
+    2295             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 523, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #513
+    2296             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 524, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #514
+    2297             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 525, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #515
+    2298             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 526, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }  // #516
+    2299             : };
+    2300             : #undef SINGLE_REG
+    2301             : #undef JUMP_TYPE
+    2302             : #undef F
+    2303             : // ----------------------------------------------------------------------------
+    2304             : // ${commonData:End}
+    2305             : 
+    2306             : // ${operationData:Begin}
+    2307             : // ------------------- Automatically generated, do not edit -------------------
+    2308             : #define OP_FLAG(F) X86Inst::kOperation##F
+    2309             : #define FEATURE(F) CpuInfo::kX86Feature##F
+    2310             : #define SPECIAL(F) x86::kSpecialReg_##F
+    2311             : const X86Inst::OperationData X86InstDB::operationData[] = {
+    2312             :   { 0, { 0 }, 0, 0 }, // #0
+    2313             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #1
+    2314             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #2
+    2315             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #3
+    2316             :   { 0, { FEATURE(SSE2) }, 0, 0 }, // #4
+    2317             :   { 0, { FEATURE(SSE) }, 0, 0 }, // #5
+    2318             :   { 0, { FEATURE(SSE3) }, 0, 0 }, // #6
+    2319             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_OF), SPECIAL(FLAGS_OF) }, // #7
+    2320             :   { 0, { FEATURE(AESNI) }, 0, 0 }, // #8
+    2321             :   { 0, { FEATURE(BMI) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #9
+    2322             :   { 0, { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #10
+    2323             :   { 0, { FEATURE(TBM) }, 0, 0 }, // #11
+    2324             :   { 0, { FEATURE(SSE4_1) }, 0, 0 }, // #12
+    2325             :   { 0, { FEATURE(MPX) }, 0, 0 }, // #13
+    2326             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) }, // #14
+    2327             :   { 0, { FEATURE(BMI2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #15
+    2328             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #16
+    2329             :   { OP_FLAG(Volatile), { FEATURE(SMAP) }, 0, SPECIAL(FLAGS_AC) }, // #17
+    2330             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) }, // #18
+    2331             :   { 0, { 0 }, 0, SPECIAL(FLAGS_DF) }, // #19
+    2332             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSH) }, 0, 0 }, // #20
+    2333             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSHOPT) }, 0, 0 }, // #21
+    2334             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_IF) }, // #22
+    2335             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { 0 }, 0, 0 }, // #23
+    2336             :   { OP_FLAG(Volatile), { FEATURE(CLWB) }, 0, 0 }, // #24
+    2337             :   { OP_FLAG(Volatile), { FEATURE(CLZERO) }, 0, 0 }, // #25
+    2338             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #26
+    2339             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #27
+    2340             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF), 0 }, // #28
+    2341             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_ZF), 0 }, // #29
+    2342             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #30
+    2343             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #31
+    2344             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF), 0 }, // #32
+    2345             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_PF), 0 }, // #33
+    2346             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_SF), 0 }, // #34
+    2347             :   { 0, { 0 }, SPECIAL(FLAGS_DF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #35
+    2348             :   { 0, { FEATURE(I486) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #36
+    2349             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG16B) }, 0, SPECIAL(FLAGS_ZF) }, // #37
+    2350             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG8B) }, 0, SPECIAL(FLAGS_ZF) }, // #38
+    2351             :   { 0, { FEATURE(SSE2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #39
+    2352             :   { 0, { FEATURE(SSE) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #40
+    2353             :   { OP_FLAG(Volatile), { FEATURE(I486) }, 0, 0 }, // #41
+    2354             :   { 0, { FEATURE(SSE4_2) }, 0, 0 }, // #42
+    2355             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #43
+    2356             :   { OP_FLAG(Volatile), { FEATURE(MMX) }, 0, 0 }, // #44
+    2357             :   { OP_FLAG(Volatile), { 0 }, 0, 0 }, // #45
+    2358             :   { 0, { FEATURE(SSE4A) }, 0, 0 }, // #46
+    2359             :   { 0, { 0 }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #47
+    2360             :   { 0, { FEATURE(CMOV) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #48
+    2361             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_ZF) | SPECIAL(X87SW_C1) }, // #49
+    2362             :   { OP_FLAG(Volatile), { FEATURE(3DNOW) }, 0, 0 }, // #50
+    2363             :   { 0, { FEATURE(SSE3) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #51
+    2364             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #52
+    2365             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, 0 }, // #53
+    2366             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF), 0 }, // #54
+    2367             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(I486) }, 0, 0 }, // #55
+    2368             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #56
+    2369             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF), 0 }, // #57
+    2370             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #58
+    2371             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #59
+    2372             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #60
+    2373             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_PF), 0 }, // #61
+    2374             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_SF), 0 }, // #62
+    2375             :   { 0, { FEATURE(AVX512_DQ) }, 0, 0 }, // #63
+    2376             :   { 0, { FEATURE(AVX512_BW) }, 0, 0 }, // #64
+    2377             :   { 0, { FEATURE(AVX512_F) }, 0, 0 }, // #65
+    2378             :   { 0, { FEATURE(AVX512_DQ) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #66
+    2379             :   { 0, { FEATURE(AVX512_BW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #67
+    2380             :   { 0, { FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #68
+    2381             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #69
+    2382             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #70
+    2383             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(SSE2) }, 0, 0 }, // #71
+    2384             :   { 0, { 0 }, SPECIAL(FLAGS_DF), 0 }, // #72
+    2385             :   { 0, { FEATURE(LZCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #73
+    2386             :   { 0, { FEATURE(MMX2) }, 0, 0 }, // #74
+    2387             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MONITOR) }, 0, 0 }, // #75
+    2388             :   { OP_FLAG(MovCrDr), { 0 }, 0, 0 }, // #76
+    2389             :   { 0, { FEATURE(MOVBE) }, 0, 0 }, // #77
+    2390             :   { 0, { FEATURE(MMX), FEATURE(SSE2) }, 0, 0 }, // #78
+    2391             :   { OP_FLAG(MovSsSd), { FEATURE(SSE2) }, 0, 0 }, // #79
+    2392             :   { OP_FLAG(MovSsSd), { FEATURE(SSE) }, 0, 0 }, // #80
+    2393             :   { 0, { FEATURE(BMI2) }, 0, 0 }, // #81
+    2394             :   { 0, { FEATURE(SSSE3) }, 0, 0 }, // #82
+    2395             :   { 0, { FEATURE(MMX2), FEATURE(SSE2) }, 0, 0 }, // #83
+    2396             :   { 0, { FEATURE(3DNOW) }, 0, 0 }, // #84
+    2397             :   { 0, { FEATURE(PCLMULQDQ) }, 0, 0 }, // #85
+    2398             :   { 0, { FEATURE(SSE4_2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #86
+    2399             :   { OP_FLAG(Volatile), { FEATURE(PCOMMIT) }, 0, 0 }, // #87
+    2400             :   { 0, { FEATURE(MMX2), FEATURE(SSE2), FEATURE(SSE4_1) }, 0, 0 }, // #88
+    2401             :   { 0, { FEATURE(3DNOW2) }, 0, 0 }, // #89
+    2402             :   { 0, { FEATURE(GEODE) }, 0, 0 }, // #90
+    2403             :   { 0, { FEATURE(POPCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #91
+    2404             :   { OP_FLAG(Prefetch), { FEATURE(3DNOW) }, 0, 0 }, // #92
+    2405             :   { OP_FLAG(Prefetch), { FEATURE(MMX2) }, 0, 0 }, // #93
+    2406             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #94
+    2407             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHWT1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #95
+    2408             :   { 0, { FEATURE(SSE4_1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #96
+    2409             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) }, // #97
+    2410             :   { OP_FLAG(Volatile), { FEATURE(FSGSBASE) }, 0, 0 }, // #98
+    2411             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, SPECIAL(MSR), 0 }, // #99
+    2412             :   { OP_FLAG(Volatile), { FEATURE(RDRAND) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #100
+    2413             :   { OP_FLAG(Volatile), { FEATURE(RDSEED) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #101
+    2414             :   { OP_FLAG(Volatile), { FEATURE(RDTSC) }, 0, 0 }, // #102
+    2415             :   { OP_FLAG(Volatile), { FEATURE(RDTSCP) }, 0, 0 }, // #103
+    2416             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #104
+    2417             :   { 0, { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #105
+    2418             :   { 0, { 0 }, SPECIAL(FLAGS_CF), 0 }, // #106
+    2419             :   { 0, { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #107
+    2420             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #108
+    2421             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #109
+    2422             :   { 0, { 0 }, SPECIAL(FLAGS_OF), 0 }, // #110
+    2423             :   { 0, { 0 }, SPECIAL(FLAGS_PF), 0 }, // #111
+    2424             :   { 0, { 0 }, SPECIAL(FLAGS_SF), 0 }, // #112
+    2425             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(MMX2) }, 0, 0 }, // #113
+    2426             :   { 0, { FEATURE(SHA) }, 0, 0 }, // #114
+    2427             :   { 0, { FEATURE(AVX512_4FMAPS) }, 0, 0 }, // #115
+    2428             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #116
+    2429             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, 0 }, // #117
+    2430             :   { 0, { FEATURE(AVX) }, 0, 0 }, // #118
+    2431             :   { 0, { FEATURE(AESNI), FEATURE(AVX) }, 0, 0 }, // #119
+    2432             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #120
+    2433             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #121
+    2434             :   { 0, { FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #122
+    2435             :   { 0, { FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #123
+    2436             :   { 0, { FEATURE(AVX2) }, 0, 0 }, // #124
+    2437             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #125
+    2438             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #126
+    2439             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(F16C) }, 0, 0 }, // #127
+    2440             :   { 0, { FEATURE(AVX512_ERI) }, 0, 0 }, // #128
+    2441             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(FMA) }, 0, 0 }, // #129
+    2442             :   { 0, { FEATURE(AVX512_F), FEATURE(FMA) }, 0, 0 }, // #130
+    2443             :   { 0, { FEATURE(FMA4) }, 0, 0 }, // #131
+    2444             :   { 0, { FEATURE(XOP) }, 0, 0 }, // #132
+    2445             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #133
+    2446             :   { 0, { FEATURE(AVX512_PFI) }, 0, 0 }, // #134
+    2447             :   { 0, { FEATURE(AVX), FEATURE(AVX2) }, 0, 0 }, // #135
+    2448             :   { 0, { FEATURE(AVX512_4VNNIW) }, 0, 0 }, // #136
+    2449             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #137
+    2450             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #138
+    2451             :   { 0, { FEATURE(AVX512_CDI), FEATURE(AVX512_VL) }, 0, 0 }, // #139
+    2452             :   { 0, { FEATURE(AVX), FEATURE(PCLMULQDQ) }, 0, 0 }, // #140
+    2453             :   { 0, { FEATURE(AVX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #141
+    2454             :   { 0, { FEATURE(AVX512_VBMI), FEATURE(AVX512_VL) }, 0, 0 }, // #142
+    2455             :   { 0, { FEATURE(AVX), FEATURE(AVX512_BW) }, 0, 0 }, // #143
+    2456             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ) }, 0, 0 }, // #144
+    2457             :   { 0, { FEATURE(AVX512_IFMA), FEATURE(AVX512_VL) }, 0, 0 }, // #145
+    2458             :   { 0, { FEATURE(AVX512_VPOPCNTDQ) }, 0, 0 }, // #146
+    2459             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, 0, SPECIAL(MSR) }, // #147
+    2460             :   { OP_FLAG(Volatile), { FEATURE(RTM) }, 0, 0 }, // #148
+    2461             :   { OP_FLAG(Volatile), { FEATURE(XSAVE) }, SPECIAL(XCR), 0 }, // #149
+    2462             :   { OP_FLAG(Volatile), { FEATURE(XSAVES) }, SPECIAL(XCR), 0 }, // #150
+    2463             :   { OP_FLAG(Volatile), { FEATURE(XSAVEC) }, SPECIAL(XCR), 0 }, // #151
+    2464             :   { OP_FLAG(Volatile), { FEATURE(XSAVEOPT) }, SPECIAL(XCR), 0 }, // #152
+    2465             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(XSAVE) }, 0, SPECIAL(XCR) }, // #153
+    2466             :   { OP_FLAG(Volatile), { FEATURE(TSX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }  // #154
+    2467             : };
+    2468             : #undef SPECIAL
+    2469             : #undef FEATURE
+    2470             : #undef OP_FLAG
+    2471             : // ----------------------------------------------------------------------------
+    2472             : // ${operationData:End}
+    2473             : 
+    2474             : // ${sseToAvxData:Begin}
+    2475             : // ------------------- Automatically generated, do not edit -------------------
+    2476             : const X86Inst::SseToAvxData X86InstDB::sseToAvxData[] = {
+    2477             :   { X86Inst::kSseToAvxNone     , 0    }, // #0
+    2478             :   { X86Inst::kSseToAvxExtend   , 725  }, // #1
+    2479             :   { X86Inst::kSseToAvxExtend   , 724  }, // #2
+    2480             :   { X86Inst::kSseToAvxMove     , 724  }, // #3
+    2481             :   { X86Inst::kSseToAvxExtend   , 723  }, // #4
+    2482             :   { X86Inst::kSseToAvxBlend    , 723  }, // #5
+    2483             :   { X86Inst::kSseToAvxExtend   , 671  }, // #6
+    2484             :   { X86Inst::kSseToAvxExtend   , 670  }, // #7
+    2485             :   { X86Inst::kSseToAvxMove     , 667  }, // #8
+    2486             :   { X86Inst::kSseToAvxMove     , 666  }, // #9
+    2487             :   { X86Inst::kSseToAvxMove     , 665  }, // #10
+    2488             :   { X86Inst::kSseToAvxMove     , 672  }, // #11
+    2489             :   { X86Inst::kSseToAvxExtend   , 672  }, // #12
+    2490             :   { X86Inst::kSseToAvxExtend   , 673  }, // #13
+    2491             :   { X86Inst::kSseToAvxMove     , 673  }, // #14
+    2492             :   { X86Inst::kSseToAvxMove     , 674  }, // #15
+    2493             :   { X86Inst::kSseToAvxMove     , 676  }, // #16
+    2494             :   { X86Inst::kSseToAvxMove     , 678  }, // #17
+    2495             :   { X86Inst::kSseToAvxMove     , 679  }, // #18
+    2496             :   { X86Inst::kSseToAvxExtend   , 681  }, // #19
+    2497             :   { X86Inst::kSseToAvxMove     , 695  }, // #20
+    2498             :   { X86Inst::kSseToAvxExtend   , 708  }, // #21
+    2499             :   { X86Inst::kSseToAvxExtend   , 707  }, // #22
+    2500             :   { X86Inst::kSseToAvxExtend   , 712  }, // #23
+    2501             :   { X86Inst::kSseToAvxMove     , 616  }, // #24
+    2502             :   { X86Inst::kSseToAvxMove     , 597  }, // #25
+    2503             :   { X86Inst::kSseToAvxExtend   , 598  }, // #26
+    2504             :   { X86Inst::kSseToAvxExtend   , 597  }, // #27
+    2505             :   { X86Inst::kSseToAvxMove     , 595  }, // #28
+    2506             :   { X86Inst::kSseToAvxMove     , 594  }, // #29
+    2507             :   { X86Inst::kSseToAvxMove     , 593  }, // #30
+    2508             :   { X86Inst::kSseToAvxExtend   , 599  }, // #31
+    2509             :   { X86Inst::kSseToAvxMoveIfMem, 599  }, // #32
+    2510             :   { X86Inst::kSseToAvxMove     , 599  }, // #33
+    2511             :   { X86Inst::kSseToAvxMove     , 598  }, // #34
+    2512             :   { X86Inst::kSseToAvxMoveIfMem, 593  }, // #35
+    2513             :   { X86Inst::kSseToAvxMove     , 591  }, // #36
+    2514             :   { X86Inst::kSseToAvxExtend   , 590  }, // #37
+    2515             :   { X86Inst::kSseToAvxExtend   , 589  }, // #38
+    2516             :   { X86Inst::kSseToAvxExtend   , 583  }, // #39
+    2517             :   { X86Inst::kSseToAvxMove     , 583  }, // #40
+    2518             :   { X86Inst::kSseToAvxMove     , 584  }, // #41
+    2519             :   { X86Inst::kSseToAvxExtend   , 584  }, // #42
+    2520             :   { X86Inst::kSseToAvxExtend   , 585  }, // #43
+    2521             :   { X86Inst::kSseToAvxExtend   , 587  }, // #44
+    2522             :   { X86Inst::kSseToAvxExtend   , 586  }, // #45
+    2523             :   { X86Inst::kSseToAvxBlend    , 587  }, // #46
+    2524             :   { X86Inst::kSseToAvxExtend   , 593  }, // #47
+    2525             :   { X86Inst::kSseToAvxExtend   , 596  }, // #48
+    2526             :   { X86Inst::kSseToAvxMove     , 596  }, // #49
+    2527             :   { X86Inst::kSseToAvxMove     , 637  }, // #50
+    2528             :   { X86Inst::kSseToAvxExtend   , 623  }, // #51
+    2529             :   { X86Inst::kSseToAvxExtend   , 624  }, // #52
+    2530             :   { X86Inst::kSseToAvxExtend   , 630  }, // #53
+    2531             :   { X86Inst::kSseToAvxMove     , 632  }, // #54
+    2532             :   { X86Inst::kSseToAvxExtend   , 633  }, // #55
+    2533             :   { X86Inst::kSseToAvxExtend   , 634  }, // #56
+    2534             :   { X86Inst::kSseToAvxMove     , 633  }, // #57
+    2535             :   { X86Inst::kSseToAvxExtend   , 649  }, // #58
+    2536             :   { X86Inst::kSseToAvxExtend   , 651  }, // #59
+    2537             :   { X86Inst::kSseToAvxExtend   , 652  }, // #60
+    2538             :   { X86Inst::kSseToAvxExtend   , 653  }, // #61
+    2539             :   { X86Inst::kSseToAvxExtend   , 654  }, // #62
+    2540             :   { X86Inst::kSseToAvxExtend   , 655  }, // #63
+    2541             :   { X86Inst::kSseToAvxMove     , 663  }, // #64
+    2542             :   { X86Inst::kSseToAvxMove     , 681  }, // #65
+    2543             :   { X86Inst::kSseToAvxExtend   , 680  }, // #66
+    2544             :   { X86Inst::kSseToAvxExtend   , 682  }, // #67
+    2545             :   { X86Inst::kSseToAvxExtend   , 677  }, // #68
+    2546             :   { X86Inst::kSseToAvxExtend   , 685  }, // #69
+    2547             :   { X86Inst::kSseToAvxExtend   , 697  }, // #70
+    2548             :   { X86Inst::kSseToAvxMove     , 697  }, // #71
+    2549             :   { X86Inst::kSseToAvxExtend   , 696  }, // #72
+    2550             :   { X86Inst::kSseToAvxExtend   , 699  }, // #73
+    2551             :   { X86Inst::kSseToAvxExtend   , 703  }, // #74
+    2552             :   { X86Inst::kSseToAvxExtend   , 706  }, // #75
+    2553             :   { X86Inst::kSseToAvxMove     , 707  }, // #76
+    2554             :   { X86Inst::kSseToAvxExtend   , 715  }, // #77
+    2555             :   { X86Inst::kSseToAvxExtend   , 709  }, // #78
+    2556             :   { X86Inst::kSseToAvxMove     , 722  }, // #79
+    2557             :   { X86Inst::kSseToAvxExtend   , 722  }, // #80
+    2558             :   { X86Inst::kSseToAvxMove     , 717  }, // #81
+    2559             :   { X86Inst::kSseToAvxExtend   , 717  }, // #82
+    2560             :   { X86Inst::kSseToAvxExtend   , 693  }, // #83
+    2561             :   { X86Inst::kSseToAvxMove     , 690  }, // #84
+    2562             :   { X86Inst::kSseToAvxExtend   , 690  }, // #85
+    2563             :   { X86Inst::kSseToAvxExtend   , 683  }, // #86
+    2564             :   { X86Inst::kSseToAvxExtend   , -16  }  // #87
+    2565             : };
+    2566             : // ----------------------------------------------------------------------------
+    2567             : // ${sseToAvxData:End}
+    2568             : 
+    2569             : // ============================================================================
+    2570             : // [asmjit::X86Inst - Id <-> Name]
+    2571             : // ============================================================================
+    2572             : 
+    2573             : #if !defined(ASMJIT_DISABLE_TEXT)
+    2574             : // ${nameData:Begin}
+    2575             : // ------------------- Automatically generated, do not edit -------------------
+    2576             : const char X86InstDB::nameData[] =
+    2577             :   "\0" "aaa\0" "aad\0" "aam\0" "aas\0" "adc\0" "adcx\0" "adox\0" "arpl\0"
+    2578             :   "bextr\0" "blcfill\0" "blci\0" "blcic\0" "blcmsk\0" "blcs\0" "blsfill\0"
+    2579             :   "blsi\0" "blsic\0" "blsmsk\0" "blsr\0" "bndcl\0" "bndcn\0" "bndcu\0"
+    2580             :   "bndldx\0" "bndmk\0" "bndmov\0" "bndstx\0" "bound\0" "bsf\0" "bsr\0"
+    2581             :   "bswap\0" "bt\0" "btc\0" "btr\0" "bts\0" "bzhi\0" "cbw\0" "cdq\0" "cdqe\0"
+    2582             :   "clac\0" "clc\0" "cld\0" "clflush\0" "clflushopt\0" "cli\0" "clts\0" "clwb\0"
+    2583             :   "clzero\0" "cmc\0" "cmova\0" "cmovae\0" "cmovc\0" "cmovg\0" "cmovge\0"
+    2584             :   "cmovl\0" "cmovle\0" "cmovna\0" "cmovnae\0" "cmovnc\0" "cmovng\0" "cmovnge\0"
+    2585             :   "cmovnl\0" "cmovnle\0" "cmovno\0" "cmovnp\0" "cmovns\0" "cmovnz\0" "cmovo\0"
+    2586             :   "cmovp\0" "cmovpe\0" "cmovpo\0" "cmovs\0" "cmovz\0" "cmp\0" "cmps\0"
+    2587             :   "cmpxchg\0" "cmpxchg16b\0" "cmpxchg8b\0" "cpuid\0" "cqo\0" "crc32\0"
+    2588             :   "cvtpd2pi\0" "cvtpi2pd\0" "cvtpi2ps\0" "cvtps2pi\0" "cvttpd2pi\0"
+    2589             :   "cvttps2pi\0" "cwd\0" "cwde\0" "daa\0" "das\0" "f2xm1\0" "fabs\0" "faddp\0"
+    2590             :   "fbld\0" "fbstp\0" "fchs\0" "fclex\0" "fcmovb\0" "fcmovbe\0" "fcmove\0"
+    2591             :   "fcmovnb\0" "fcmovnbe\0" "fcmovne\0" "fcmovnu\0" "fcmovu\0" "fcom\0"
+    2592             :   "fcomi\0" "fcomip\0" "fcomp\0" "fcompp\0" "fcos\0" "fdecstp\0" "fdiv\0"
+    2593             :   "fdivp\0" "fdivr\0" "fdivrp\0" "femms\0" "ffree\0" "fiadd\0" "ficom\0"
+    2594             :   "ficomp\0" "fidiv\0" "fidivr\0" "fild\0" "fimul\0" "fincstp\0" "finit\0"
+    2595             :   "fist\0" "fistp\0" "fisttp\0" "fisub\0" "fisubr\0" "fld\0" "fld1\0" "fldcw\0"
+    2596             :   "fldenv\0" "fldl2e\0" "fldl2t\0" "fldlg2\0" "fldln2\0" "fldpi\0" "fldz\0"
+    2597             :   "fmulp\0" "fnclex\0" "fninit\0" "fnop\0" "fnsave\0" "fnstcw\0" "fnstenv\0"
+    2598             :   "fnstsw\0" "fpatan\0" "fprem\0" "fprem1\0" "fptan\0" "frndint\0" "frstor\0"
+    2599             :   "fsave\0" "fscale\0" "fsin\0" "fsincos\0" "fsqrt\0" "fst\0" "fstcw\0"
+    2600             :   "fstenv\0" "fstp\0" "fstsw\0" "fsubp\0" "fsubrp\0" "ftst\0" "fucom\0"
+    2601             :   "fucomi\0" "fucomip\0" "fucomp\0" "fucompp\0" "fwait\0" "fxam\0" "fxch\0"
+    2602             :   "fxrstor\0" "fxrstor64\0" "fxsave\0" "fxsave64\0" "fxtract\0" "fyl2x\0"
+    2603             :   "fyl2xp1\0" "hlt\0" "inc\0" "ins\0" "insertq\0" "int3\0" "into\0" "invlpg\0"
+    2604             :   "invpcid\0" "iret\0" "iretd\0" "iretq\0" "iretw\0" "ja\0" "jae\0" "jb\0"
+    2605             :   "jbe\0" "jc\0" "je\0" "jecxz\0" "jg\0" "jge\0" "jl\0" "jle\0" "jmp\0" "jna\0"
+    2606             :   "jnae\0" "jnb\0" "jnbe\0" "jnc\0" "jne\0" "jng\0" "jnge\0" "jnl\0" "jnle\0"
+    2607             :   "jno\0" "jnp\0" "jns\0" "jnz\0" "jo\0" "jp\0" "jpe\0" "jpo\0" "js\0" "jz\0"
+    2608             :   "kaddb\0" "kaddd\0" "kaddq\0" "kaddw\0" "kandb\0" "kandd\0" "kandnb\0"
+    2609             :   "kandnd\0" "kandnq\0" "kandnw\0" "kandq\0" "kandw\0" "kmovb\0" "kmovw\0"
+    2610             :   "knotb\0" "knotd\0" "knotq\0" "knotw\0" "korb\0" "kord\0" "korq\0"
+    2611             :   "kortestb\0" "kortestd\0" "kortestq\0" "kortestw\0" "korw\0" "kshiftlb\0"
+    2612             :   "kshiftld\0" "kshiftlq\0" "kshiftlw\0" "kshiftrb\0" "kshiftrd\0" "kshiftrq\0"
+    2613             :   "kshiftrw\0" "ktestb\0" "ktestd\0" "ktestq\0" "ktestw\0" "kunpckbw\0"
+    2614             :   "kunpckdq\0" "kunpckwd\0" "kxnorb\0" "kxnord\0" "kxnorq\0" "kxnorw\0"
+    2615             :   "kxorb\0" "kxord\0" "kxorq\0" "kxorw\0" "lahf\0" "lar\0" "lds\0" "lea\0"
+    2616             :   "leave\0" "les\0" "lfence\0" "lfs\0" "lgdt\0" "lgs\0" "lidt\0" "lldt\0"
+    2617             :   "lmsw\0" "lods\0" "loop\0" "loope\0" "loopne\0" "lsl\0" "ltr\0" "lzcnt\0"
+    2618             :   "mfence\0" "monitor\0" "movdq2q\0" "movnti\0" "movntq\0" "movntsd\0"
+    2619             :   "movntss\0" "movq2dq\0" "movsx\0" "movsxd\0" "movzx\0" "mulx\0" "mwait\0"
+    2620             :   "neg\0" "not\0" "out\0" "outs\0" "pause\0" "pavgusb\0" "pcommit\0" "pdep\0"
+    2621             :   "pext\0" "pf2id\0" "pf2iw\0" "pfacc\0" "pfadd\0" "pfcmpeq\0" "pfcmpge\0"
+    2622             :   "pfcmpgt\0" "pfmax\0" "pfmin\0" "pfmul\0" "pfnacc\0" "pfpnacc\0" "pfrcp\0"
+    2623             :   "pfrcpit1\0" "pfrcpit2\0" "pfrcpv\0" "pfrsqit1\0" "pfrsqrt\0" "pfrsqrtv\0"
+    2624             :   "pfsub\0" "pfsubr\0" "pi2fd\0" "pi2fw\0" "pmulhrw\0" "pop\0" "popa\0"
+    2625             :   "popad\0" "popcnt\0" "popf\0" "popfd\0" "popfq\0" "prefetch\0"
+    2626             :   "prefetchnta\0" "prefetcht0\0" "prefetcht1\0" "prefetcht2\0" "prefetchw\0"
+    2627             :   "prefetchwt1\0" "pshufw\0" "pswapd\0" "push\0" "pusha\0" "pushad\0" "pushf\0"
+    2628             :   "pushfd\0" "pushfq\0" "rcl\0" "rcr\0" "rdfsbase\0" "rdgsbase\0" "rdmsr\0"
+    2629             :   "rdpmc\0" "rdrand\0" "rdseed\0" "rdtsc\0" "rdtscp\0" "rol\0" "ror\0" "rorx\0"
+    2630             :   "rsm\0" "sahf\0" "sal\0" "sar\0" "sarx\0" "sbb\0" "scas\0" "seta\0" "setae\0"
+    2631             :   "setb\0" "setbe\0" "setc\0" "sete\0" "setg\0" "setge\0" "setl\0" "setle\0"
+    2632             :   "setna\0" "setnae\0" "setnb\0" "setnbe\0" "setnc\0" "setne\0" "setng\0"
+    2633             :   "setnge\0" "setnl\0" "setnle\0" "setno\0" "setnp\0" "setns\0" "setnz\0"
+    2634             :   "seto\0" "setp\0" "setpe\0" "setpo\0" "sets\0" "setz\0" "sfence\0" "sgdt\0"
+    2635             :   "sha1msg1\0" "sha1msg2\0" "sha1nexte\0" "sha1rnds4\0" "sha256msg1\0"
+    2636             :   "sha256msg2\0" "sha256rnds2\0" "shl\0" "shlx\0" "shr\0" "shrd\0" "shrx\0"
+    2637             :   "sidt\0" "sldt\0" "smsw\0" "stac\0" "stc\0" "sti\0" "stos\0" "str\0"
+    2638             :   "swapgs\0" "syscall\0" "sysenter\0" "sysexit\0" "sysexit64\0" "sysret\0"
+    2639             :   "sysret64\0" "t1mskc\0" "tzcnt\0" "tzmsk\0" "ud2\0" "v4fmaddps\0"
+    2640             :   "v4fnmaddps\0" "vaddpd\0" "vaddps\0" "vaddsd\0" "vaddss\0" "vaddsubpd\0"
+    2641             :   "vaddsubps\0" "vaesdec\0" "vaesdeclast\0" "vaesenc\0" "vaesenclast\0"
+    2642             :   "vaesimc\0" "vaeskeygenassist\0" "valignd\0" "valignq\0" "vandnpd\0"
+    2643             :   "vandnps\0" "vandpd\0" "vandps\0" "vblendmb\0" "vblendmd\0" "vblendmpd\0"
+    2644             :   "vblendmps\0" "vblendmq\0" "vblendmw\0" "vblendpd\0" "vblendps\0"
+    2645             :   "vblendvpd\0" "vblendvps\0" "vbroadcastf128\0" "vbroadcastf32x2\0"
+    2646             :   "vbroadcastf32x4\0" "vbroadcastf32x8\0" "vbroadcastf64x2\0"
+    2647             :   "vbroadcastf64x4\0" "vbroadcasti128\0" "vbroadcasti32x2\0"
+    2648             :   "vbroadcasti32x4\0" "vbroadcasti32x8\0" "vbroadcasti64x2\0"
+    2649             :   "vbroadcasti64x4\0" "vbroadcastsd\0" "vbroadcastss\0" "vcmppd\0" "vcmpps\0"
+    2650             :   "vcmpsd\0" "vcmpss\0" "vcomisd\0" "vcomiss\0" "vcompresspd\0" "vcompressps\0"
+    2651             :   "vcvtdq2pd\0" "vcvtdq2ps\0" "vcvtpd2dq\0" "vcvtpd2ps\0" "vcvtpd2qq\0"
+    2652             :   "vcvtpd2udq\0" "vcvtpd2uqq\0" "vcvtph2ps\0" "vcvtps2dq\0" "vcvtps2pd\0"
+    2653             :   "vcvtps2ph\0" "vcvtps2qq\0" "vcvtps2udq\0" "vcvtps2uqq\0" "vcvtqq2pd\0"
+    2654             :   "vcvtqq2ps\0" "vcvtsd2si\0" "vcvtsd2ss\0" "vcvtsd2usi\0" "vcvtsi2sd\0"
+    2655             :   "vcvtsi2ss\0" "vcvtss2sd\0" "vcvtss2si\0" "vcvtss2usi\0" "vcvttpd2dq\0"
+    2656             :   "vcvttpd2qq\0" "vcvttpd2udq\0" "vcvttpd2uqq\0" "vcvttps2dq\0" "vcvttps2qq\0"
+    2657             :   "vcvttps2udq\0" "vcvttps2uqq\0" "vcvttsd2si\0" "vcvttsd2usi\0" "vcvttss2si\0"
+    2658             :   "vcvttss2usi\0" "vcvtudq2pd\0" "vcvtudq2ps\0" "vcvtuqq2pd\0" "vcvtuqq2ps\0"
+    2659             :   "vcvtusi2sd\0" "vcvtusi2ss\0" "vdbpsadbw\0" "vdivpd\0" "vdivps\0" "vdivsd\0"
+    2660             :   "vdivss\0" "vdppd\0" "vdpps\0" "verr\0" "verw\0" "vexp2pd\0" "vexp2ps\0"
+    2661             :   "vexpandpd\0" "vexpandps\0" "vextractf128\0" "vextractf32x4\0"
+    2662             :   "vextractf32x8\0" "vextractf64x2\0" "vextractf64x4\0" "vextracti128\0"
+    2663             :   "vextracti32x4\0" "vextracti32x8\0" "vextracti64x2\0" "vextracti64x4\0"
+    2664             :   "vextractps\0" "vfixupimmpd\0" "vfixupimmps\0" "vfixupimmsd\0"
+    2665             :   "vfixupimmss\0" "vfmadd132pd\0" "vfmadd132ps\0" "vfmadd132sd\0"
+    2666             :   "vfmadd132ss\0" "vfmadd213pd\0" "vfmadd213ps\0" "vfmadd213sd\0"
+    2667             :   "vfmadd213ss\0" "vfmadd231pd\0" "vfmadd231ps\0" "vfmadd231sd\0"
+    2668             :   "vfmadd231ss\0" "vfmaddpd\0" "vfmaddps\0" "vfmaddsd\0" "vfmaddss\0"
+    2669             :   "vfmaddsub132pd\0" "vfmaddsub132ps\0" "vfmaddsub213pd\0" "vfmaddsub213ps\0"
+    2670             :   "vfmaddsub231pd\0" "vfmaddsub231ps\0" "vfmaddsubpd\0" "vfmaddsubps\0"
+    2671             :   "vfmsub132pd\0" "vfmsub132ps\0" "vfmsub132sd\0" "vfmsub132ss\0"
+    2672             :   "vfmsub213pd\0" "vfmsub213ps\0" "vfmsub213sd\0" "vfmsub213ss\0"
+    2673             :   "vfmsub231pd\0" "vfmsub231ps\0" "vfmsub231sd\0" "vfmsub231ss\0"
+    2674             :   "vfmsubadd132pd\0" "vfmsubadd132ps\0" "vfmsubadd213pd\0" "vfmsubadd213ps\0"
+    2675             :   "vfmsubadd231pd\0" "vfmsubadd231ps\0" "vfmsubaddpd\0" "vfmsubaddps\0"
+    2676             :   "vfmsubpd\0" "vfmsubps\0" "vfmsubsd\0" "vfmsubss\0" "vfnmadd132pd\0"
+    2677             :   "vfnmadd132ps\0" "vfnmadd132sd\0" "vfnmadd132ss\0" "vfnmadd213pd\0"
+    2678             :   "vfnmadd213ps\0" "vfnmadd213sd\0" "vfnmadd213ss\0" "vfnmadd231pd\0"
+    2679             :   "vfnmadd231ps\0" "vfnmadd231sd\0" "vfnmadd231ss\0" "vfnmaddpd\0"
+    2680             :   "vfnmaddps\0" "vfnmaddsd\0" "vfnmaddss\0" "vfnmsub132pd\0" "vfnmsub132ps\0"
+    2681             :   "vfnmsub132sd\0" "vfnmsub132ss\0" "vfnmsub213pd\0" "vfnmsub213ps\0"
+    2682             :   "vfnmsub213sd\0" "vfnmsub213ss\0" "vfnmsub231pd\0" "vfnmsub231ps\0"
+    2683             :   "vfnmsub231sd\0" "vfnmsub231ss\0" "vfnmsubpd\0" "vfnmsubps\0" "vfnmsubsd\0"
+    2684             :   "vfnmsubss\0" "vfpclasspd\0" "vfpclassps\0" "vfpclasssd\0" "vfpclassss\0"
+    2685             :   "vfrczpd\0" "vfrczps\0" "vfrczsd\0" "vfrczss\0" "vgatherdpd\0" "vgatherdps\0"
+    2686             :   "vgatherpf0dpd\0" "vgatherpf0dps\0" "vgatherpf0qpd\0" "vgatherpf0qps\0"
+    2687             :   "vgatherpf1dpd\0" "vgatherpf1dps\0" "vgatherpf1qpd\0" "vgatherpf1qps\0"
+    2688             :   "vgatherqpd\0" "vgatherqps\0" "vgetexppd\0" "vgetexpps\0" "vgetexpsd\0"
+    2689             :   "vgetexpss\0" "vgetmantpd\0" "vgetmantps\0" "vgetmantsd\0" "vgetmantss\0"
+    2690             :   "vhaddpd\0" "vhaddps\0" "vhsubpd\0" "vhsubps\0" "vinsertf128\0"
+    2691             :   "vinsertf32x4\0" "vinsertf32x8\0" "vinsertf64x2\0" "vinsertf64x4\0"
+    2692             :   "vinserti128\0" "vinserti32x4\0" "vinserti32x8\0" "vinserti64x2\0"
+    2693             :   "vinserti64x4\0" "vinsertps\0" "vlddqu\0" "vldmxcsr\0" "vmaskmovdqu\0"
+    2694             :   "vmaskmovpd\0" "vmaskmovps\0" "vmaxpd\0" "vmaxps\0" "vmaxsd\0" "vmaxss\0"
+    2695             :   "vminpd\0" "vminps\0" "vminsd\0" "vminss\0" "vmovapd\0" "vmovaps\0" "vmovd\0"
+    2696             :   "vmovddup\0" "vmovdqa\0" "vmovdqa32\0" "vmovdqa64\0" "vmovdqu\0"
+    2697             :   "vmovdqu16\0" "vmovdqu32\0" "vmovdqu64\0" "vmovdqu8\0" "vmovhlps\0"
+    2698             :   "vmovhpd\0" "vmovhps\0" "vmovlhps\0" "vmovlpd\0" "vmovlps\0" "vmovmskpd\0"
+    2699             :   "vmovmskps\0" "vmovntdq\0" "vmovntdqa\0" "vmovntpd\0" "vmovntps\0" "vmovq\0"
+    2700             :   "vmovsd\0" "vmovshdup\0" "vmovsldup\0" "vmovss\0" "vmovupd\0" "vmovups\0"
+    2701             :   "vmpsadbw\0" "vmulpd\0" "vmulps\0" "vmulsd\0" "vmulss\0" "vorpd\0" "vorps\0"
+    2702             :   "vp4dpwssd\0" "vp4dpwssds\0" "vpabsb\0" "vpabsd\0" "vpabsq\0" "vpabsw\0"
+    2703             :   "vpackssdw\0" "vpacksswb\0" "vpackusdw\0" "vpackuswb\0" "vpaddb\0" "vpaddd\0"
+    2704             :   "vpaddq\0" "vpaddsb\0" "vpaddsw\0" "vpaddusb\0" "vpaddusw\0" "vpaddw\0"
+    2705             :   "vpalignr\0" "vpand\0" "vpandd\0" "vpandn\0" "vpandnd\0" "vpandnq\0"
+    2706             :   "vpandq\0" "vpavgb\0" "vpavgw\0" "vpblendd\0" "vpblendvb\0" "vpblendw\0"
+    2707             :   "vpbroadcastb\0" "vpbroadcastd\0" "vpbroadcastmb2d\0" "vpbroadcastmb2q\0"
+    2708             :   "vpbroadcastq\0" "vpbroadcastw\0" "vpclmulqdq\0" "vpcmov\0" "vpcmpb\0"
+    2709             :   "vpcmpd\0" "vpcmpeqb\0" "vpcmpeqd\0" "vpcmpeqq\0" "vpcmpeqw\0" "vpcmpestri\0"
+    2710             :   "vpcmpestrm\0" "vpcmpgtb\0" "vpcmpgtd\0" "vpcmpgtq\0" "vpcmpgtw\0"
+    2711             :   "vpcmpistri\0" "vpcmpistrm\0" "vpcmpq\0" "vpcmpub\0" "vpcmpud\0" "vpcmpuq\0"
+    2712             :   "vpcmpuw\0" "vpcmpw\0" "vpcomb\0" "vpcomd\0" "vpcompressd\0" "vpcompressq\0"
+    2713             :   "vpcomq\0" "vpcomub\0" "vpcomud\0" "vpcomuq\0" "vpcomuw\0" "vpcomw\0"
+    2714             :   "vpconflictd\0" "vpconflictq\0" "vperm2f128\0" "vperm2i128\0" "vpermb\0"
+    2715             :   "vpermd\0" "vpermi2b\0" "vpermi2d\0" "vpermi2pd\0" "vpermi2ps\0" "vpermi2q\0"
+    2716             :   "vpermi2w\0" "vpermil2pd\0" "vpermil2ps\0" "vpermilpd\0" "vpermilps\0"
+    2717             :   "vpermpd\0" "vpermps\0" "vpermq\0" "vpermt2b\0" "vpermt2d\0" "vpermt2pd\0"
+    2718             :   "vpermt2ps\0" "vpermt2q\0" "vpermt2w\0" "vpermw\0" "vpexpandd\0"
+    2719             :   "vpexpandq\0" "vpextrb\0" "vpextrd\0" "vpextrq\0" "vpextrw\0" "vpgatherdd\0"
+    2720             :   "vpgatherdq\0" "vpgatherqd\0" "vpgatherqq\0" "vphaddbd\0" "vphaddbq\0"
+    2721             :   "vphaddbw\0" "vphaddd\0" "vphadddq\0" "vphaddsw\0" "vphaddubd\0"
+    2722             :   "vphaddubq\0" "vphaddubw\0" "vphaddudq\0" "vphadduwd\0" "vphadduwq\0"
+    2723             :   "vphaddw\0" "vphaddwd\0" "vphaddwq\0" "vphminposuw\0" "vphsubbw\0"
+    2724             :   "vphsubd\0" "vphsubdq\0" "vphsubsw\0" "vphsubw\0" "vphsubwd\0" "vpinsrb\0"
+    2725             :   "vpinsrd\0" "vpinsrq\0" "vpinsrw\0" "vplzcntd\0" "vplzcntq\0" "vpmacsdd\0"
+    2726             :   "vpmacsdqh\0" "vpmacsdql\0" "vpmacssdd\0" "vpmacssdqh\0" "vpmacssdql\0"
+    2727             :   "vpmacsswd\0" "vpmacssww\0" "vpmacswd\0" "vpmacsww\0" "vpmadcsswd\0"
+    2728             :   "vpmadcswd\0" "vpmadd52huq\0" "vpmadd52luq\0" "vpmaddubsw\0" "vpmaddwd\0"
+    2729             :   "vpmaskmovd\0" "vpmaskmovq\0" "vpmaxsb\0" "vpmaxsd\0" "vpmaxsq\0" "vpmaxsw\0"
+    2730             :   "vpmaxub\0" "vpmaxud\0" "vpmaxuq\0" "vpmaxuw\0" "vpminsb\0" "vpminsd\0"
+    2731             :   "vpminsq\0" "vpminsw\0" "vpminub\0" "vpminud\0" "vpminuq\0" "vpminuw\0"
+    2732             :   "vpmovb2m\0" "vpmovd2m\0" "vpmovdb\0" "vpmovdw\0" "vpmovm2b\0" "vpmovm2d\0"
+    2733             :   "vpmovm2q\0" "vpmovm2w\0" "vpmovmskb\0" "vpmovq2m\0" "vpmovqb\0" "vpmovqd\0"
+    2734             :   "vpmovqw\0" "vpmovsdb\0" "vpmovsdw\0" "vpmovsqb\0" "vpmovsqd\0" "vpmovsqw\0"
+    2735             :   "vpmovswb\0" "vpmovsxbd\0" "vpmovsxbq\0" "vpmovsxbw\0" "vpmovsxdq\0"
+    2736             :   "vpmovsxwd\0" "vpmovsxwq\0" "vpmovusdb\0" "vpmovusdw\0" "vpmovusqb\0"
+    2737             :   "vpmovusqd\0" "vpmovusqw\0" "vpmovuswb\0" "vpmovw2m\0" "vpmovwb\0"
+    2738             :   "vpmovzxbd\0" "vpmovzxbq\0" "vpmovzxbw\0" "vpmovzxdq\0" "vpmovzxwd\0"
+    2739             :   "vpmovzxwq\0" "vpmuldq\0" "vpmulhrsw\0" "vpmulhuw\0" "vpmulhw\0" "vpmulld\0"
+    2740             :   "vpmullq\0" "vpmullw\0" "vpmultishiftqb\0" "vpmuludq\0" "vpopcntd\0"
+    2741             :   "vpopcntq\0" "vpor\0" "vpord\0" "vporq\0" "vpperm\0" "vprold\0" "vprolq\0"
+    2742             :   "vprolvd\0" "vprolvq\0" "vprord\0" "vprorq\0" "vprorvd\0" "vprorvq\0"
+    2743             :   "vprotb\0" "vprotd\0" "vprotq\0" "vprotw\0" "vpsadbw\0" "vpscatterdd\0"
+    2744             :   "vpscatterdq\0" "vpscatterqd\0" "vpscatterqq\0" "vpshab\0" "vpshad\0"
+    2745             :   "vpshaq\0" "vpshaw\0" "vpshlb\0" "vpshld\0" "vpshlq\0" "vpshlw\0" "vpshufb\0"
+    2746             :   "vpshufd\0" "vpshufhw\0" "vpshuflw\0" "vpsignb\0" "vpsignd\0" "vpsignw\0"
+    2747             :   "vpslld\0" "vpslldq\0" "vpsllq\0" "vpsllvd\0" "vpsllvq\0" "vpsllvw\0"
+    2748             :   "vpsllw\0" "vpsrad\0" "vpsraq\0" "vpsravd\0" "vpsravq\0" "vpsravw\0"
+    2749             :   "vpsraw\0" "vpsrld\0" "vpsrldq\0" "vpsrlq\0" "vpsrlvd\0" "vpsrlvq\0"
+    2750             :   "vpsrlvw\0" "vpsrlw\0" "vpsubb\0" "vpsubd\0" "vpsubq\0" "vpsubsb\0"
+    2751             :   "vpsubsw\0" "vpsubusb\0" "vpsubusw\0" "vpsubw\0" "vpternlogd\0"
+    2752             :   "vpternlogq\0" "vptest\0" "vptestmb\0" "vptestmd\0" "vptestmq\0" "vptestmw\0"
+    2753             :   "vptestnmb\0" "vptestnmd\0" "vptestnmq\0" "vptestnmw\0" "vpunpckhbw\0"
+    2754             :   "vpunpckhdq\0" "vpunpckhqdq\0" "vpunpckhwd\0" "vpunpcklbw\0" "vpunpckldq\0"
+    2755             :   "vpunpcklqdq\0" "vpunpcklwd\0" "vpxor\0" "vpxord\0" "vpxorq\0" "vrangepd\0"
+    2756             :   "vrangeps\0" "vrangesd\0" "vrangess\0" "vrcp14pd\0" "vrcp14ps\0" "vrcp14sd\0"
+    2757             :   "vrcp14ss\0" "vrcp28pd\0" "vrcp28ps\0" "vrcp28sd\0" "vrcp28ss\0" "vrcpps\0"
+    2758             :   "vrcpss\0" "vreducepd\0" "vreduceps\0" "vreducesd\0" "vreducess\0"
+    2759             :   "vrndscalepd\0" "vrndscaleps\0" "vrndscalesd\0" "vrndscaless\0" "vroundpd\0"
+    2760             :   "vroundps\0" "vroundsd\0" "vroundss\0" "vrsqrt14pd\0" "vrsqrt14ps\0"
+    2761             :   "vrsqrt14sd\0" "vrsqrt14ss\0" "vrsqrt28pd\0" "vrsqrt28ps\0" "vrsqrt28sd\0"
+    2762             :   "vrsqrt28ss\0" "vrsqrtps\0" "vrsqrtss\0" "vscalefpd\0" "vscalefps\0"
+    2763             :   "vscalefsd\0" "vscalefss\0" "vscatterdpd\0" "vscatterdps\0"
+    2764             :   "vscatterpf0dpd\0" "vscatterpf0dps\0" "vscatterpf0qpd\0" "vscatterpf0qps\0"
+    2765             :   "vscatterpf1dpd\0" "vscatterpf1dps\0" "vscatterpf1qpd\0" "vscatterpf1qps\0"
+    2766             :   "vscatterqpd\0" "vscatterqps\0" "vshuff32x4\0" "vshuff64x2\0" "vshufi32x4\0"
+    2767             :   "vshufi64x2\0" "vshufpd\0" "vshufps\0" "vsqrtpd\0" "vsqrtps\0" "vsqrtsd\0"
+    2768             :   "vsqrtss\0" "vstmxcsr\0" "vsubpd\0" "vsubps\0" "vsubsd\0" "vsubss\0"
+    2769             :   "vtestpd\0" "vtestps\0" "vucomisd\0" "vucomiss\0" "vunpckhpd\0" "vunpckhps\0"
+    2770             :   "vunpcklpd\0" "vunpcklps\0" "vxorpd\0" "vxorps\0" "vzeroall\0" "vzeroupper\0"
+    2771             :   "wbinvd\0" "wrfsbase\0" "wrgsbase\0" "wrmsr\0" "xabort\0" "xadd\0" "xbegin\0"
+    2772             :   "xend\0" "xgetbv\0" "xlatb\0" "xrstors\0" "xrstors64\0" "xsavec\0"
+    2773             :   "xsavec64\0" "xsaveopt\0" "xsaveopt64\0" "xsaves\0" "xsaves64\0" "xsetbv\0"
+    2774             :   "xtest";
+    2775             : 
+    2776             : enum {
+    2777             :   kX86InstMaxLength = 16
+    2778             : };
+    2779             : 
+    2780             : struct InstNameAZ {
+    2781             :   uint16_t start;
+    2782             :   uint16_t end;
+    2783             : };
+    2784             : 
+    2785             : static const InstNameAZ X86InstNameAZ[26] = {
+    2786             :   { X86Inst::kIdAaa       , X86Inst::kIdArpl       + 1 },
+    2787             :   { X86Inst::kIdBextr     , X86Inst::kIdBzhi       + 1 },
+    2788             :   { X86Inst::kIdCall      , X86Inst::kIdCwde       + 1 },
+    2789             :   { X86Inst::kIdDaa       , X86Inst::kIdDpps       + 1 },
+    2790             :   { X86Inst::kIdEmms      , X86Inst::kIdExtrq      + 1 },
+    2791             :   { X86Inst::kIdF2xm1     , X86Inst::kIdFyl2xp1    + 1 },
+    2792             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2793             :   { X86Inst::kIdHaddpd    , X86Inst::kIdHsubps     + 1 },
+    2794             :   { X86Inst::kIdIdiv      , X86Inst::kIdIretw      + 1 },
+    2795             :   { X86Inst::kIdJa        , X86Inst::kIdJz         + 1 },
+    2796             :   { X86Inst::kIdKaddb     , X86Inst::kIdKxorw      + 1 },
+    2797             :   { X86Inst::kIdLahf      , X86Inst::kIdLzcnt      + 1 },
+    2798             :   { X86Inst::kIdMaskmovdqu, X86Inst::kIdMwait      + 1 },
+    2799             :   { X86Inst::kIdNeg       , X86Inst::kIdNot        + 1 },
+    2800             :   { X86Inst::kIdOr        , X86Inst::kIdOuts       + 1 },
+    2801             :   { X86Inst::kIdPabsb     , X86Inst::kIdPxor       + 1 },
+    2802             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2803             :   { X86Inst::kIdRcl       , X86Inst::kIdRsqrtss    + 1 },
+    2804             :   { X86Inst::kIdSahf      , X86Inst::kIdSysret64   + 1 },
+    2805             :   { X86Inst::kIdT1mskc    , X86Inst::kIdTzmsk      + 1 },
+    2806             :   { X86Inst::kIdUcomisd   , X86Inst::kIdUnpcklps   + 1 },
+    2807             :   { X86Inst::kIdV4fmaddps , X86Inst::kIdVzeroupper + 1 },
+    2808             :   { X86Inst::kIdWbinvd    , X86Inst::kIdWrmsr      + 1 },
+    2809             :   { X86Inst::kIdXabort    , X86Inst::kIdXtest      + 1 },
+    2810             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2811             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 }
+    2812             : };
+    2813             : // ----------------------------------------------------------------------------
+    2814             : // ${nameData:End}
+    2815             : 
+    2816           0 : uint32_t X86Inst::getIdByName(const char* name, size_t len) noexcept {
+    2817           0 :   if (ASMJIT_UNLIKELY(!name))
+    2818             :     return Inst::kIdNone;
+    2819             : 
+    2820           0 :   if (len == Globals::kInvalidIndex)
+    2821           0 :     len = ::strlen(name);
+    2822             : 
+    2823           0 :   if (ASMJIT_UNLIKELY(len == 0 || len > kX86InstMaxLength))
+    2824             :     return Inst::kIdNone;
+    2825             : 
+    2826           0 :   uint32_t prefix = static_cast<uint32_t>(name[0]) - 'a';
+    2827           0 :   if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
+    2828             :     return Inst::kIdNone;
+    2829             : 
+    2830           0 :   uint32_t index = X86InstNameAZ[prefix].start;
+    2831           0 :   if (ASMJIT_UNLIKELY(!index))
+    2832             :     return Inst::kIdNone;
+    2833             : 
+    2834             :   const char* nameData = X86InstDB::nameData;
+    2835             :   const X86Inst* instData = X86InstDB::instData;
+    2836             : 
+    2837           0 :   const X86Inst* base = instData + index;
+    2838           0 :   const X86Inst* end  = instData + X86InstNameAZ[prefix].end;
+    2839             : 
+    2840           0 :   for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
+    2841           0 :     const X86Inst* cur = base + (lim >> 1);
+    2842           0 :     int result = Utils::cmpInstName(nameData + cur[0].getNameDataIndex(), name, len);
+    2843             : 
+    2844           0 :     if (result < 0) {
+    2845           0 :       base = cur + 1;
+    2846           0 :       lim--;
+    2847           0 :       continue;
+    2848             :     }
+    2849             : 
+    2850           0 :     if (result > 0)
+    2851           0 :       continue;
+    2852             : 
+    2853           0 :     return static_cast<uint32_t>((size_t)(cur - instData));
+    2854             :   }
+    2855             : 
+    2856             :   return Inst::kIdNone;
+    2857             : }
+    2858             : 
+    2859           0 : const char* X86Inst::getNameById(uint32_t id) noexcept {
+    2860           0 :   if (ASMJIT_UNLIKELY(id >= X86Inst::_kIdCount))
+    2861             :     return nullptr;
+    2862           0 :   return X86Inst::getInst(id).getName();
+    2863             : }
+    2864             : #else
+    2865             : const char X86InstDB::nameData[] = "";
+    2866             : #endif // !ASMJIT_DISABLE_TEXT
+    2867             : 
+    2868             : // ============================================================================
+    2869             : // [asmjit::X86Inst - Validation]
+    2870             : // ============================================================================
+    2871             : 
+    2872             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2873             : // ${signatureData:Begin}
+    2874             : // ------------------- Automatically generated, do not edit -------------------
+    2875             : #define FLAG(flag) X86Inst::kOp##flag
+    2876             : #define MEM(mem) X86Inst::kMemOp##mem
+    2877             : #define OSIGNATURE(flags, memFlags, extFlags, regId) \
+    2878             :   { uint32_t(flags), uint16_t(memFlags), uint8_t(extFlags), uint8_t(regId) }
+    2879             : const X86Inst::OSignature X86InstDB::oSignatureData[] = {
+    2880             :   OSIGNATURE(0, 0, 0, 0xFF),
+    2881             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2882             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2883             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2884             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2885             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2886             :   OSIGNATURE(FLAG(R) | FLAG(Gpd), 0, 0, 0x00),
+    2887             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2888             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Seg) | FLAG(I32), 0, 0, 0x00),
+    2889             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2890             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem) | FLAG(I8) | FLAG(U8), MEM(Any) | MEM(M8), 0, 0x00),
+    2891             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2892             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2893             :   OSIGNATURE(FLAG(W) | FLAG(Gpd), 0, 0, 0x00),
+    2894             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem) | FLAG(I32) | FLAG(U32), MEM(Any) | MEM(M32), 0, 0x00),
+    2895             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Seg), 0, 0, 0x00),
+    2896             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2897             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2898             :   OSIGNATURE(FLAG(R) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2899             :   OSIGNATURE(FLAG(W) | FLAG(Gpq), 0, 0, 0x00),
+    2900             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr) | FLAG(I64) | FLAG(U64), 0, 0, 0x00),
+    2901             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2902             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(U8), 0, 0, 0x00),
+    2903             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2904             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2905             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2906             :   OSIGNATURE(FLAG(W) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2907             :   OSIGNATURE(FLAG(R) | FLAG(Gpq), 0, 0, 0x00),
+    2908             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2909             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2910             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2911             :   OSIGNATURE(FLAG(X) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2912             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(I32), 0, 0, 0x00),
+    2913             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2914             :   OSIGNATURE(FLAG(R) | FLAG(I8), 0, 0, 0x00),
+    2915             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2916             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2917             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x00),
+    2918             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2919             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2920             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2921             :   OSIGNATURE(FLAG(X) | FLAG(Gpw), 0, 0, 0x00),
+    2922             :   OSIGNATURE(FLAG(X) | FLAG(Gpd), 0, 0, 0x00),
+    2923             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2924             :   OSIGNATURE(FLAG(X) | FLAG(Gpq), 0, 0, 0x00),
+    2925             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2926             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2927             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2928             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2929             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2930             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2931             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2932             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2933             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2934             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2935             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2936             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem) | FLAG(I8) | FLAG(I16), MEM(Any) | MEM(M16), 0, 0x00),
+    2937             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M32), 0, 0x00),
+    2938             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M64), 0, 0x00),
+    2939             :   OSIGNATURE(FLAG(W) | FLAG(Gpw), 0, 0, 0x00),
+    2940             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2941             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2942             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32), 0, 0, 0x00),
+    2943             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2944             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2945             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2946             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2947             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2948             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2949             :   OSIGNATURE(FLAG(W) | FLAG(Mm), 0, 0, 0x00),
+    2950             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2951             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2952             :   OSIGNATURE(FLAG(R) | FLAG(Mm), 0, 0, 0x00),
+    2953             :   OSIGNATURE(FLAG(R) | FLAG(Xmm), 0, 0, 0x00),
+    2954             :   OSIGNATURE(FLAG(W) | FLAG(Xmm), 0, 0, 0x00),
+    2955             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2956             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2957             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2958             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2959             :   OSIGNATURE(FLAG(W) | FLAG(Ymm), 0, 0, 0x00),
+    2960             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2961             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2962             :   OSIGNATURE(FLAG(R) | FLAG(Ymm), 0, 0, 0x00),
+    2963             :   OSIGNATURE(FLAG(W) | FLAG(Zmm), 0, 0, 0x00),
+    2964             :   OSIGNATURE(FLAG(R) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2965             :   OSIGNATURE(FLAG(W) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2966             :   OSIGNATURE(FLAG(R) | FLAG(Zmm), 0, 0, 0x00),
+    2967             :   OSIGNATURE(FLAG(R) | FLAG(U8), 0, 0, 0x00),
+    2968             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M128), 0, 0x00),
+    2969             :   OSIGNATURE(FLAG(X) | FLAG(Xmm), 0, 0, 0x00),
+    2970             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    2971             :   OSIGNATURE(FLAG(X) | FLAG(Ymm), 0, 0, 0x00),
+    2972             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    2973             :   OSIGNATURE(FLAG(X) | FLAG(Zmm), 0, 0, 0x00),
+    2974             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    2975             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    2976             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    2977             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    2978             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(U8), 0, 0, 0x00),
+    2979             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2980             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2981             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo), 0, 0, 0x01),
+    2982             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2983             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2984             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2985             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2986             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2987             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2988             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2989             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x1A),
+    2990             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x60),
+    2991             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I16) | FLAG(I32), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2992             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x1E),
+    2993             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x60),
+    2994             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    2995             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2996             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2997             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2998             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2999             :   OSIGNATURE(FLAG(R) | FLAG(U4), 0, 0, 0x00),
+    3000             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3001             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x01),
+    3002             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x00),
+    3003             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x00),
+    3004             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x01),
+    3005             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3006             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M48), 0, 0x00),
+    3007             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3008             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(U8), 0, 0, 0x02),
+    3009             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Xmm), 0, 0, 0x00),
+    3010             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Ymm), 0, 0, 0x00),
+    3011             :   OSIGNATURE(FLAG(W) | FLAG(K), 0, 0, 0x00),
+    3012             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M64) | MEM(M128) | MEM(M256), 0, 0x00),
+    3013             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(M128), 0, 0x00),
+    3014             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(M256), 0, 0x00),
+    3015             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3016             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3017             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3018             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3019             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3020             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3021             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3022             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    3023             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    3024             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    3025             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    3026             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    3027             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    3028             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    3029             :   OSIGNATURE(FLAG(R) | FLAG(Bnd), 0, 0, 0x00),
+    3030             :   OSIGNATURE(FLAG(W) | FLAG(Bnd), 0, 0, 0x00),
+    3031             :   OSIGNATURE(FLAG(R) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3032             :   OSIGNATURE(FLAG(W) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3033             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3034             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M8) | MEM(M16) | MEM(M32), 0, 0x00),
+    3035             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpq) | FLAG(Mem), MEM(M8) | MEM(M64), 0, 0x00),
+    3036             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x00),
+    3037             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3038             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3039             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8), 0, 0, 0x00),
+    3040             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3041             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3042             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3043             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3044             :   OSIGNATURE(FLAG(R) | FLAG(K), 0, 0, 0x00),
+    3045             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3046             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3047             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3048             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3049             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3050             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3051             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3052             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3053             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3054             :   OSIGNATURE(FLAG(W) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3055             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3056             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3057             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3058             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    3059             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    3060             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3061             :   OSIGNATURE(FLAG(X) | FLAG(Mm), 0, 0, 0x00),
+    3062             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M64), 0, 0x00),
+    3063             :   OSIGNATURE(FLAG(R) | FLAG(U16), 0, 0, 0x00),
+    3064             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M128) | MEM(M256), 0, 0x00),
+    3065             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3066             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3067             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3068             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3069             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(U8), 0, 0, 0x00),
+    3070             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    3071             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm), 0, 0, 0x00),
+    3072             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3073             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3074             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3075             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3076             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3077             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x01),
+    3078             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3079             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3080             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    3081             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x02),
+    3082             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x08),
+    3083             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3084             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3085             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3086             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3087             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3088             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32) | MEM(M64), 0, 0x00),
+    3089             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3090             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3091             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3092             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3093             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3094             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3095             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3096             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x01),
+    3097             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3098             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3099             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3100             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(U8), 0, 0, 0x04),
+    3101             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3102             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x04),
+    3103             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), 0, 0, 0x00),
+    3104             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3105             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M48) | MEM(M64) | MEM(M80) | MEM(M128) | MEM(M256) | MEM(M512) | MEM(M1024), 0, 0x00),
+    3106             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3107             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3108             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x80),
+    3109             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3110             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3111             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3112             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3113             :   OSIGNATURE(FLAG(X) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3114             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    3115             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3116             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3117             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3118             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3119             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm) | FLAG(Mem), MEM(M128) | MEM(M256) | MEM(M512), 0, 0x00),
+    3120             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3121             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), 0, 0, 0x00)
+    3122             : };
+    3123             : #undef OSIGNATURE
+    3124             : #undef MEM
+    3125             : #undef FLAG
+    3126             : 
+    3127             : #define ISIGNATURE(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \
+    3128             :   { count, (x86 ? uint8_t(X86Inst::kArchMaskX86) : uint8_t(0)) |      \
+    3129             :            (x64 ? uint8_t(X86Inst::kArchMaskX64) : uint8_t(0)) ,      \
+    3130             :     implicit,                                                         \
+    3131             :     0,                                                                \
+    3132             :     { o0, o1, o2, o3, o4, o5 }                                        \
+    3133             :   }
+    3134             : const X86Inst::ISignature X86InstDB::iSignatureData[] = {
+    3135             :   ISIGNATURE(2, 1, 1, 0, 1  , 2  , 0  , 0  , 0  , 0  ), // #0   {W:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3136             :   ISIGNATURE(2, 1, 1, 0, 3  , 4  , 0  , 0  , 0  , 0  ), //      {W:r16|m16|mem, R:r16|sreg}
+    3137             :   ISIGNATURE(2, 1, 1, 0, 5  , 6  , 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|sreg, R:r32}
+    3138             :   ISIGNATURE(2, 0, 1, 0, 7  , 8  , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:r64|sreg|i32}
+    3139             :   ISIGNATURE(2, 1, 1, 0, 9  , 10 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi, R:r8lo|r8hi|m8|mem|i8|u8}
+    3140             :   ISIGNATURE(2, 1, 1, 0, 11 , 12 , 0  , 0  , 0  , 0  ), //      {W:r16|sreg, R:r16|m16|mem}
+    3141             :   ISIGNATURE(2, 1, 1, 0, 13 , 14 , 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem|sreg|i32|u32}
+    3142             :   ISIGNATURE(2, 0, 1, 0, 15 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64|sreg, R:r64|m64|mem}
+    3143             :   ISIGNATURE(2, 1, 1, 0, 17 , 18 , 0  , 0  , 0  , 0  ), //      {W:r16|m16, R:i16|u16}
+    3144             :   ISIGNATURE(2, 0, 1, 0, 19 , 20 , 0  , 0  , 0  , 0  ), //      {W:r64, R:i64|u64|creg|dreg}
+    3145             :   ISIGNATURE(2, 1, 1, 0, 21 , 22 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi|m8, R:i8|u8}
+    3146             :   ISIGNATURE(2, 1, 1, 0, 23 , 24 , 0  , 0  , 0  , 0  ), //      {W:r32|m32, R:i32|u32}
+    3147             :   ISIGNATURE(2, 1, 0, 0, 13 , 25 , 0  , 0  , 0  , 0  ), //      {W:r32, R:creg|dreg}
+    3148             :   ISIGNATURE(2, 1, 0, 0, 26 , 6  , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r32}
+    3149             :   ISIGNATURE(2, 0, 1, 0, 26 , 27 , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r64}
+    3150             :   ISIGNATURE(2, 1, 1, 0, 28 , 22 , 0  , 0  , 0  , 0  ), // #15  {X:r8lo|r8hi|m8, R:i8|u8}
+    3151             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3152             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3153             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3154             :   ISIGNATURE(2, 1, 1, 0, 33 , 34 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3155             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3156             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3157             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3158             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3159             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), // #24  {X:r16, R:r16|m16|mem}
+    3160             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), // #25  {X:r32, R:r32|m32|mem}
+    3161             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3162             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #27  {R:r8lo|r8hi|m8, R:i8|u8}
+    3163             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3164             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3165             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3166             :   ISIGNATURE(2, 1, 1, 0, 48 , 34 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3167             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3168             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3169             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3170             :   ISIGNATURE(2, 1, 1, 0, 2  , 40 , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3171             :   ISIGNATURE(2, 1, 1, 0, 37 , 12 , 0  , 0  , 0  , 0  ), //      {R:r16, R:r16|m16|mem}
+    3172             :   ISIGNATURE(2, 1, 1, 0, 6  , 43 , 0  , 0  , 0  , 0  ), //      {R:r32, R:r32|m32|mem}
+    3173             :   ISIGNATURE(2, 0, 1, 0, 27 , 16 , 0  , 0  , 0  , 0  ), //      {R:r64, R:r64|m64|mem}
+    3174             :   ISIGNATURE(2, 1, 1, 0, 49 , 22 , 0  , 0  , 0  , 0  ), // #39  {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:i8|u8}
+    3175             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3176             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3177             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3178             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3179             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3180             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3181             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3182             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem}
+    3183             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem}
+    3184             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3185             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #50  {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3186             :   ISIGNATURE(3, 1, 1, 2, 51 , 50 , 12 , 0  , 0  , 0  ), //      {W:<dx>, X:<ax>, R:r16|m16|mem}
+    3187             :   ISIGNATURE(3, 1, 1, 2, 52 , 53 , 43 , 0  , 0  , 0  ), //      {W:<edx>, X:<eax>, R:r32|m32|mem}
+    3188             :   ISIGNATURE(3, 0, 1, 2, 54 , 55 , 16 , 0  , 0  , 0  ), //      {W:<rdx>, X:<rax>, R:r64|m64|mem}
+    3189             :   ISIGNATURE(2, 1, 1, 0, 41 , 56 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem|i8|i16}
+    3190             :   ISIGNATURE(2, 1, 1, 0, 42 , 57 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem|i8|i32}
+    3191             :   ISIGNATURE(2, 0, 1, 0, 44 , 58 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem|i8|i32}
+    3192             :   ISIGNATURE(3, 1, 1, 0, 59 , 12 , 60 , 0  , 0  , 0  ), //      {W:r16, R:r16|m16|mem, R:i8|i16|u16}
+    3193             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 61 , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem, R:i8|i32|u32}
+    3194             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 62 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:i8|i32}
+    3195             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), // #60  {X:r16|m16|mem, X:r16}
+    3196             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3197             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3198             :   ISIGNATURE(2, 1, 1, 0, 41 , 36 , 0  , 0  , 0  , 0  ), //      {X:r16, X:r16|m16|mem}
+    3199             :   ISIGNATURE(2, 1, 1, 0, 42 , 38 , 0  , 0  , 0  , 0  ), //      {X:r32, X:r32|m32|mem}
+    3200             :   ISIGNATURE(2, 0, 1, 0, 44 , 31 , 0  , 0  , 0  , 0  ), //      {X:r64, X:r64|m64|mem}
+    3201             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3202             :   ISIGNATURE(2, 1, 1, 0, 39 , 35 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, X:r8lo|r8hi|m8|mem}
+    3203             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #68  {R:r8lo|r8hi|m8, R:i8|u8}
+    3204             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3205             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3206             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3207             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3208             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3209             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3210             :   ISIGNATURE(2, 1, 1, 0, 59 , 63 , 0  , 0  , 0  , 0  ), // #75  {W:r16, R:m16|mem}
+    3211             :   ISIGNATURE(2, 1, 1, 0, 13 , 64 , 0  , 0  , 0  , 0  ), //      {W:r32, R:m32|mem}
+    3212             :   ISIGNATURE(2, 0, 1, 0, 19 , 65 , 0  , 0  , 0  , 0  ), //      {W:r64, R:m64|mem}
+    3213             :   ISIGNATURE(2, 1, 1, 0, 66 , 37 , 0  , 0  , 0  , 0  ), //      {W:m16|mem, R:r16}
+    3214             :   ISIGNATURE(2, 1, 1, 0, 67 , 6  , 0  , 0  , 0  , 0  ), // #79  {W:m32|mem, R:r32}
+    3215             :   ISIGNATURE(2, 0, 1, 0, 68 , 27 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:r64}
+    3216             :   ISIGNATURE(2, 1, 1, 0, 69 , 70 , 0  , 0  , 0  , 0  ), // #81  {W:mm, R:mm|m64|mem|r64|xmm}
+    3217             :   ISIGNATURE(2, 1, 1, 0, 71 , 72 , 0  , 0  , 0  , 0  ), //      {W:mm|m64|mem|r64|xmm, R:mm}
+    3218             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:xmm}
+    3219             :   ISIGNATURE(2, 0, 1, 0, 74 , 16 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:r64|m64|mem}
+    3220             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #85  {W:xmm, R:xmm|m64|mem}
+    3221             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3222             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #87  {W:xmm, R:xmm|m128|mem}
+    3223             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:xmm}
+    3224             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3225             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3226             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), // #91  {W:zmm, R:zmm|m512|mem}
+    3227             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3228             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #93  {W:xmm, R:xmm, R:xmm|m128|mem}
+    3229             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #94  {W:xmm, R:xmm|m128|mem, R:u8}
+    3230             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #95  {W:ymm, R:ymm, R:ymm|m256|mem}
+    3231             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #96  {W:ymm, R:ymm|m256|mem, R:u8}
+    3232             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3233             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3234             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 88 , 0  , 0  , 0  ), // #99  {W:xmm, R:xmm, R:u8|xmm|m128|mem}
+    3235             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 88 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:u8|xmm|m128|mem}
+    3236             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #101 {W:xmm, R:xmm|m128|mem, R:u8}
+    3237             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3238             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3239             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3240             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #105 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3241             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8}
+    3242             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 77 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:xmm|m128|mem}
+    3243             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3244             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3245             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3246             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #111 {X:xmm, R:vm32x, X:xmm}
+    3247             :   ISIGNATURE(3, 1, 1, 0, 91 , 90 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32x, X:ymm}
+    3248             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3249             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3250             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3251             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #116 {X:xmm, R:vm32x, X:xmm}
+    3252             :   ISIGNATURE(3, 1, 1, 0, 91 , 92 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32y, X:ymm}
+    3253             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3254             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3255             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3256             :   ISIGNATURE(3, 1, 1, 0, 89 , 95 , 89 , 0  , 0  , 0  ), // #121 {X:xmm, R:vm64x, X:xmm}
+    3257             :   ISIGNATURE(3, 1, 1, 0, 91 , 96 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm64y, X:ymm}
+    3258             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3259             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3260             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3261             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), // #126 {R:r16|m16|mem, R:r16}
+    3262             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3263             :   ISIGNATURE(2, 0, 1, 0, 16 , 98 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:r64|u8}
+    3264             :   ISIGNATURE(2, 1, 1, 0, 99 , 87 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32, R:u8}
+    3265             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #130 {X:r16|m16|mem, R:r16}
+    3266             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3267             :   ISIGNATURE(2, 0, 1, 0, 31 , 98 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64|u8}
+    3268             :   ISIGNATURE(2, 1, 1, 0, 100, 87 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32, R:u8}
+    3269             :   ISIGNATURE(3, 1, 1, 1, 35 , 2  , 101, 0  , 0  , 0  ), // #134 {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi, R:<al>}
+    3270             :   ISIGNATURE(3, 1, 1, 1, 36 , 37 , 102, 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16, R:<ax>}
+    3271             :   ISIGNATURE(3, 1, 1, 1, 38 , 6  , 103, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:<eax>}
+    3272             :   ISIGNATURE(3, 0, 1, 1, 31 , 27 , 104, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:<rax>}
+    3273             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #138 {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3274             :   ISIGNATURE(3, 1, 1, 2, 105, 50 , 12 , 0  , 0  , 0  ), //      {X:<dx>, X:<ax>, R:r16|m16|mem}
+    3275             :   ISIGNATURE(3, 1, 1, 2, 106, 53 , 43 , 0  , 0  , 0  ), //      {X:<edx>, X:<eax>, R:r32|m32|mem}
+    3276             :   ISIGNATURE(3, 0, 1, 2, 107, 55 , 16 , 0  , 0  , 0  ), //      {X:<rdx>, X:<rax>, R:r64|m64|mem}
+    3277             :   ISIGNATURE(1, 1, 1, 0, 108, 0  , 0  , 0  , 0  , 0  ), // #142 {W:r16|m16|r64|m64|mem}
+    3278             :   ISIGNATURE(1, 1, 0, 0, 23 , 0  , 0  , 0  , 0  , 0  ), //      {W:r32|m32}
+    3279             :   ISIGNATURE(1, 1, 0, 0, 109, 0  , 0  , 0  , 0  , 0  ), //      {W:ds|es|ss}
+    3280             :   ISIGNATURE(1, 1, 1, 0, 110, 0  , 0  , 0  , 0  , 0  ), //      {W:fs|gs}
+    3281             :   ISIGNATURE(1, 1, 1, 0, 111, 0  , 0  , 0  , 0  , 0  ), // #146 {R:r16|m16|r64|m64|mem|i8|i16|i32}
+    3282             :   ISIGNATURE(1, 1, 0, 0, 47 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32}
+    3283             :   ISIGNATURE(1, 1, 0, 0, 112, 0  , 0  , 0  , 0  , 0  ), //      {R:cs|ss|ds|es}
+    3284             :   ISIGNATURE(1, 1, 1, 0, 113, 0  , 0  , 0  , 0  , 0  ), //      {R:fs|gs}
+    3285             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 77 , 0  , 0  ), // #150 {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem}
+    3286             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #151 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3287             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 82 , 80 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem}
+    3288             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3289             :   ISIGNATURE(3, 1, 1, 0, 89 , 114, 89 , 0  , 0  , 0  ), // #154 {X:xmm, R:vm64x|vm64y, X:xmm}
+    3290             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3291             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3292             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3293             :   ISIGNATURE(3, 1, 1, 0, 115, 73 , 73 , 0  , 0  , 0  ), // #158 {W:m128|mem, R:xmm, R:xmm}
+    3294             :   ISIGNATURE(3, 1, 1, 0, 116, 82 , 82 , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm, R:ymm}
+    3295             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 117, 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m128|mem}
+    3296             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 118, 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:m256|mem}
+    3297             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 77 , 73 , 119, 0  ), // #162 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm, R:u4}
+    3298             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 73 , 77 , 119, 0  ), //      {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem, R:u4}
+    3299             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 80 , 82 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm, R:u4}
+    3300             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 82 , 80 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem, R:u4}
+    3301             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #166 {W:ymm, R:ymm|m256|mem, R:u8}
+    3302             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #167 {W:ymm, R:ymm, R:ymm|m256|mem}
+    3303             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3304             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3305             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), // #170 {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3306             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, X:r16}
+    3307             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3308             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3309             :   ISIGNATURE(1, 1, 1, 0, 120, 0  , 0  , 0  , 0  , 0  ), // #174 {R:m32|m64}
+    3310             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3311             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3312             :   ISIGNATURE(1, 1, 1, 0, 125, 0  , 0  , 0  , 0  , 0  ), // #177 {X:m32|m64}
+    3313             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3314             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3315             :   ISIGNATURE(2, 1, 1, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #180 {X:r16, R:m32|mem}
+    3316             :   ISIGNATURE(2, 1, 1, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3317             :   ISIGNATURE(2, 0, 1, 0, 44 , 127, 0  , 0  , 0  , 0  ), //      {X:r64, R:m80|mem}
+    3318             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #183 {W:r16, R:r16|m16|mem}
+    3319             :   ISIGNATURE(2, 1, 1, 0, 13 , 43 , 0  , 0  , 0  , 0  ), // #184 {W:r32, R:r32|m32|mem}
+    3320             :   ISIGNATURE(2, 0, 1, 0, 19 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem}
+    3321             :   ISIGNATURE(3, 1, 1, 0, 36 , 37 , 128, 0  , 0  , 0  ), // #186 {X:r16|m16|mem, R:r16, R:u8|cl}
+    3322             :   ISIGNATURE(3, 1, 1, 0, 38 , 6  , 128, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:u8|cl}
+    3323             :   ISIGNATURE(3, 0, 1, 0, 31 , 27 , 128, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:u8|cl}
+    3324             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #189 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3325             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem}
+    3326             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3327             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 87 , 0  , 0  ), // #192 {W:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3328             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 87 , 0  , 0  ), // #193 {W:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3329             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 84 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3330             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 77 , 87 , 0  , 0  ), // #195 {W:xmm|k, R:xmm, R:xmm|m128|mem, R:u8}
+    3331             :   ISIGNATURE(4, 1, 1, 0, 130, 82 , 80 , 87 , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem, R:u8}
+    3332             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3333             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), // #198 {W:xmm|m128|mem, R:xmm}
+    3334             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3335             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3336             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #201 {W:xmm, R:xmm|m64|mem}
+    3337             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3338             :   ISIGNATURE(2, 1, 1, 0, 83 , 80 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256|mem}
+    3339             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #204 {W:xmm, R:xmm|m128|mem}
+    3340             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3341             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3342             :   ISIGNATURE(2, 1, 1, 0, 74 , 132, 0  , 0  , 0  , 0  ), // #207 {W:xmm, R:xmm|m128|ymm|m256|m64}
+    3343             :   ISIGNATURE(2, 1, 1, 0, 79 , 133, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128}
+    3344             :   ISIGNATURE(2, 1, 1, 0, 83 , 134, 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256}
+    3345             :   ISIGNATURE(3, 1, 1, 0, 76 , 73 , 87 , 0  , 0  , 0  ), // #210 {W:xmm|m64|mem, R:xmm, R:u8}
+    3346             :   ISIGNATURE(3, 1, 1, 0, 78 , 82 , 87 , 0  , 0  , 0  ), // #211 {W:xmm|m128|mem, R:ymm, R:u8}
+    3347             :   ISIGNATURE(3, 1, 1, 0, 81 , 86 , 87 , 0  , 0  , 0  ), // #212 {W:ymm|m256|mem, R:zmm, R:u8}
+    3348             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 77 , 87 , 0  , 0  ), // #213 {X:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3349             :   ISIGNATURE(4, 1, 1, 0, 91 , 82 , 80 , 87 , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3350             :   ISIGNATURE(4, 1, 1, 0, 93 , 86 , 84 , 87 , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3351             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 77 , 0  , 0  , 0  ), // #216 {X:xmm, R:xmm, R:xmm|m128|mem}
+    3352             :   ISIGNATURE(3, 1, 1, 0, 91 , 82 , 80 , 0  , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem}
+    3353             :   ISIGNATURE(3, 1, 1, 0, 93 , 86 , 84 , 0  , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem}
+    3354             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #219 {W:xmm, R:xmm|m128|mem, R:u8}
+    3355             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3356             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3357             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #222 {W:xmm, R:xmm|m64|mem}
+    3358             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3359             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3360             :   ISIGNATURE(2, 1, 1, 0, 115, 73 , 0  , 0  , 0  , 0  ), // #225 {W:m128|mem, R:xmm}
+    3361             :   ISIGNATURE(2, 1, 1, 0, 116, 82 , 0  , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm}
+    3362             :   ISIGNATURE(2, 1, 1, 0, 135, 86 , 0  , 0  , 0  , 0  ), //      {W:m512|mem, R:zmm}
+    3363             :   ISIGNATURE(2, 1, 1, 0, 74 , 117, 0  , 0  , 0  , 0  ), // #228 {W:xmm, R:m128|mem}
+    3364             :   ISIGNATURE(2, 1, 1, 0, 79 , 118, 0  , 0  , 0  , 0  ), //      {W:ymm, R:m256|mem}
+    3365             :   ISIGNATURE(2, 1, 1, 0, 83 , 136, 0  , 0  , 0  , 0  ), //      {W:zmm, R:m512|mem}
+    3366             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), // #231 {W:r64|m64|mem, R:xmm}
+    3367             :   ISIGNATURE(2, 1, 1, 0, 74 , 137, 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m64|mem|r64}
+    3368             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3369             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #234 {W:m64|mem, R:xmm}
+    3370             :   ISIGNATURE(2, 1, 1, 0, 74 , 65 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m64|mem}
+    3371             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), // #236 {W:xmm, R:xmm, R:xmm}
+    3372             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), // #237 {W:m32|mem, R:xmm}
+    3373             :   ISIGNATURE(2, 1, 1, 0, 74 , 64 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m32|mem}
+    3374             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm}
+    3375             :   ISIGNATURE(4, 1, 1, 0, 131, 73 , 77 , 87 , 0  , 0  ), // #240 {W:k, R:xmm, R:xmm|m128|mem, R:u8}
+    3376             :   ISIGNATURE(4, 1, 1, 0, 131, 82 , 80 , 87 , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem, R:u8}
+    3377             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3378             :   ISIGNATURE(3, 1, 1, 0, 129, 73 , 77 , 0  , 0  , 0  ), // #243 {W:xmm|k, R:xmm, R:xmm|m128|mem}
+    3379             :   ISIGNATURE(3, 1, 1, 0, 130, 82 , 80 , 0  , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem}
+    3380             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3381             :   ISIGNATURE(2, 1, 1, 0, 138, 73 , 0  , 0  , 0  , 0  ), // #246 {W:xmm|m32|mem, R:xmm}
+    3382             :   ISIGNATURE(2, 1, 1, 0, 76 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:ymm}
+    3383             :   ISIGNATURE(2, 1, 1, 0, 78 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:zmm}
+    3384             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), // #249 {W:xmm|m64|mem, R:xmm}
+    3385             :   ISIGNATURE(2, 1, 1, 0, 78 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:ymm}
+    3386             :   ISIGNATURE(2, 1, 1, 0, 81 , 86 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:zmm}
+    3387             :   ISIGNATURE(2, 1, 1, 0, 139, 73 , 0  , 0  , 0  , 0  ), // #252 {W:xmm|m16|mem, R:xmm}
+    3388             :   ISIGNATURE(2, 1, 1, 0, 138, 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m32|mem, R:ymm}
+    3389             :   ISIGNATURE(2, 1, 1, 0, 76 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:zmm}
+    3390             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #255 {W:xmm, R:xmm|m32|mem}
+    3391             :   ISIGNATURE(2, 1, 1, 0, 79 , 75 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m64|mem}
+    3392             :   ISIGNATURE(2, 1, 1, 0, 83 , 77 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m128|mem}
+    3393             :   ISIGNATURE(2, 1, 1, 0, 74 , 141, 0  , 0  , 0  , 0  ), // #258 {W:xmm, R:xmm|m16|mem}
+    3394             :   ISIGNATURE(2, 1, 1, 0, 79 , 140, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m32|mem}
+    3395             :   ISIGNATURE(2, 1, 1, 0, 83 , 75 , 0  , 0  , 0  , 0  ), // #260 {W:zmm, R:xmm|m64|mem}
+    3396             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #261 {W:xmm, R:xmm|m64|mem}
+    3397             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3398             :   ISIGNATURE(2, 1, 1, 0, 83 , 142, 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m256|mem}
+    3399             :   ISIGNATURE(2, 1, 1, 0, 143, 73 , 0  , 0  , 0  , 0  ), // #264 {W:vm32x, R:xmm}
+    3400             :   ISIGNATURE(2, 1, 1, 0, 144, 82 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:ymm}
+    3401             :   ISIGNATURE(2, 1, 1, 0, 145, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32z, R:zmm}
+    3402             :   ISIGNATURE(2, 1, 1, 0, 146, 73 , 0  , 0  , 0  , 0  ), // #267 {W:vm64x, R:xmm}
+    3403             :   ISIGNATURE(2, 1, 1, 0, 147, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64y, R:ymm}
+    3404             :   ISIGNATURE(2, 1, 1, 0, 148, 86 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:zmm}
+    3405             :   ISIGNATURE(3, 1, 1, 0, 131, 73 , 77 , 0  , 0  , 0  ), // #270 {W:k, R:xmm, R:xmm|m128|mem}
+    3406             :   ISIGNATURE(3, 1, 1, 0, 131, 82 , 80 , 0  , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem}
+    3407             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3408             :   ISIGNATURE(3, 1, 1, 0, 13 , 6  , 43 , 0  , 0  , 0  ), // #273 {W:r32, R:r32, R:r32|m32|mem}
+    3409             :   ISIGNATURE(3, 0, 1, 0, 19 , 27 , 16 , 0  , 0  , 0  ), //      {W:r64, R:r64, R:r64|m64|mem}
+    3410             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 6  , 0  , 0  , 0  ), // #275 {W:r32, R:r32|m32|mem, R:r32}
+    3411             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 27 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:r64}
+    3412             :   ISIGNATURE(2, 1, 0, 0, 149, 43 , 0  , 0  , 0  , 0  ), // #277 {R:bnd, R:r32|m32|mem}
+    3413             :   ISIGNATURE(2, 0, 1, 0, 149, 16 , 0  , 0  , 0  , 0  ), //      {R:bnd, R:r64|m64|mem}
+    3414             :   ISIGNATURE(2, 1, 1, 0, 150, 151, 0  , 0  , 0  , 0  ), // #279 {W:bnd, R:bnd|mem}
+    3415             :   ISIGNATURE(2, 1, 1, 0, 152, 149, 0  , 0  , 0  , 0  ), //      {W:bnd|mem, R:bnd}
+    3416             :   ISIGNATURE(2, 1, 0, 0, 37 , 64 , 0  , 0  , 0  , 0  ), // #281 {R:r16, R:m32|mem}
+    3417             :   ISIGNATURE(2, 1, 0, 0, 6  , 65 , 0  , 0  , 0  , 0  ), //      {R:r32, R:m64|mem}
+    3418             :   ISIGNATURE(1, 1, 1, 0, 153, 0  , 0  , 0  , 0  , 0  ), // #283 {R:rel32|r64|m64|mem}
+    3419             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3420             :   ISIGNATURE(2, 1, 1, 0, 42 , 154, 0  , 0  , 0  , 0  ), // #285 {X:r32, R:r8lo|r8hi|m8|r16|m16|r32|m32}
+    3421             :   ISIGNATURE(2, 0, 1, 0, 44 , 155, 0  , 0  , 0  , 0  ), //      {X:r64, R:r8lo|r8hi|m8|r64|m64}
+    3422             :   ISIGNATURE(1, 1, 0, 0, 156, 0  , 0  , 0  , 0  , 0  ), // #287 {X:r16|r32}
+    3423             :   ISIGNATURE(1, 1, 1, 0, 49 , 0  , 0  , 0  , 0  , 0  ), // #288 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem}
+    3424             :   ISIGNATURE(3, 1, 1, 0, 89 , 87 , 87 , 0  , 0  , 0  ), // #289 {X:xmm, R:u8, R:u8}
+    3425             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:xmm}
+    3426             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #291 {}
+    3427             :   ISIGNATURE(1, 1, 1, 0, 123, 0  , 0  , 0  , 0  , 0  ), // #292 {X:fp}
+    3428             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #293 {}
+    3429             :   ISIGNATURE(1, 1, 1, 0, 157, 0  , 0  , 0  , 0  , 0  ), //      {R:m32|m64|fp}
+    3430             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #295 {}
+    3431             :   ISIGNATURE(1, 1, 1, 0, 122, 0  , 0  , 0  , 0  , 0  ), // #296 {R:fp}
+    3432             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), // #297 {X:xmm, R:xmm}
+    3433             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 87 , 87 , 0  , 0  ), //      {X:xmm, R:xmm, R:u8, R:u8}
+    3434             :   ISIGNATURE(2, 1, 0, 0, 6  , 117, 0  , 0  , 0  , 0  ), // #299 {R:r32, R:m128|mem}
+    3435             :   ISIGNATURE(2, 0, 1, 0, 27 , 117, 0  , 0  , 0  , 0  ), //      {R:r64, R:m128|mem}
+    3436             :   ISIGNATURE(2, 1, 0, 1, 158, 159, 0  , 0  , 0  , 0  ), // #301 {R:<cx|ecx>, R:rel8}
+    3437             :   ISIGNATURE(2, 0, 1, 1, 160, 159, 0  , 0  , 0  , 0  ), //      {R:<ecx|rcx>, R:rel8}
+    3438             :   ISIGNATURE(1, 1, 1, 0, 161, 0  , 0  , 0  , 0  , 0  ), // #303 {R:rel8|rel32|r64|m64|mem}
+    3439             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3440             :   ISIGNATURE(2, 1, 1, 0, 131, 162, 0  , 0  , 0  , 0  ), // #305 {W:k, R:k|m8|mem|r32|r64|r8lo|r8hi|r16}
+    3441             :   ISIGNATURE(2, 1, 1, 0, 163, 164, 0  , 0  , 0  , 0  ), //      {W:m8|mem|r32|r64|r8lo|r8hi|r16, R:k}
+    3442             :   ISIGNATURE(2, 1, 1, 0, 131, 165, 0  , 0  , 0  , 0  ), // #307 {W:k, R:k|m32|mem|r32|r64}
+    3443             :   ISIGNATURE(2, 1, 1, 0, 166, 164, 0  , 0  , 0  , 0  ), //      {W:m32|mem|r32|r64, R:k}
+    3444             :   ISIGNATURE(2, 1, 1, 0, 131, 167, 0  , 0  , 0  , 0  ), // #309 {W:k, R:k|m64|mem|r64}
+    3445             :   ISIGNATURE(2, 1, 1, 0, 7  , 164, 0  , 0  , 0  , 0  ), //      {W:m64|mem|r64, R:k}
+    3446             :   ISIGNATURE(2, 1, 1, 0, 131, 168, 0  , 0  , 0  , 0  ), // #311 {W:k, R:k|m16|mem|r32|r64|r16}
+    3447             :   ISIGNATURE(2, 1, 1, 0, 169, 164, 0  , 0  , 0  , 0  ), //      {W:m16|mem|r32|r64|r16, R:k}
+    3448             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #313 {W:r16, R:r16|m16|mem}
+    3449             :   ISIGNATURE(2, 1, 1, 0, 13 , 170, 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m16|mem|r16}
+    3450             :   ISIGNATURE(2, 1, 0, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #315 {X:r16, R:m32|mem}
+    3451             :   ISIGNATURE(2, 1, 0, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3452             :   ISIGNATURE(2, 1, 0, 1, 171, 159, 0  , 0  , 0  , 0  ), // #317 {X:<cx|ecx>, R:rel8}
+    3453             :   ISIGNATURE(2, 0, 1, 1, 172, 159, 0  , 0  , 0  , 0  ), //      {X:<ecx|rcx>, R:rel8}
+    3454             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #319 {W:r16, R:r16|m16|mem}
+    3455             :   ISIGNATURE(2, 1, 1, 0, 173, 170, 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r32|m16|mem|r16}
+    3456             :   ISIGNATURE(2, 1, 1, 0, 174, 175, 0  , 0  , 0  , 0  ), // #321 {W:mm|xmm, R:r32|m32|mem|r64}
+    3457             :   ISIGNATURE(2, 1, 1, 0, 166, 176, 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|r64, R:mm|xmm}
+    3458             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #323 {W:xmm, R:xmm|m64|mem}
+    3459             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:xmm}
+    3460             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #325 {W:xmm, R:xmm|m32|mem}
+    3461             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), //      {W:m32|mem, R:xmm}
+    3462             :   ISIGNATURE(2, 1, 1, 0, 177, 45 , 0  , 0  , 0  , 0  ), // #327 {W:r16|r32|r64, R:r8lo|r8hi|m8}
+    3463             :   ISIGNATURE(2, 1, 1, 0, 173, 46 , 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r16|m16}
+    3464             :   ISIGNATURE(4, 1, 1, 1, 13 , 13 , 43 , 178, 0  , 0  ), // #329 {W:r32, W:r32, R:r32|m32|mem, R:<edx>}
+    3465             :   ISIGNATURE(4, 0, 1, 1, 19 , 19 , 16 , 179, 0  , 0  ), //      {W:r64, W:r64, R:r64|m64|mem, R:<rdx>}
+    3466             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #331 {}
+    3467             :   ISIGNATURE(1, 1, 1, 0, 99 , 0  , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32}
+    3468             :   ISIGNATURE(2, 1, 1, 0, 69 , 180, 0  , 0  , 0  , 0  ), // #333 {W:mm, R:mm|m64|mem}
+    3469             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem}
+    3470             :   ISIGNATURE(2, 1, 1, 0, 181, 180, 0  , 0  , 0  , 0  ), // #335 {X:mm, R:mm|m64|mem}
+    3471             :   ISIGNATURE(2, 1, 1, 0, 89 , 77 , 0  , 0  , 0  , 0  ), // #336 {X:xmm, R:xmm|m128|mem}
+    3472             :   ISIGNATURE(3, 1, 1, 0, 181, 180, 87 , 0  , 0  , 0  ), // #337 {X:mm, R:mm|m64|mem, R:u8}
+    3473             :   ISIGNATURE(3, 1, 1, 0, 89 , 77 , 87 , 0  , 0  , 0  ), // #338 {X:xmm, R:xmm|m128|mem, R:u8}
+    3474             :   ISIGNATURE(3, 1, 1, 0, 173, 72 , 87 , 0  , 0  , 0  ), // #339 {W:r32|r64, R:mm, R:u8}
+    3475             :   ISIGNATURE(3, 1, 1, 0, 169, 73 , 87 , 0  , 0  , 0  ), // #340 {W:r32|r64|m16|mem|r16, R:xmm, R:u8}
+    3476             :   ISIGNATURE(2, 1, 1, 0, 181, 182, 0  , 0  , 0  , 0  ), // #341 {X:mm, R:u8|mm|m64|mem}
+    3477             :   ISIGNATURE(2, 1, 1, 0, 89 , 88 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:u8|xmm|m128|mem}
+    3478             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #343 {}
+    3479             :   ISIGNATURE(1, 1, 1, 0, 183, 0  , 0  , 0  , 0  , 0  ), //      {R:u16}
+    3480             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 87 , 0  , 0  , 0  ), // #345 {W:r32, R:r32|m32|mem, R:u8}
+    3481             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 87 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:u8}
+    3482             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #347 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3483             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3484             :   ISIGNATURE(2, 1, 1, 0, 74 , 184, 0  , 0  , 0  , 0  ), // #349 {W:xmm, R:xmm|m128|ymm|m256}
+    3485             :   ISIGNATURE(2, 1, 1, 0, 79 , 84 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:zmm|m512|mem}
+    3486             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 75 , 0  , 0  ), // #351 {W:xmm, R:xmm, R:xmm, R:xmm|m64|mem}
+    3487             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m64|mem, R:xmm}
+    3488             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 140, 0  , 0  ), // #353 {W:xmm, R:xmm, R:xmm, R:xmm|m32|mem}
+    3489             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m32|mem, R:xmm}
+    3490             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 77 , 87 , 0  , 0  ), // #355 {W:ymm, R:ymm, R:xmm|m128|mem, R:u8}
+    3491             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 77 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem, R:u8}
+    3492             :   ISIGNATURE(2, 1, 1, 0, 166, 73 , 0  , 0  , 0  , 0  ), // #357 {W:r32|m32|mem|r64, R:xmm}
+    3493             :   ISIGNATURE(2, 1, 1, 0, 74 , 175, 0  , 0  , 0  , 0  ), //      {W:xmm, R:r32|m32|mem|r64}
+    3494             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #359 {W:m64|mem, R:xmm}
+    3495             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 65 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m64|mem}
+    3496             :   ISIGNATURE(2, 1, 1, 0, 185, 186, 0  , 0  , 0  , 0  ), // #361 {W:xmm|ymm|zmm, R:xmm|m8|mem}
+    3497             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3498             :   ISIGNATURE(2, 1, 1, 0, 185, 140, 0  , 0  , 0  , 0  ), // #363 {W:xmm|ymm|zmm, R:xmm|m32|mem}
+    3499             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3500             :   ISIGNATURE(2, 1, 1, 0, 185, 141, 0  , 0  , 0  , 0  ), // #365 {W:xmm|ymm|zmm, R:xmm|m16|mem}
+    3501             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3502             :   ISIGNATURE(3, 1, 1, 0, 74 , 188, 87 , 0  , 0  , 0  ), // #367 {W:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3503             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 188, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3504             :   ISIGNATURE(3, 1, 1, 0, 74 , 175, 87 , 0  , 0  , 0  ), // #369 {W:xmm, R:r32|m32|mem|r64, R:u8}
+    3505             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 175, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m32|mem|r64, R:u8}
+    3506             :   ISIGNATURE(3, 0, 1, 0, 74 , 16 , 87 , 0  , 0  , 0  ), // #371 {W:xmm, R:r64|m64|mem, R:u8}
+    3507             :   ISIGNATURE(4, 0, 1, 0, 74 , 73 , 16 , 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r64|m64|mem, R:u8}
+    3508             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #373 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3509             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 189, 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8|xmm}
+    3510             :   ISIGNATURE(2, 1, 1, 0, 190, 73 , 0  , 0  , 0  , 0  ), // #375 {W:vm64x|vm64y, R:xmm}
+    3511             :   ISIGNATURE(2, 1, 1, 0, 148, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:ymm}
+    3512             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #377 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3513             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:xmm}
+    3514             :   ISIGNATURE(2, 1, 1, 0, 73 , 77 , 0  , 0  , 0  , 0  ), // #379 {R:xmm, R:xmm|m128|mem}
+    3515             :   ISIGNATURE(2, 1, 1, 0, 82 , 80 , 0  , 0  , 0  , 0  ), //      {R:ymm, R:ymm|m256|mem}
+    3516             :   ISIGNATURE(2, 1, 1, 0, 143, 191, 0  , 0  , 0  , 0  ), // #381 {W:vm32x, R:xmm|ymm}
+    3517             :   ISIGNATURE(2, 1, 1, 0, 144, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:zmm}
+    3518             :   ISIGNATURE(1, 1, 0, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #383 {X:<ax>}
+    3519             :   ISIGNATURE(2, 1, 0, 1, 50 , 87 , 0  , 0  , 0  , 0  ), // #384 {X:<ax>, R:u8}
+    3520             :   ISIGNATURE(2, 1, 1, 0, 89 , 75 , 0  , 0  , 0  , 0  ), // #385 {X:xmm, R:xmm|m64|mem}
+    3521             :   ISIGNATURE(2, 1, 1, 0, 89 , 140, 0  , 0  , 0  , 0  ), // #386 {X:xmm, R:xmm|m32|mem}
+    3522             :   ISIGNATURE(2, 1, 0, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #387 {X:r16|m16|mem, R:r16}
+    3523             :   ISIGNATURE(3, 1, 1, 1, 89 , 77 , 192, 0  , 0  , 0  ), // #388 {X:xmm, R:xmm|m128|mem, R:<xmm0>}
+    3524             :   ISIGNATURE(2, 1, 1, 0, 150, 193, 0  , 0  , 0  , 0  ), // #389 {W:bnd, R:mib}
+    3525             :   ISIGNATURE(2, 1, 1, 0, 150, 194, 0  , 0  , 0  , 0  ), // #390 {W:bnd, R:mem}
+    3526             :   ISIGNATURE(2, 1, 1, 0, 195, 149, 0  , 0  , 0  , 0  ), // #391 {W:mib, R:bnd}
+    3527             :   ISIGNATURE(1, 1, 1, 0, 196, 0  , 0  , 0  , 0  , 0  ), // #392 {X:r32|r64}
+    3528             :   ISIGNATURE(1, 1, 1, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #393 {X:<ax>}
+    3529             :   ISIGNATURE(2, 1, 1, 2, 52 , 103, 0  , 0  , 0  , 0  ), // #394 {W:<edx>, R:<eax>}
+    3530             :   ISIGNATURE(1, 0, 1, 1, 55 , 0  , 0  , 0  , 0  , 0  ), // #395 {X:<rax>}
+    3531             :   ISIGNATURE(1, 1, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #396 {R:mem}
+    3532             :   ISIGNATURE(1, 1, 1, 1, 197, 0  , 0  , 0  , 0  , 0  ), // #397 {R:<ds:[zax]>}
+    3533             :   ISIGNATURE(2, 1, 1, 2, 198, 199, 0  , 0  , 0  , 0  ), // #398 {X:<ds:[zsi]>, X:<es:[zdi]>}
+    3534             :   ISIGNATURE(3, 1, 1, 0, 89 , 75 , 87 , 0  , 0  , 0  ), // #399 {X:xmm, R:xmm|m64|mem, R:u8}
+    3535             :   ISIGNATURE(3, 1, 1, 0, 89 , 140, 87 , 0  , 0  , 0  ), // #400 {X:xmm, R:xmm|m32|mem, R:u8}
+    3536             :   ISIGNATURE(5, 0, 1, 4, 200, 107, 55 , 201, 202, 0  ), // #401 {X:m128|mem, X:<rdx>, X:<rax>, R:<rcx>, R:<rbx>}
+    3537             :   ISIGNATURE(5, 1, 1, 4, 203, 106, 53 , 204, 205, 0  ), // #402 {X:m64|mem, X:<edx>, X:<eax>, R:<ecx>, R:<ebx>}
+    3538             :   ISIGNATURE(2, 1, 1, 0, 73 , 75 , 0  , 0  , 0  , 0  ), // #403 {R:xmm, R:xmm|m64|mem}
+    3539             :   ISIGNATURE(2, 1, 1, 0, 73 , 140, 0  , 0  , 0  , 0  ), // #404 {R:xmm, R:xmm|m32|mem}
+    3540             :   ISIGNATURE(4, 1, 1, 4, 53 , 206, 207, 52 , 0  , 0  ), // #405 {X:<eax>, W:<ebx>, X:<ecx>, W:<edx>}
+    3541             :   ISIGNATURE(2, 0, 1, 2, 54 , 104, 0  , 0  , 0  , 0  ), // #406 {W:<rdx>, R:<rax>}
+    3542             :   ISIGNATURE(2, 1, 1, 0, 69 , 77 , 0  , 0  , 0  , 0  ), // #407 {W:mm, R:xmm|m128|mem}
+    3543             :   ISIGNATURE(2, 1, 1, 0, 74 , 180, 0  , 0  , 0  , 0  ), // #408 {W:xmm, R:mm|m64|mem}
+    3544             :   ISIGNATURE(2, 1, 1, 0, 69 , 75 , 0  , 0  , 0  , 0  ), // #409 {W:mm, R:xmm|m64|mem}
+    3545             :   ISIGNATURE(2, 1, 1, 0, 173, 75 , 0  , 0  , 0  , 0  ), // #410 {W:r32|r64, R:xmm|m64|mem}
+    3546             :   ISIGNATURE(2, 1, 1, 0, 74 , 208, 0  , 0  , 0  , 0  ), // #411 {W:xmm, R:r32|m32|mem|r64|m64}
+    3547             :   ISIGNATURE(2, 1, 1, 0, 173, 140, 0  , 0  , 0  , 0  ), // #412 {W:r32|r64, R:xmm|m32|mem}
+    3548             :   ISIGNATURE(2, 1, 1, 2, 51 , 102, 0  , 0  , 0  , 0  ), // #413 {W:<dx>, R:<ax>}
+    3549             :   ISIGNATURE(1, 1, 1, 1, 53 , 0  , 0  , 0  , 0  , 0  ), // #414 {X:<eax>}
+    3550             :   ISIGNATURE(2, 1, 1, 0, 183, 87 , 0  , 0  , 0  , 0  ), // #415 {R:u16, R:u8}
+    3551             :   ISIGNATURE(3, 1, 1, 0, 166, 73 , 87 , 0  , 0  , 0  ), // #416 {W:r32|m32|mem|r64, R:xmm, R:u8}
+    3552             :   ISIGNATURE(1, 1, 1, 0, 127, 0  , 0  , 0  , 0  , 0  ), // #417 {R:m80|mem}
+    3553             :   ISIGNATURE(1, 1, 1, 0, 209, 0  , 0  , 0  , 0  , 0  ), // #418 {W:m80|mem}
+    3554             :   ISIGNATURE(1, 1, 1, 0, 210, 0  , 0  , 0  , 0  , 0  ), // #419 {R:m16|m32}
+    3555             :   ISIGNATURE(1, 1, 1, 0, 211, 0  , 0  , 0  , 0  , 0  ), // #420 {R:m16|m32|m64}
+    3556             :   ISIGNATURE(1, 1, 1, 0, 212, 0  , 0  , 0  , 0  , 0  ), // #421 {W:m16|m32}
+    3557             :   ISIGNATURE(1, 1, 1, 0, 213, 0  , 0  , 0  , 0  , 0  ), // #422 {W:m16|m32|m64}
+    3558             :   ISIGNATURE(1, 1, 1, 0, 214, 0  , 0  , 0  , 0  , 0  ), // #423 {R:m32|m64|m80|fp}
+    3559             :   ISIGNATURE(1, 1, 1, 0, 63 , 0  , 0  , 0  , 0  , 0  ), // #424 {R:m16|mem}
+    3560             :   ISIGNATURE(1, 1, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #425 {W:mem}
+    3561             :   ISIGNATURE(1, 1, 1, 0, 66 , 0  , 0  , 0  , 0  , 0  ), // #426 {W:m16|mem}
+    3562             :   ISIGNATURE(1, 1, 1, 0, 216, 0  , 0  , 0  , 0  , 0  ), // #427 {W:ax|m16|mem}
+    3563             :   ISIGNATURE(1, 1, 1, 0, 217, 0  , 0  , 0  , 0  , 0  ), // #428 {W:m32|m64|fp}
+    3564             :   ISIGNATURE(1, 1, 1, 0, 218, 0  , 0  , 0  , 0  , 0  ), // #429 {W:m32|m64|m80|fp}
+    3565             :   ISIGNATURE(1, 0, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #430 {R:mem}
+    3566             :   ISIGNATURE(1, 0, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #431 {W:mem}
+    3567             :   ISIGNATURE(2, 1, 1, 0, 219, 220, 0  , 0  , 0  , 0  ), // #432 {W:al|ax|eax, R:u8|dx}
+    3568             :   ISIGNATURE(2, 1, 1, 0, 221, 222, 0  , 0  , 0  , 0  ), // #433 {W:es:[zdi], R:dx}
+    3569             :   ISIGNATURE(1, 1, 1, 0, 87 , 0  , 0  , 0  , 0  , 0  ), // #434 {R:u8}
+    3570             :   ISIGNATURE(0, 1, 0, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #435 {}
+    3571             :   ISIGNATURE(0, 0, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #436 {}
+    3572             :   ISIGNATURE(1, 1, 1, 0, 223, 0  , 0  , 0  , 0  , 0  ), // #437 {R:rel8|rel32}
+    3573             :   ISIGNATURE(1, 1, 1, 0, 159, 0  , 0  , 0  , 0  , 0  ), // #438 {R:rel8}
+    3574             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 164, 0  , 0  , 0  ), // #439 {W:k, R:k, R:k}
+    3575             :   ISIGNATURE(2, 1, 1, 0, 131, 164, 0  , 0  , 0  , 0  ), // #440 {W:k, R:k}
+    3576             :   ISIGNATURE(2, 1, 1, 0, 164, 164, 0  , 0  , 0  , 0  ), // #441 {R:k, R:k}
+    3577             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 87 , 0  , 0  , 0  ), // #442 {W:k, R:k, R:u8}
+    3578             :   ISIGNATURE(1, 1, 1, 1, 224, 0  , 0  , 0  , 0  , 0  ), // #443 {W:<ah>}
+    3579             :   ISIGNATURE(1, 1, 1, 0, 64 , 0  , 0  , 0  , 0  , 0  ), // #444 {R:m32|mem}
+    3580             :   ISIGNATURE(2, 1, 1, 0, 177, 225, 0  , 0  , 0  , 0  ), // #445 {W:r16|r32|r64, R:mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+    3581             :   ISIGNATURE(1, 1, 1, 0, 226, 0  , 0  , 0  , 0  , 0  ), // #446 {R:r16|m16|mem|r32|r64}
+    3582             :   ISIGNATURE(2, 1, 1, 2, 227, 198, 0  , 0  , 0  , 0  ), // #447 {W:<al|ax|eax|rax>, X:<ds:[zsi]>}
+    3583             :   ISIGNATURE(3, 1, 1, 1, 89 , 73 , 228, 0  , 0  , 0  ), // #448 {X:xmm, R:xmm, R:<ds:[zdi]>}
+    3584             :   ISIGNATURE(3, 1, 1, 1, 181, 72 , 228, 0  , 0  , 0  ), // #449 {X:mm, R:mm, R:<ds:[zdi]>}
+    3585             :   ISIGNATURE(3, 1, 1, 3, 197, 204, 178, 0  , 0  , 0  ), // #450 {R:<ds:[zax]>, R:<ecx>, R:<edx>}
+    3586             :   ISIGNATURE(2, 1, 1, 0, 69 , 73 , 0  , 0  , 0  , 0  ), // #451 {W:mm, R:xmm}
+    3587             :   ISIGNATURE(2, 1, 1, 0, 74 , 73 , 0  , 0  , 0  , 0  ), // #452 {W:xmm, R:xmm}
+    3588             :   ISIGNATURE(2, 1, 1, 0, 173, 73 , 0  , 0  , 0  , 0  ), // #453 {W:r32|r64, R:xmm}
+    3589             :   ISIGNATURE(2, 1, 1, 0, 68 , 72 , 0  , 0  , 0  , 0  ), // #454 {W:m64|mem, R:mm}
+    3590             :   ISIGNATURE(2, 1, 1, 0, 74 , 72 , 0  , 0  , 0  , 0  ), // #455 {W:xmm, R:mm}
+    3591             :   ISIGNATURE(2, 1, 1, 2, 199, 198, 0  , 0  , 0  , 0  ), // #456 {X:<es:[zdi]>, X:<ds:[zsi]>}
+    3592             :   ISIGNATURE(2, 0, 1, 0, 19 , 43 , 0  , 0  , 0  , 0  ), // #457 {W:r64, R:r32|m32|mem}
+    3593             :   ISIGNATURE(2, 1, 1, 2, 103, 204, 0  , 0  , 0  , 0  ), // #458 {R:<eax>, R:<ecx>}
+    3594             :   ISIGNATURE(2, 1, 1, 0, 220, 229, 0  , 0  , 0  , 0  ), // #459 {R:u8|dx, R:al|ax|eax}
+    3595             :   ISIGNATURE(2, 1, 1, 0, 222, 230, 0  , 0  , 0  , 0  ), // #460 {R:dx, R:ds:[zsi]}
+    3596             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 231, 103, 178), // #461 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>, R:<eax>, R:<edx>}
+    3597             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 232, 103, 178), // #462 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>, R:<eax>, R:<edx>}
+    3598             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 231, 0  , 0  ), // #463 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>}
+    3599             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 232, 0  , 0  ), // #464 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>}
+    3600             :   ISIGNATURE(3, 1, 1, 0, 163, 73 , 87 , 0  , 0  , 0  ), // #465 {W:r32|m8|mem|r8lo|r8hi|r16|r64, R:xmm, R:u8}
+    3601             :   ISIGNATURE(3, 0, 1, 0, 7  , 73 , 87 , 0  , 0  , 0  ), // #466 {W:r64|m64|mem, R:xmm, R:u8}
+    3602             :   ISIGNATURE(3, 1, 1, 0, 89 , 188, 87 , 0  , 0  , 0  ), // #467 {X:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3603             :   ISIGNATURE(3, 1, 1, 0, 89 , 175, 87 , 0  , 0  , 0  ), // #468 {X:xmm, R:r32|m32|mem|r64, R:u8}
+    3604             :   ISIGNATURE(3, 0, 1, 0, 89 , 16 , 87 , 0  , 0  , 0  ), // #469 {X:xmm, R:r64|m64|mem, R:u8}
+    3605             :   ISIGNATURE(3, 1, 1, 0, 233, 226, 87 , 0  , 0  , 0  ), // #470 {X:mm|xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3606             :   ISIGNATURE(2, 1, 1, 0, 173, 176, 0  , 0  , 0  , 0  ), // #471 {W:r32|r64, R:mm|xmm}
+    3607             :   ISIGNATURE(3, 1, 1, 0, 69 , 180, 87 , 0  , 0  , 0  ), // #472 {W:mm, R:mm|m64|mem, R:u8}
+    3608             :   ISIGNATURE(2, 1, 1, 0, 89 , 87 , 0  , 0  , 0  , 0  ), // #473 {X:xmm, R:u8}
+    3609             :   ISIGNATURE(2, 1, 1, 0, 49 , 128, 0  , 0  , 0  , 0  ), // #474 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:cl|u8}
+    3610             :   ISIGNATURE(1, 0, 1, 0, 173, 0  , 0  , 0  , 0  , 0  ), // #475 {W:r32|r64}
+    3611             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 204, 0  , 0  , 0  ), // #476 {W:<edx>, W:<eax>, R:<ecx>}
+    3612             :   ISIGNATURE(1, 1, 1, 0, 177, 0  , 0  , 0  , 0  , 0  ), // #477 {W:r16|r32|r64}
+    3613             :   ISIGNATURE(2, 1, 1, 2, 52 , 234, 0  , 0  , 0  , 0  ), // #478 {W:<edx>, W:<eax>}
+    3614             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 231, 0  , 0  , 0  ), // #479 {W:<edx>, W:<eax>, W:<ecx>}
+    3615             :   ISIGNATURE(3, 1, 1, 0, 74 , 75 , 87 , 0  , 0  , 0  ), // #480 {W:xmm, R:xmm|m64|mem, R:u8}
+    3616             :   ISIGNATURE(3, 1, 1, 0, 74 , 140, 87 , 0  , 0  , 0  ), // #481 {W:xmm, R:xmm|m32|mem, R:u8}
+    3617             :   ISIGNATURE(1, 1, 1, 1, 235, 0  , 0  , 0  , 0  , 0  ), // #482 {R:<ah>}
+    3618             :   ISIGNATURE(2, 1, 1, 2, 236, 199, 0  , 0  , 0  , 0  ), // #483 {R:<al|ax|eax|rax>, X:<es:[zdi]>}
+    3619             :   ISIGNATURE(1, 1, 1, 0, 1  , 0  , 0  , 0  , 0  , 0  ), // #484 {W:r8lo|r8hi|m8|mem}
+    3620             :   ISIGNATURE(1, 1, 1, 0, 169, 0  , 0  , 0  , 0  , 0  ), // #485 {W:r16|m16|mem|r32|r64}
+    3621             :   ISIGNATURE(1, 1, 1, 0, 67 , 0  , 0  , 0  , 0  , 0  ), // #486 {W:m32|mem}
+    3622             :   ISIGNATURE(2, 1, 1, 2, 199, 236, 0  , 0  , 0  , 0  ), // #487 {X:<es:[zdi]>, R:<al|ax|eax|rax>}
+    3623             :   ISIGNATURE(6, 1, 1, 0, 93 , 86 , 86 , 86 , 86 , 117), // #488 {X:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3624             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 75 , 0  , 0  , 0  ), // #489 {W:xmm, R:xmm, R:xmm|m64|mem}
+    3625             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 140, 0  , 0  , 0  ), // #490 {W:xmm, R:xmm, R:xmm|m32|mem}
+    3626             :   ISIGNATURE(2, 1, 1, 0, 79 , 117, 0  , 0  , 0  , 0  ), // #491 {W:ymm, R:m128|mem}
+    3627             :   ISIGNATURE(2, 1, 1, 0, 237, 75 , 0  , 0  , 0  , 0  ), // #492 {W:ymm|zmm, R:xmm|m64|mem}
+    3628             :   ISIGNATURE(2, 1, 1, 0, 237, 117, 0  , 0  , 0  , 0  ), // #493 {W:ymm|zmm, R:m128|mem}
+    3629             :   ISIGNATURE(2, 1, 1, 0, 83 , 118, 0  , 0  , 0  , 0  ), // #494 {W:zmm, R:m256|mem}
+    3630             :   ISIGNATURE(2, 1, 1, 0, 185, 75 , 0  , 0  , 0  , 0  ), // #495 {W:xmm|ymm|zmm, R:xmm|m64|mem}
+    3631             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 75 , 87 , 0  , 0  ), // #496 {W:xmm|k, R:xmm, R:xmm|m64|mem, R:u8}
+    3632             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 140, 87 , 0  , 0  ), // #497 {W:xmm|k, R:xmm, R:xmm|m32|mem, R:u8}
+    3633             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 208, 0  , 0  , 0  ), // #498 {W:xmm, R:xmm, R:r32|m32|mem|r64|m64}
+    3634             :   ISIGNATURE(3, 1, 1, 0, 78 , 238, 87 , 0  , 0  , 0  ), // #499 {W:xmm|m128|mem, R:ymm|zmm, R:u8}
+    3635             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 75 , 87 , 0  , 0  ), // #500 {X:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3636             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 140, 87 , 0  , 0  ), // #501 {X:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3637             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 75 , 0  , 0  , 0  ), // #502 {X:xmm, R:xmm, R:xmm|m64|mem}
+    3638             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 140, 0  , 0  , 0  ), // #503 {X:xmm, R:xmm, R:xmm|m32|mem}
+    3639             :   ISIGNATURE(3, 1, 1, 0, 131, 239, 87 , 0  , 0  , 0  ), // #504 {W:k, R:xmm|m128|ymm|m256|zmm|m512, R:u8}
+    3640             :   ISIGNATURE(3, 1, 1, 0, 131, 75 , 87 , 0  , 0  , 0  ), // #505 {W:k, R:xmm|m64|mem, R:u8}
+    3641             :   ISIGNATURE(3, 1, 1, 0, 131, 140, 87 , 0  , 0  , 0  ), // #506 {W:k, R:xmm|m32|mem, R:u8}
+    3642             :   ISIGNATURE(1, 1, 1, 0, 92 , 0  , 0  , 0  , 0  , 0  ), // #507 {R:vm32y}
+    3643             :   ISIGNATURE(1, 1, 1, 0, 94 , 0  , 0  , 0  , 0  , 0  ), // #508 {R:vm32z}
+    3644             :   ISIGNATURE(1, 1, 1, 0, 97 , 0  , 0  , 0  , 0  , 0  ), // #509 {R:vm64z}
+    3645             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 80 , 87 , 0  , 0  ), // #510 {W:zmm, R:zmm, R:ymm|m256|mem, R:u8}
+    3646             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 87 , 0  , 0  ), // #511 {W:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3647             :   ISIGNATURE(3, 1, 1, 1, 73 , 73 , 228, 0  , 0  , 0  ), // #512 {R:xmm, R:xmm, R:<ds:[zdi]>}
+    3648             :   ISIGNATURE(2, 1, 1, 0, 173, 191, 0  , 0  , 0  , 0  ), // #513 {W:r32|r64, R:xmm|ymm}
+    3649             :   ISIGNATURE(6, 1, 1, 0, 83 , 86 , 86 , 86 , 86 , 117), // #514 {W:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3650             :   ISIGNATURE(2, 1, 1, 0, 185, 164, 0  , 0  , 0  , 0  ), // #515 {W:xmm|ymm|zmm, R:k}
+    3651             :   ISIGNATURE(2, 1, 1, 0, 185, 137, 0  , 0  , 0  , 0  ), // #516 {W:xmm|ymm|zmm, R:xmm|m64|mem|r64}
+    3652             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 226, 87 , 0  , 0  ), // #517 {W:xmm, R:xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3653             :   ISIGNATURE(2, 1, 1, 0, 131, 240, 0  , 0  , 0  , 0  ), // #518 {W:k, R:xmm|ymm|zmm}
+    3654             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 87 , 0  , 0  ), // #519 {W:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3655             :   ISIGNATURE(1, 0, 1, 0, 187, 0  , 0  , 0  , 0  , 0  ), // #520 {R:r32|r64}
+    3656             :   ISIGNATURE(3, 1, 1, 3, 178, 103, 204, 0  , 0  , 0  ), // #521 {R:<edx>, R:<eax>, R:<ecx>}
+    3657             :   ISIGNATURE(1, 1, 1, 0, 241, 0  , 0  , 0  , 0  , 0  ), // #522 {R:rel16|rel32}
+    3658             :   ISIGNATURE(3, 1, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #523 {R:mem, R:<edx>, R:<eax>}
+    3659             :   ISIGNATURE(3, 0, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #524 {R:mem, R:<edx>, R:<eax>}
+    3660             :   ISIGNATURE(3, 1, 1, 2, 215, 178, 103, 0  , 0  , 0  ), // #525 {W:mem, R:<edx>, R:<eax>}
+    3661             :   ISIGNATURE(3, 0, 1, 2, 215, 178, 103, 0  , 0  , 0  )  // #526 {W:mem, R:<edx>, R:<eax>}
+    3662             : };
+    3663             : #undef ISIGNATURE
+    3664             : // ----------------------------------------------------------------------------
+    3665             : // ${signatureData:End}
+    3666             : #endif // !ASMJIT_DISABLE_VALIDATION
+    3667             : 
+    3668             : // ============================================================================
+    3669             : // [asmjit::X86Inst - MiscData]
+    3670             : // ============================================================================
+    3671             : 
+    3672             : #define CC_TO_INST(inst) {               \
+    3673             :   inst##o, inst##no, inst##b , inst##ae, \
+    3674             :   inst##e, inst##ne, inst##be, inst##a , \
+    3675             :   inst##s, inst##ns, inst##pe, inst##po, \
+    3676             :   inst##l, inst##ge, inst##le, inst##g   \
+    3677             : }
+    3678             : 
+    3679             : const X86Inst::MiscData X86InstDB::miscData = {
+    3680             :   CC_TO_INST(X86Inst::kIdJ),
+    3681             :   CC_TO_INST(X86Inst::kIdSet),
+    3682             :   CC_TO_INST(X86Inst::kIdCmov),
+    3683             : 
+    3684             :   // ReversedCond[]:
+    3685             :   {
+    3686             :     x86::kCondO, x86::kCondNO, x86::kCondA , x86::kCondBE, // O|NO|B |AE
+    3687             :     x86::kCondE, x86::kCondNE, x86::kCondAE, x86::kCondB , // E|NE|BE|A
+    3688             :     x86::kCondS, x86::kCondNS, x86::kCondPE, x86::kCondPO, // S|NS|PE|PO
+    3689             :     x86::kCondG, x86::kCondLE, x86::kCondGE, x86::kCondL   // L|GE|LE|G
+    3690             :   }
+    3691             : };
+    3692             : 
+    3693             : #undef CC_TO_INST
+    3694             : 
+    3695             : // ============================================================================
+    3696             : // [asmjit::X86Inst - Test]
+    3697             : // ============================================================================
+    3698             : 
+    3699             : #if defined(ASMJIT_TEST)
+    3700             : UNIT(x86_inst_bits) {
+    3701             :   INFO("Checking validity of X86Inst enums");
+    3702             : 
+    3703             :   // Cross-validate prefixes.
+    3704             :   EXPECT(X86Inst::kOptionRex  == 0x80000000U, "REX prefix must be at 0x80000000");
+    3705             :   EXPECT(X86Inst::kOptionVex3 == 0x00000400U, "VEX3 prefix must be at 0x00000400");
+    3706             :   EXPECT(X86Inst::kOptionEvex == 0x00001000U, "EVEX prefix must be at 0x00001000");
+    3707             : 
+    3708             :   // These could be combined together to form a valid REX prefix, they must match.
+    3709             :   EXPECT(int(X86Inst::kOptionOpCodeB) == int(X86Inst::kOpCode_B));
+    3710             :   EXPECT(int(X86Inst::kOptionOpCodeX) == int(X86Inst::kOpCode_X));
+    3711             :   EXPECT(int(X86Inst::kOptionOpCodeR) == int(X86Inst::kOpCode_R));
+    3712             :   EXPECT(int(X86Inst::kOptionOpCodeW) == int(X86Inst::kOpCode_W));
+    3713             : 
+    3714             :   uint32_t rex_rb = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3715             :                     (X86Inst::kOpCode_B >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3716             :   uint32_t rex_rw = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3717             :                     (X86Inst::kOpCode_W >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3718             :   EXPECT(rex_rb == 0x45, "kOpCode_R|B must form a valid REX prefix 0x45 if combined with 0x40");
+    3719             :   EXPECT(rex_rw == 0x4C, "kOpCode_R|W must form a valid REX prefix 0x4C if combined with 0x40");
+    3720             : }
+    3721             : #endif // ASMJIT_TEST
+    3722             : 
+    3723             : #if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_TEXT)
+    3724             : UNIT(x86_inst_names) {
+    3725             :   // All known instructions should be matched.
+    3726             :   INFO("Matching all X86/X64 instructions");
+    3727             :   for (uint32_t a = 0; a < X86Inst::_kIdCount; a++) {
+    3728             :     uint32_t b = X86Inst::getIdByName(X86Inst::getInst(a).getName());
+    3729             :     EXPECT(a == b,
+    3730             :       "Should match existing instruction \"%s\" {id:%u} != \"%s\" {id:%u}",
+    3731             :         X86Inst::getInst(a).getName(), a,
+    3732             :         X86Inst::getInst(b).getName(), b);
+    3733             :   }
+    3734             : 
+    3735             :   // Everything else should return `Inst::kIdNone`.
+    3736             :   INFO("Trying to look-up instructions that don't exist");
+    3737             :   EXPECT(X86Inst::getIdByName(nullptr)  == Inst::kIdNone, "Should return Inst::kIdNone for null input");
+    3738             :   EXPECT(X86Inst::getIdByName("")       == Inst::kIdNone, "Should return Inst::kIdNone for empty string");
+    3739             :   EXPECT(X86Inst::getIdByName("_")      == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3740             :   EXPECT(X86Inst::getIdByName("123xyz") == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3741             : }
+    3742             : #endif // ASMJIT_TEST && !ASMJIT_DISABLE_TEXT
+    3743             : 
+    3744             : } // asmjit namespace
+    3745             : } // namespace PLMD
+    3746             : 
+    3747             : // [Api-End]
+    3748             : #include "./asmjit_apiend.h"
+    3749             : 
+    3750             : // [Guard]
+    3751             : #endif // ASMJIT_BUILD_X86
+    3752             : #pragma GCC diagnostic pop
+    3753             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func-sort-c.html b/coverage-libs/asmjit/x86inst.h.func-sort-c.html new file mode 100644 index 0000000000..98219c210b --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func.html b/coverage-libs/asmjit/x86inst.h.func.html new file mode 100644 index 0000000000..04bb292c51 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.gcov.html b/coverage-libs/asmjit/x86inst.h.gcov.html new file mode 100644 index 0000000000..1015dfea09 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.gcov.html @@ -0,0 +1,2623 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86InstImpl13checkFeaturesEjRKNS0_4Inst6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit11X86InstImpl8validateEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL18x86GetRegTypesMaskEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.func.html b/coverage-libs/asmjit/x86instimpl.cpp.func.html new file mode 100644 index 0000000000..dad06fb470 --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:16Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86InstImpl13checkFeaturesEjRKNS0_4Inst6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit11X86InstImpl8validateEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL18x86GetRegTypesMaskEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.gcov.html b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html new file mode 100644 index 0000000000..02ffa7edfc --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html @@ -0,0 +1,833 @@ + + + + + + + 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-05-27 13:05:16Functions:030.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3596
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3596
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.func.html b/coverage-libs/asmjit/x86internal.cpp.func.html new file mode 100644 index 0000000000..ec7b59afc6 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:16Functions:61442.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3596
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3596
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.gcov.html b/coverage-libs/asmjit/x86internal.cpp.gcov.html new file mode 100644 index 0000000000..56ad2cd69a --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.gcov.html @@ -0,0 +1,1458 @@ + + + + + + + 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-05-27 13:05:16Functions:61442.9 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit10X86Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit10X86Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL23x86GetAddressSizeStringEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmBitsERNS0_13StringBuilderEjPKNS0_7ImmBitsEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmShufERNS0_13StringBuilderEjjj0
_ZN4PLMD6asmjitL24X86Logging_formatImmTextERNS0_13StringBuilderEjjjPKcj0
_ZN4PLMD6asmjitL28X86Logging_formatImmExtendedERNS0_13StringBuilderEjjjRKNS0_3ImmE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.func.html b/coverage-libs/asmjit/x86logging.cpp.func.html new file mode 100644 index 0000000000..a5d3cfcf4e --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:16Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit10X86Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit10X86Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL23x86GetAddressSizeStringEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmBitsERNS0_13StringBuilderEjPKNS0_7ImmBitsEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmShufERNS0_13StringBuilderEjjj0
_ZN4PLMD6asmjitL24X86Logging_formatImmTextERNS0_13StringBuilderEjjjPKcj0
_ZN4PLMD6asmjitL28X86Logging_formatImmExtendedERNS0_13StringBuilderEjjjRKNS0_3ImmE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.gcov.html b/coverage-libs/asmjit/x86logging.cpp.gcov.html new file mode 100644 index 0000000000..89705b3afc --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.gcov.html @@ -0,0 +1,786 @@ + + + + + + + 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-05-27 13:05:16Functions:080.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.func.html b/coverage-libs/asmjit/x86misc.h.func.html new file mode 100644 index 0000000000..b9bd5cd33d --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.gcov.html b/coverage-libs/asmjit/x86misc.h.gcov.html new file mode 100644 index 0000000000..e53ef7c09e --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.gcov.html @@ -0,0 +1,493 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.func.html b/coverage-libs/asmjit/x86operand.h.func.html new file mode 100644 index 0000000000..49730b81e8 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.gcov.html b/coverage-libs/asmjit/x86operand.h.gcov.html new file mode 100644 index 0000000000..82f6e7247f --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.gcov.html @@ -0,0 +1,1209 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE248
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE420
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1648
_ZN4PLMD6asmjit9X86RAPass5fetchEv1948
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit9X86RAPass9translateEv1948
_ZN4PLMD6asmjit9X86RAPassC2Ev1948
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1948
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32806
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE35054
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func.html b/coverage-libs/asmjit/x86regalloc.cpp.func.html new file mode 100644 index 0000000000..351ad059e5 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func.html @@ -0,0 +1,188 @@ + + + + + + + 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-05-27 13:05:16Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE35054
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1648
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE420
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass5fetchEv1948
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPass9translateEv1948
_ZN4PLMD6asmjit9X86RAPassC2Ev1948
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1948
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32806
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE248
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.gcov.html b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html new file mode 100644 index 0000000000..309529fde2 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html @@ -0,0 +1,4164 @@ + + + + + + + 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-05-27 13:05:16Functions:172958.6 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.func.html b/coverage-libs/asmjit/x86regalloc_p.h.func.html new file mode 100644 index 0000000000..1ee6699c9e --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.gcov.html b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html new file mode 100644 index 0000000000..fc30505416 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html @@ -0,0 +1,810 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm0
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE3896
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3896
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3896
_ZN4PLMD6asmjit4Zone6_allocEm7796
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9740
_ZN4PLMD6asmjit4ZoneC2Ejj11688
_ZN4PLMD6asmjit4ZoneD2Ev11688
_ZN4PLMD6asmjit4Zone5resetEb17532
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit4Zone11allocZeroedEm27684
_ZN4PLMD6asmjit4Zone3dupEPKvmb36702
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79986
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func.html b/coverage-libs/asmjit/zone.cpp.func.html new file mode 100644 index 0000000000..fc27623536 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func.html @@ -0,0 +1,160 @@ + + + + + + + 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-05-27 13:05:16Functions:132259.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE3896
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3896
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit4Zone11allocZeroedEm27684
_ZN4PLMD6asmjit4Zone3dupEPKvmb36702
_ZN4PLMD6asmjit4Zone5resetEb17532
_ZN4PLMD6asmjit4Zone6_allocEm7796
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit4ZoneC2Ejj11688
_ZN4PLMD6asmjit4ZoneD2Ev11688
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3896
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm0
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9740
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79986
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.gcov.html b/coverage-libs/asmjit/zone.cpp.gcov.html new file mode 100644 index 0000000000..cd7024d6ce --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.gcov.html @@ -0,0 +1,935 @@ + + + + + + + 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-05-27 13:05:16Functions:132259.1 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1948
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func.html b/coverage-libs/asmjit/zone.h.func.html new file mode 100644 index 0000000000..64f6b6d45a --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:16Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1948
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.gcov.html b/coverage-libs/asmjit/zone.h.gcov.html new file mode 100644 index 0000000000..20a333ac9b --- /dev/null +++ b/coverage-libs/asmjit/zone.h.gcov.html @@ -0,0 +1,1233 @@ + + + + + + + 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-05-27 13:05:16Functions:22100.0 %
+
+ + + + + + + + +

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index-sort-l.html b/coverage-libs/blas/index-sort-l.html new file mode 100644 index 0000000000..6962d9aac2 --- /dev/null +++ b/coverage-libs/blas/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + 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-05-27 13:05:16Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index.html b/coverage-libs/blas/index.html new file mode 100644 index 0000000000..32d6bbc99a --- /dev/null +++ b/coverage-libs/blas/index.html @@ -0,0 +1,93 @@ + + + + + + + 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-05-27 13:05:16Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

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

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

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

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
asmjit +
31.4%31.4%
+
31.4 %2235 / 712439.5 %139 / 352
blas +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
lapack +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
lepton +
89.0%89.0%
+
89.0 %1593 / 178992.3 %395 / 428
molfile +
40.9%40.9%
+
40.9 %861 / 210445.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-f.html b/coverage-libs/lapack/index-sort-f.html new file mode 100644 index 0000000000..c5fd6788c0 --- /dev/null +++ b/coverage-libs/lapack/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + 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-05-27 13:05:16Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-l.html b/coverage-libs/lapack/index-sort-l.html new file mode 100644 index 0000000000..360bf4b86e --- /dev/null +++ b/coverage-libs/lapack/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + 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-05-27 13:05:16Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index.html b/coverage-libs/lapack/index.html new file mode 100644 index 0000000000..218ef8ce93 --- /dev/null +++ b/coverage-libs/lapack/index.html @@ -0,0 +1,93 @@ + + + + + + + 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-05-27 13:05:16Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func-sort-c.html b/coverage-libs/lapack/lapack.cpp.func-sort-c.html new file mode 100644 index 0000000000..3759ab5138 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func-sort-c.html @@ -0,0 +1,796 @@ + + + + + + + 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-05-27 13:05:16Functions: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_557317
_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_608139
_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_12568762
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568766
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_13125548
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func.html b/coverage-libs/lapack/lapack.cpp.func.html new file mode 100644 index 0000000000..af4da02bc5 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func.html @@ -0,0 +1,796 @@ + + + + + + + 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-05-27 13:05:16Functions: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_13125548
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_12568762
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568766
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_557317
_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_608139
_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.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.gcov.html b/coverage-libs/lapack/lapack.cpp.gcov.html new file mode 100644 index 0000000000..6c67049f89 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.gcov.html @@ -0,0 +1,31099 @@ + + + + + + + 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-05-27 13:05:16Functions: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      608139 : 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      608139 :     --work;
+    3894             :     --isuppz;
+    3895      608139 :     --z__;
+    3896      608139 :     --gersch;
+    3897      608139 :     --lld;
+    3898      608139 :     --ld;
+    3899      608139 :     --l;
+    3900      608139 :     --d__;
+    3901             : 
+    3902             :     /* Function Body */
+    3903             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3904      608139 :     if (*r__ == 0) {
+    3905             : 
+    3906      606866 :         r1 = *b1;
+    3907      606866 :         r2 = *bn;
+    3908             :         i__1 = *bn;
+    3909     1399107 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+    3910     1399107 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3911             :                 r1 = i__;
+    3912      606866 :                 goto L20;
+    3913             :             }
+    3914             :         }
+    3915           0 :         goto L40;
+    3916             : L20:
+    3917             :         i__1 = *b1;
+    3918     1557137 :         for (i__ = *bn; i__ >= i__1; --i__) {
+    3919     1557137 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3920             :                 r2 = i__;
+    3921      606866 :                 goto L40;
+    3922             :             }
+    3923             :         }
+    3924             :     } else {
+    3925             :         r1 = *r__;
+    3926             :         r2 = *r__;
+    3927             :     }
+    3928             : 
+    3929      608139 : L40:
+    3930      608139 :     indumn = *n;
+    3931      608139 :     inds = (*n << 1) + 1;
+    3932      608139 :     indp = *n * 3 + 1;
+    3933             :     sawnan = 0;
+    3934             : 
+    3935      608139 :     if (*b1 == 1) {
+    3936      608139 :         work[inds] = 0.;
+    3937             :     } else {
+    3938           0 :         work[inds] = lld[*b1 - 1];
+    3939             :     }
+    3940      608139 :     s = work[inds] - *sigma;
+    3941             :     i__1 = r2 - 1;
+    3942     1842521 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+    3943     1234382 :         dplus = d__[i__] + s;
+    3944     1234382 :         work[i__] = ld[i__] / dplus;
+    3945     1234382 :         work[inds + i__] = s * work[i__] * l[i__];
+    3946     1234382 :         s = work[inds + i__] - *sigma;
+    3947             :     }
+    3948             : 
+    3949      608139 :     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      608139 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+    3974             :     i__1 = r1;
+    3975     2110778 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+    3976     1502639 :         dminus = lld[i__] + work[indp + i__];
+    3977     1502639 :         tmp = d__[i__] / dminus;
+    3978     1502639 :         work[indumn + i__] = l[i__] * tmp;
+    3979     1502639 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+    3980             :     }
+    3981      608139 :     tmp = work[indp + r1 - 1];
+    3982      608139 :     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      608139 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+    4006      608139 :     if (std::abs(*mingma)<PLUMED_GMX_DOUBLE_MIN) {
+    4007       45757 :         *mingma = eps * work[inds + r1 - 1];
+    4008             :     }
+    4009      608139 :     *r__ = r1;
+    4010             :     i__1 = r2 - 1;
+    4011      956212 :     for (i__ = r1; i__ <= i__1; ++i__) {
+    4012      348073 :         tmp = work[inds + i__] + work[indp + i__];
+    4013      348073 :         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4014       23351 :             tmp = eps * work[inds + i__];
+    4015             :         }
+    4016      348073 :         if (std::abs(tmp) < std::abs(*mingma)) {
+    4017       50702 :             *mingma = tmp;
+    4018       50702 :             *r__ = i__ + 1;
+    4019             :         }
+    4020             :     }
+    4021             : 
+    4022      608139 :     isuppz[1] = *b1;
+    4023      608139 :     isuppz[2] = *bn;
+    4024      608139 :     z__[*r__] = 1.;
+    4025      608139 :     *ztz = 1.;
+    4026      608139 :     if (! sawnan) {
+    4027      608139 :         from = *r__ - 1;
+    4028      608139 :         i__1 = *r__ - 32;
+    4029      608139 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+    4030             : L120:
+    4031     1148734 :         if (from >= *b1) {
+    4032             :             i__1 = to;
+    4033     1355280 :             for (i__ = from; i__ >= i__1; --i__) {
+    4034      813473 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4035      813473 :                 *ztz += z__[i__] * z__[i__];
+    4036             :             }
+    4037      541807 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+    4038        1212 :                 isuppz[1] = to + 2;
+    4039             :             } else {
+    4040      540595 :                 from = to - 1;
+    4041      540595 :                 i__1 = to - 32;
+    4042      540595 :                 to = (i__1>*b1) ? i__1 : *b1;
+    4043      540595 :                 goto L120;
+    4044             :             }
+    4045             :         }
+    4046      608139 :         from = *r__ + 1;
+    4047      608139 :         i__1 = *r__ + 32;
+    4048      608139 :         to = (i__1<*bn) ? i__1 : *bn;
+    4049             : L140:
+    4050     1192356 :         if (from <= *bn) {
+    4051             :             i__1 = to;
+    4052     2016537 :             for (i__ = from; i__ <= i__1; ++i__) {
+    4053     1432314 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+    4054     1432314 :                 *ztz += z__[i__] * z__[i__];
+    4055             :             }
+    4056      584223 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+    4057           6 :                 isuppz[2] = to - 2;
+    4058             :             } else {
+    4059      584217 :                 from = to + 1;
+    4060      584217 :                 i__1 = to + 32;
+    4061      584217 :                 to = (i__1<*bn) ? i__1 : *bn;
+    4062      584217 :                 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      608139 :     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      453492 :       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     5134164 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    4893     4564084 :         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     2677334 :                 for (j = 1; j <= i__1; ++j) {
+    4924     2106298 :                     dplus = d__[j] + s;
+    4925     2106298 :                     s = s * lld[j] / dplus - left;
+    4926     2106298 :                     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     2654334 :             for (j = 1; j <= i__1; ++j) {
+    4971     2083372 :                 dplus = d__[j] + s;
+    4972     2083372 :                 s = s * lld[j] / dplus - right;
+    4973     2083372 :                 if (dplus < 0.) {
+    4974     1882767 :                     ++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   114233046 :         for (j = 1; j <= i__2; ++j) {
+    5088    85492243 :             dplus = d__[j] + s;
+    5089    85492243 :             s = s * lld[j] / dplus - mid;
+    5090    85492243 :             if (dplus < 0.) {
+    5091    15245070 :                 ++cnt;
+    5092             :             }
+    5093             :         }
+    5094    28740803 :         dplus = d__[*n] + s;
+    5095    28740803 :         if (dplus < 0.) {
+    5096    12605338 :             ++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         667 :             isplit[*nsplit] = i__;
+    5256         667 :             ++(*nsplit);
+    5257             :         }
+    5258             :     }
+    5259      570008 :     isplit[*nsplit] = *n;
+    5260             : 
+    5261             :     ibegin = 1;
+    5262      570008 :     i__1 = *nsplit;
+    5263     1140683 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5264      570675 :         iend = isplit[jblk];
+    5265      570675 :         if (ibegin == iend) {
+    5266         665 :             ++(*m);
+    5267         665 :             w[*m] = d__[ibegin];
+    5268         665 :             iblock[*m] = jblk;
+    5269         665 :             indexw[*m] = 1;
+    5270         665 :             e[iend] = 0.;
+    5271         665 :             ibegin = iend + 1;
+    5272         665 :             goto L170;
+    5273             :         }
+    5274      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     1683754 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5288     1113744 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+    5289     1113744 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+    5290             :             d__1 = gersch[(i__ << 1) - 1];
+    5291     1113744 :             gl = (d__1<gl) ? d__1 : gl;
+    5292     1113744 :             gersch[i__ * 2] = d__[i__] + offd;
+    5293             :             d__1 = gersch[i__ * 2];
+    5294     1113744 :             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     2253764 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5302     1683754 :             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     4507528 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5318     3367508 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+    5319     3367508 :                 if (tmp < 0.) {
+    5320     1585168 :                     ++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     2253764 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5349     1683754 :             work[(in << 1) + i__] = 1. / work[i__];
+    5350     1683754 :             tmp = e[j] * work[(in << 1) + i__];
+    5351     1683754 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+    5352     1683754 :             work[in + i__] = tmp;
+    5353     1683754 :             ++j;
+    5354             :         }
+    5355     2823774 :         for (i__ = in; i__ >= 1; --i__) {
+    5356     2253764 :             tmp = sgndef * work[i__];
+    5357     2253764 :         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     2253764 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5368     1683754 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+    5369     1683754 :             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     2253764 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5402     1683754 :             work[i__] = d__[j] + s;
+    5403     1683754 :             work[(in << 1) + i__] = 1. / work[i__];
+    5404     1683754 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+    5405     1683754 :             s = s * work[in + i__] * e[j] - tau;
+    5406     1683754 :             ++j;
+    5407             :         }
+    5408      570010 :         work[in] = d__[iend] + s;
+    5409             : 
+    5410     2823774 :         for (i__ = in; i__ >= 1; --i__) {
+    5411     2253764 :             tmp = sgndef * work[i__];
+    5412     2253764 :             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     2823774 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5426     2253764 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+    5427     2253764 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+    5428             :         }
+    5429             : 
+    5430             :         j = ibegin;
+    5431      570010 :         i__2 = in - 1;
+    5432     2253764 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5433     1683754 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+    5434     1683754 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+    5435     1683754 :             ++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     2426219 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5447     1935768 :                 ++(*m);
+    5448     1935768 :                 w[*m] = work[in - i__ + 1];
+    5449     1935768 :                 iblock[*m] = jblk;
+    5450     1935768 :                 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      570675 : 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         685 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5496         673 :                 iend = isplit[i__];
+    5497         673 :                 i__2 = iend;
+    5498        1451 :                 for (j = ibegin; j <= i__2; ++j) {
+    5499         778 :                     work[j] = w[j] + e[iend];
+    5500             :                 }
+    5501         673 :                 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         670 :                     if (iblock[i__] == itmp) {
+    5534          12 :                         till = *m;
+    5535             :                     } else {
+    5536         658 :                         till = i__ - 1;
+    5537             :                     }
+    5538         670 :                     i__2 = till - j + 1;
+    5539         670 :                     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", &i__2, &w[j], &iinfo);
+    5540         670 :                     cnt = cnt - ibegin + 1;
+    5541         670 :                     i__2 = till;
+    5542        1439 :                     for (k = j; k <= i__2; ++k) {
+    5543         769 :                         indexw[k] = cnt + k - j;
+    5544             :                     }
+    5545             :                     j = i__;
+    5546         670 :                     itmp = iblock[j];
+    5547         670 :                     cnt = iwork[*n + iwork[j]];
+    5548         670 :                     ibegin = isplit[itmp - 1] + 1;
+    5549         670 :                     if (i__ == *m && till < *m) {
+    5550           0 :                         indexw[*m] = cnt - ibegin + 1;
+    5551             :                     }
+    5552             :                 } else {
+    5553          99 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+    5554          99 :                     cnt = (i__2<i__3) ? i__2 : i__3;
+    5555             :                 }
+    5556             :             }
+    5557             :         }
+    5558             :     }
+    5559             : 
+    5560             :     return;
+    5561             : 
+    5562             : }
+    5563             : 
+    5564             : 
+    5565             : }
+    5566             : }
+    5567             : #include <cmath>
+    5568             : 
+    5569             : #include "real.h"
+    5570             : 
+    5571             : #include "blas/blas.h"
+    5572             : #include "lapack.h"
+    5573             : #include "lapack_limits.h"
+    5574             : 
+    5575             : 
+    5576             : #include "blas/blas.h"
+    5577             : namespace PLMD{
+    5578             : namespace lapack{
+    5579             : using namespace blas;
+    5580             : void
+    5581          70 : PLUMED_BLAS_F77_FUNC(dlarrfx,DLARRFX)(int *n, 
+    5582             :         double *d__, 
+    5583             :         double *l, 
+    5584             :         double *ld, 
+    5585             :         double *lld, 
+    5586             :         int *ifirst, 
+    5587             :         int *ilast, 
+    5588             :         double *w, 
+    5589             :         double *sigma, 
+    5590             :         double *dplus, 
+    5591             :         double *lplus, 
+    5592             :         double *work,
+    5593             :         int *info)
+    5594             : {
+    5595          70 :     int i1 = 1;
+    5596             :     int i__1;
+    5597             :     double d__2, d__3;
+    5598             : 
+    5599             :     int i__;
+    5600             :     double s, eps, tmp, dmax1, dmax2, delta;
+    5601          70 :     --work;
+    5602          70 :     --lplus;
+    5603          70 :     --dplus;
+    5604          70 :     --w;
+    5605             :     --lld;
+    5606          70 :     --ld;
+    5607          70 :     --l;
+    5608          70 :     --d__;
+    5609          70 :     *info = 0;
+    5610             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5611          70 :     *sigma = w[*ifirst];
+    5612             :     delta = eps * 2.;
+    5613             : 
+    5614          70 : L10:
+    5615          70 :     s = -(*sigma);
+    5616          70 :     dplus[1] = d__[1] + s;
+    5617             :     dmax1 = std::abs(dplus[1]);
+    5618          70 :     i__1 = *n - 1;
+    5619       28278 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5620       28208 :         lplus[i__] = ld[i__] / dplus[i__];
+    5621       28208 :         s = s * lplus[i__] * l[i__] - *sigma;
+    5622       28208 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+    5623             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+    5624       28208 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+    5625             :     }
+    5626          70 :     if (std::isnan(dmax1)) {
+    5627           0 :         *sigma -= std::abs(*sigma) * delta;
+    5628           0 :         delta *= 2.;
+    5629           0 :         goto L10;
+    5630             :     }
+    5631             : 
+    5632          70 :     tmp = w[*ilast];
+    5633             :     delta = eps * 2.;
+    5634          70 : L30:
+    5635          70 :     s = -tmp;
+    5636          70 :     work[1] = d__[1] + s;
+    5637             :     dmax2 = std::abs(work[1]);
+    5638          70 :     i__1 = *n - 1;
+    5639       28278 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5640       28208 :         work[*n + i__] = ld[i__] / work[i__];
+    5641       28208 :         s = s * work[*n + i__] * l[i__] - tmp;
+    5642       28208 :         work[i__ + 1] = d__[i__ + 1] + s;
+    5643             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+    5644       28208 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+    5645             :     }
+    5646          70 :     if (std::isnan(dmax2)) {
+    5647           0 :         tmp += std::abs(tmp) * delta;
+    5648           0 :         delta *= 2.;
+    5649           0 :         goto L30;
+    5650             :     }
+    5651          70 :     if (dmax2 < dmax1) {
+    5652          36 :         *sigma = tmp;
+    5653          36 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+    5654          36 :         i__1 = *n - 1;
+    5655          36 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+    5656             :     }
+    5657             : 
+    5658          70 :     return;
+    5659             : }
+    5660             : }
+    5661             : }
+    5662             : #include <cmath>
+    5663             : 
+    5664             : #include "real.h"
+    5665             : 
+    5666             : #include "blas/blas.h"
+    5667             : #include "lapack.h"
+    5668             : #include "lapack_limits.h"
+    5669             : 
+    5670             : 
+    5671             : #include "blas/blas.h"
+    5672             : namespace PLMD{
+    5673             : namespace lapack{
+    5674             : using namespace blas;
+    5675             : void
+    5676      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     1140592 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5769      570628 :         iend = isplit[jblk];
+    5770             : 
+    5771      570628 :         wend = wbegin - 1;
+    5772     1178159 : L171:
+    5773     1178159 :         if (wend < *m) {
+    5774      608195 :             if (iblock[wend + 1] == jblk) {
+    5775      607531 :                 ++wend;
+    5776      607531 :                 goto L171;
+    5777             :             }
+    5778             :         }
+    5779      570628 :         if (wend < wbegin) {
+    5780           0 :             ibegin = iend + 1;
+    5781           0 :             continue;
+    5782             :         }
+    5783             : 
+    5784      570628 :         if (ibegin == iend) {
+    5785         665 :             z__[ibegin + wbegin * z_dim1] = 1.;
+    5786         665 :             isuppz[(wbegin << 1) - 1] = ibegin;
+    5787         665 :             isuppz[wbegin * 2] = ibegin;
+    5788         665 :             ibegin = iend + 1;
+    5789         665 :             wbegin = wend + 1;
+    5790         665 :             continue;
+    5791             :         }
+    5792      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      606866 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5800       36903 :             work[inderr + i__] = eps * std::abs(work[i__]);
+    5801       36903 :             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     2281903 :                 for (j = 1; j <= i__3; ++j) {
+    5845     1711870 :                     tmp = d__[k] * l[k];
+    5846     1711870 :                     work[indld + j] = tmp;
+    5847     1711870 :                     work[indlld + j] = tmp * l[k];
+    5848     1711870 :                     ++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     1177835 :                 for (j = oldfst; j <= i__3; ++j) {
+    5864      607802 :                     if (j == oldlst || work[indgap + j] >= 
+    5865       37769 :                         reltol * std::abs(work[j])) {
+    5866      606936 :                         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      606936 :                     newsiz = newlst - newfrs + 1;
+    5878      606936 :                     newftt = wbegin + newfrs - 1;
+    5879      606936 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+    5880      606936 :                     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     1213732 :                         for (k = newfrs; k <= i__4; ++k) {
+    5935             :                             iter = 0;
+    5936      608139 : L90:
+    5937      608139 :                             lambda = work[k];
+    5938             : 
+    5939      608139 :                             PLUMED_BLAS_F77_FUNC(dlar1vx,DLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+    5940      608139 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+    5941      608139 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+    5942      608139 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+    5943      608139 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+    5944      608139 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+    5945      608139 :                             tmp = 1. / ztz;
+    5946      608139 :                             nrminv =  std::sqrt(tmp);
+    5947      608139 :                             resid = std::abs(mingma) * nrminv;
+    5948      608139 :                             rqcorr = mingma * tmp;
+    5949      608139 :                             if (k == in) {
+    5950       21047 :                                 gap = work[indgap + k - 1];
+    5951      587092 :                             } else if (k == 1) {
+    5952      570469 :                                 gap = work[indgap + k];
+    5953             :                             } else {
+    5954       16623 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+    5955       16623 :                                         indgap + k];
+    5956       16623 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+    5957             :                             }
+    5958      608139 :                             ++iter;
+    5959      608139 :                             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      606866 :                             iwork[ktot] = 1;
+    5967      606866 :                             if (newsiz == 1) {
+    5968      606866 :                                 ++ndone;
+    5969             :                             }
+    5970      606866 :                             zfrom = isuppz[(ktot << 1) - 1];
+    5971      606866 :                             zto = isuppz[ktot * 2];
+    5972      606866 :                             i__5 = zto - zfrom + 1;
+    5973      606866 :                             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+    5974      606866 :                                     ktot * z_dim1], &c__1);
+    5975      606866 :                             ++ktot;
+    5976             :                         }
+    5977      606866 :                         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      606936 :                     newfrs = j + 1;
+    6010             :                 }
+    6011             :             }
+    6012      569970 :             ++ndepth;
+    6013      569970 :             goto L40;
+    6014             :         }
+    6015      569963 :         j = wbegin << 1;
+    6016             :         i__2 = wend;
+    6017     1176829 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+    6018      606866 :             isuppz[j - 1] += oldien;
+    6019      606866 :             isuppz[j] += oldien;
+    6020      606866 :             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     2227038 :     for (k = 1; k <= i__1; k += 2) {
+    9323     1670391 :         if (z__[k] < 0.) {
+    9324           0 :             *info = -(k + 200);
+    9325           0 :             return;
+    9326     1670391 :         } else if (z__[k + 1] < 0.) {
+    9327           0 :             *info = -(k + 201);
+    9328           0 :             return;
+    9329             :         }
+    9330     1670391 :         d__ += z__[k];
+    9331     1670391 :         e += z__[k + 1];
+    9332     1670391 :         d__1 = qmax, d__2 = z__[k];
+    9333     1670391 :         qmax = (d__1>d__2) ? d__1 : d__2;
+    9334             :         d__1 = emin, d__2 = z__[k + 1];
+    9335     1670391 :         emin = (d__1<d__2) ? d__1 : d__2;
+    9336     1670391 :         d__1 = (qmax>zmax) ? qmax : zmax;
+    9337             :         d__2 = z__[k + 1];
+    9338     1670391 :         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     2783685 :     for (k = *n << 1; k >= 2; k += -2) {
+    9392     2227038 :         z__[k * 2] = 0.;
+    9393     2227038 :         z__[(k << 1) - 1] = z__[k];
+    9394     2227038 :         z__[(k << 1) - 2] = 0.;
+    9395     2227038 :         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     4454076 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+    9421     3340782 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9422           4 :                 z__[i4 - 1] = -0.;
+    9423           4 :                 d__ = z__[i4 - 3];
+    9424             :             } else {
+    9425     3340778 :                 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     4454076 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+    9433     3340782 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+    9434     3340782 :             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     3340759 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+    9440     3340759 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+    9441     3340755 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+    9442     3340755 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+    9443     3340755 :                 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     3340782 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+    9450     3340782 :             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     4454076 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+    9458     3340782 :             d__1 = qmax, d__2 = z__[i4];
+    9459     4475369 :             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     1113433 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+    9471     1113433 :         if (n0 < 1) {
+    9472      556647 :             goto L170;
+    9473             :         }
+    9474             : 
+    9475      556786 :         desig = 0.;
+    9476      556786 :         if (n0 == *n) {
+    9477      556647 :             sigma = 0.;
+    9478             :         } else {
+    9479         139 :             sigma = -z__[(n0 << 2) - 1];
+    9480             :         }
+    9481      556786 :         if (sigma < 0.) {
+    9482           0 :             *info = 1;
+    9483           0 :             return;
+    9484             :         }
+    9485             : 
+    9486             :         emax = 0.;
+    9487      556786 :         if (n0 > i0) {
+    9488      556647 :             emin = std::abs(z__[(n0 << 2) - 5]);
+    9489             :         } else {
+    9490             :             emin = 0.;
+    9491             :         }
+    9492      556786 :         qmin = z__[(n0 << 2) - 3];
+    9493      556786 :         qmax = qmin;
+    9494     2232257 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+    9495     1675584 :             if (z__[i4 - 5] <= 0.) {
+    9496         113 :                 goto L100;
+    9497             :             }
+    9498     1675471 :             if (qmin >= emax * 4.) {
+    9499     1116327 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+    9500     1116327 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+    9501             :                 d__1 = emax, d__2 = z__[i4 - 5];
+    9502     1116327 :                 emax = (d__1>d__2) ? d__1 : d__2;
+    9503             :             }
+    9504     1675471 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+    9505     1675471 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9506             :             d__1 = emin, d__2 = z__[i4 - 5];
+    9507     1675471 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9508             :         }
+    9509             :         i4 = 4;
+    9510             : 
+    9511      556786 : L100:
+    9512      556786 :         i0 = i4 / 4;
+    9513      556786 :         pp = 0;
+    9514             : 
+    9515      556786 :         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     2788949 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+    9521     2232207 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+    9522     2232207 :                 if (dee <= deemin) {
+    9523             :                     deemin = dee;
+    9524     1206053 :                     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      556786 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+    9551      556786 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+    9552             : 
+    9553      556786 :         nbig = (n0 - i0 + 1) * 30;
+    9554             :         i__2 = nbig;
+    9555    13682334 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+    9556    13682334 :             if (i0 > n0) {
+    9557      556786 :                 goto L150;
+    9558             :             }
+    9559             : 
+    9560    13125548 :             PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+    9561             :                     nfail, &iter, &ndiv, &ieee);
+    9562             : 
+    9563    13125548 :             pp = 1 - pp;
+    9564             : 
+    9565    13125548 :             if (pp == 0 && n0 - i0 >= 3) {
+    9566      162508 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+    9567             :                          sigma) {
+    9568         301 :                     splt = i0 - 1;
+    9569         301 :                     qmax = z__[(i0 << 2) - 3];
+    9570         301 :                     emin = z__[(i0 << 2) - 1];
+    9571         301 :                     oldemn = z__[i0 * 4];
+    9572         301 :                     i__3 = 4*(n0 - 3);
+    9573       41906 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+    9574       41605 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+    9575       41576 :                                 tol2 * sigma) {
+    9576         116 :                             z__[i4 - 1] = -sigma;
+    9577         116 :                             splt = i4 / 4;
+    9578         116 :                             qmax = 0.;
+    9579         116 :                             emin = z__[i4 + 3];
+    9580         116 :                             oldemn = z__[i4 + 4];
+    9581             :                         } else {
+    9582       41489 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+    9583       41489 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+    9584             :                             d__1 = emin, d__2 = z__[i4 - 1];
+    9585       41489 :                             emin = (d__1<d__2) ? d__1 : d__2;
+    9586             :                             d__1 = oldemn, d__2 = z__[i4];
+    9587       41489 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+    9588             :                         }
+    9589             :                     }
+    9590         301 :                     z__[(n0 << 2) - 1] = emin;
+    9591         301 :                     z__[n0 * 4] = oldemn;
+    9592         301 :                     i0 = splt + 1;
+    9593             :                 }
+    9594             :             }
+    9595             :         }
+    9596             : 
+    9597           0 :         *info = 2;
+    9598           0 :         return;
+    9599             : 
+    9600             : L150:
+    9601             :         ;
+    9602             :     }
+    9603             : 
+    9604           0 :     *info = 3;
+    9605           0 :     return;
+    9606             : 
+    9607             : 
+    9608             : L170:
+    9609             : 
+    9610      556647 :     i__1 = *n;
+    9611     2227038 :     for (k = 2; k <= i__1; ++k) {
+    9612     1670391 :         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     2783685 :     for (k = *n; k >= 1; --k) {
+    9619     2227038 :         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    13125548 : 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    13125548 :     int ttype = 0;
+    9664    13125548 :     double dmin1 = 0.;
+    9665    13125548 :     double dmin2 = 0.;
+    9666    13125548 :     double dn = 0.;
+    9667    13125548 :     double dn1 = 0.;
+    9668    13125548 :     double dn2 = 0.;
+    9669    13125548 :     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    13125548 :     --z__;
+    9679             : 
+    9680    13125548 :     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     1670177 : L10:
+    9688             : 
+    9689    14795725 :     if (*n0 < *i0) {
+    9690             :         return;
+    9691             :     }
+    9692    14238939 :     if (*n0 == *i0) {
+    9693          82 :         goto L20;
+    9694             :     }
+    9695    14238857 :     nn = (*n0 << 2) + *pp;
+    9696    14238857 :     if (*n0 == *i0 + 1) {
+    9697      556704 :         goto L40;
+    9698             :     }
+    9699             : 
+    9700    13682153 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+    9701    12568919 :             4] > tol2 * z__[nn - 7]) {
+    9702    12568919 :         goto L30;
+    9703             :     }
+    9704             : 
+    9705     1113234 : L20:
+    9706             : 
+    9707     1113316 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+    9708     1113316 :     --(*n0);
+    9709     1113316 :     goto L10;
+    9710             : 
+    9711             : L30:
+    9712             : 
+    9713    12568919 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+    9714    12568762 :             nn - 11]) {
+    9715    12568762 :         goto L50;
+    9716             :     }
+    9717             : 
+    9718         157 : 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      539402 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9730             :         } else {
+    9731       17459 :             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    12568762 :     if (*pp == 2) {
+    9744        7987 :         *pp = 0;
+    9745             :     }
+    9746             : 
+    9747    12568762 :     if (*dmin__ <= 0. || *n0 < n0in) {
+    9748     1113380 :         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    12568762 :     PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9788             :             dn2, &tau, &ttype);
+    9789             : 
+    9790    12568766 : L70:
+    9791             : 
+    9792    12568766 :     PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9793             :             dn2, ieee);
+    9794             : 
+    9795    12568766 :     *ndiv += *n0 - *i0 + 2;
+    9796    12568766 :     ++(*iter);
+    9797             : 
+    9798    12568766 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+    9799             : 
+    9800    12568762 :         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    12568762 : L90:
+    9837    12568762 :     if (tau < *sigma) {
+    9838    10899823 :         *desig += tau;
+    9839    10899823 :         t = *sigma + *desig;
+    9840    10899823 :         *desig -= t - *sigma;
+    9841             :     } else {
+    9842     1668939 :         t = *sigma + tau;
+    9843     1668939 :         *desig = *sigma - (t - tau) + *desig;
+    9844             :     }
+    9845    12568762 :     *sigma = t;
+    9846             : 
+    9847    12568762 :     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    12568762 : 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    12568762 :     if (*dmin__ <= 0.) {
+    9885      848266 :         *tau = -(*dmin__);
+    9886      848266 :         *ttype = -1;
+    9887      848266 :         return;
+    9888             :     }
+    9889             : 
+    9890             :     s = 0.0;
+    9891             : 
+    9892    11720496 :     nn = (*n0 << 2) + *pp;
+    9893    11720496 :     if (*n0in == *n0) {
+    9894             : 
+    9895    11455382 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) ||
+    9896    11455382 :          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    11455382 :         } 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    11455382 :             if (*ttype == -6) {
+   10023             :                 g += (1. - g) * .333;
+   10024    11455382 :             } else if (*ttype == -18) {
+   10025             :                 g = .083250000000000005;
+   10026             :             } else {
+   10027             :                 g = .25;
+   10028             :             }
+   10029    11455382 :             s = g * *dmin__;
+   10030    11455382 :             *ttype = -6;
+   10031             :         }
+   10032             : 
+   10033      265114 :     } else if (*n0in == *n0 + 1) {
+   10034             : 
+   10035      265005 :         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      265005 :             s = *dmin1 * .25;
+   10076      265005 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+   10077           0 :                 s = *dmin1 * .5;
+   10078             :             }
+   10079      265005 :             *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    11720496 :     *tau = s;
+   10131    11720496 :     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    12568766 : 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    12568766 :     --z__;
+   10167             : 
+   10168    12568766 :     if (*n0 - *i0 - 1 <= 0) {
+   10169             :         return;
+   10170             :     }
+   10171             : 
+   10172    12568766 :     j4 = (*i0 << 2) + *pp - 3;
+   10173    12568766 :     emin = z__[j4 + 4];
+   10174    12568766 :     d__ = z__[j4] - *tau;
+   10175    12568766 :     *dmin__ = d__;
+   10176    12568766 :     *dmin1 = -z__[j4];
+   10177             : 
+   10178    12568766 :     if (*ieee) {
+   10179             : 
+   10180    12568766 :         if (*pp == 0) {
+   10181     6430794 :             i__1 = 4*(*n0 - 3);
+   10182     7707680 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10183     1276886 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10184     1276886 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10185     1276886 :                 d__ = d__ * temp - *tau;
+   10186     1276886 :                 if(d__<*dmin__)
+   10187      328487 :                   *dmin__ = d__;
+   10188     1276886 :                 z__[j4] = z__[j4 - 1] * temp;
+   10189             :                 d__1 = z__[j4];
+   10190     1276886 :                 if(d__1<emin)
+   10191             :                   emin = d__1;
+   10192             :             }
+   10193             :         } else {
+   10194     6137972 :             i__1 = 4*(*n0 - 3);
+   10195     7015854 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10196      877882 :                 z__[j4 - 3] = d__ + z__[j4];
+   10197      877882 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10198      877882 :                 d__ = d__ * temp - *tau;
+   10199      877882 :                 if(d__<*dmin__)
+   10200      239959 :                   *dmin__ = d__;
+   10201      877882 :                 z__[j4 - 1] = z__[j4] * temp;
+   10202             :                 d__1 = z__[j4 - 1];
+   10203      877882 :                 if(d__1<emin)
+   10204             :                   emin = d__1;
+   10205             :             }
+   10206             :         }
+   10207             : 
+   10208    12568766 :         *dnm2 = d__;
+   10209    12568766 :         *dmin2 = *dmin__;
+   10210    12568766 :         j4 = 4*(*n0 - 2) - *pp;
+   10211    12568766 :         j4p2 = j4 + (*pp << 1) - 1;
+   10212    12568766 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10213    12568766 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10214    12568766 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10215    12568766 :         if(*dnm1<*dmin__)
+   10216     9958646 :           *dmin__ = *dnm1;
+   10217             : 
+   10218    12568766 :         *dmin1 = *dmin__;
+   10219    12568766 :         j4 += 4;
+   10220    12568766 :         j4p2 = j4 + (*pp << 1) - 1;
+   10221    12568766 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10222    12568766 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10223    12568766 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10224    12568766 :         if(*dn<*dmin__)
+   10225    12019828 :           *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    12568766 :     z__[j4 + 2] = *dn;
+   10291    12568766 :     z__[(*n0 << 2) - *pp] = emin;
+   10292    12568766 :     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      557317 : 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      557317 :     --d__;
+   10717             : 
+   10718      557317 :     *info = 0;
+   10719             :     dir = -1;
+   10720      557317 :     if (*id=='D' || *id=='d') 
+   10721             :         dir = 0;
+   10722         670 :     else if (*id=='I' || *id=='i') 
+   10723             :         dir = 1;
+   10724             :    
+   10725             :     if (dir == -1) {
+   10726           0 :         *info = -1;
+   10727      557317 :     } else if (*n < 0) {
+   10728           0 :         *info = -2;
+   10729             :     }
+   10730      557317 :     if (*info != 0) {
+   10731             :         return;
+   10732             :     }
+   10733      557317 :     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     2227038 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10751             :                 i__2 = start + 1;
+   10752     1670335 :                 for (j = i__; j >= i__2; --j) {
+   10753     1670335 :                     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     1670335 :                         goto L30;
+   10759             :                     }
+   10760             :                 }
+   10761     1670335 : L30:
+   10762             :                 ;
+   10763             :             }
+   10764             : 
+   10765             :         } else {
+   10766             : 
+   10767             :             i__1 = endd;
+   10768         108 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10769             :                 i__2 = start + 1;
+   10770          96 :                 for (j = i__; j >= i__2; --j) {
+   10771          96 :                     if (d__[j] < d__[j - 1]) {
+   10772             :                         dmnmx = d__[j];
+   10773           0 :                         d__[j] = d__[j - 1];
+   10774           0 :                         d__[j - 1] = dmnmx;
+   10775             :                     } else {
+   10776          96 :                         goto L50;
+   10777             :                     }
+   10778             :                 }
+   10779          96 : L50:
+   10780             :                 ;
+   10781             :             }
+   10782             : 
+   10783             :         }
+   10784             : 
+   10785          59 :     } else if (endd - start > 20) {
+   10786             : 
+   10787          59 :         d1 = d__[start];
+   10788          59 :         d2 = d__[endd];
+   10789          59 :         i__ = (start + endd) / 2;
+   10790          59 :         d3 = d__[i__];
+   10791          59 :         if (d1 < d2) {
+   10792           3 :             if (d3 < d1) {
+   10793             :                 dmnmx = d1;
+   10794           3 :             } else if (d3 < d2) {
+   10795             :                 dmnmx = d3;
+   10796             :             } else {
+   10797             :                 dmnmx = d2;
+   10798             :             }
+   10799             :         } else {
+   10800          56 :             if (d3 < d2) {
+   10801             :                 dmnmx = d2;
+   10802          56 :             } else if (d3 < d1) {
+   10803             :                 dmnmx = d3;
+   10804             :             } else {
+   10805             :                 dmnmx = d1;
+   10806             :             }
+   10807             :         }
+   10808             : 
+   10809          59 :         if (dir == 0) {
+   10810             : 
+   10811          56 :             i__ = start - 1;
+   10812          56 :             j = endd + 1;
+   10813        1944 : L60:
+   10814        1944 : L70:
+   10815        2000 :             --j;
+   10816        2000 :             if (d__[j] < dmnmx) {
+   10817        1944 :                 goto L70;
+   10818             :             }
+   10819          56 : L80:
+   10820        1980 :             ++i__;
+   10821        1980 :             if (d__[i__] > dmnmx) {
+   10822        1924 :                 goto L80;
+   10823             :             }
+   10824          56 :             if (i__ < j) {
+   10825             :                 tmp = d__[i__];
+   10826           0 :                 d__[i__] = d__[j];
+   10827           0 :                 d__[j] = tmp;
+   10828           0 :                 goto L60;
+   10829             :             }
+   10830          56 :             if (j - start > endd - j - 1) {
+   10831             :                 ++stkpnt;
+   10832             :                 stack[(stkpnt << 1) - 2] = start;
+   10833          36 :                 stack[(stkpnt << 1) - 1] = j;
+   10834          36 :                 ++stkpnt;
+   10835          36 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10836          36 :                 stack[(stkpnt << 1) - 1] = endd;
+   10837             :             } else {
+   10838             :                 ++stkpnt;
+   10839          20 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10840          20 :                 stack[(stkpnt << 1) - 1] = endd;
+   10841          20 :                 ++stkpnt;
+   10842          20 :                 stack[(stkpnt << 1) - 2] = start;
+   10843          20 :                 stack[(stkpnt << 1) - 1] = j;
+   10844             :             }
+   10845             :         } else {
+   10846             : 
+   10847           3 :             i__ = start - 1;
+   10848           3 :             j = endd + 1;
+   10849          61 : L90:
+   10850          61 : L100:
+   10851          64 :             --j;
+   10852          64 :             if (d__[j] > dmnmx) {
+   10853          61 :                 goto L100;
+   10854             :             }
+   10855           3 : L110:
+   10856          63 :             ++i__;
+   10857          63 :             if (d__[i__] < dmnmx) {
+   10858          60 :                 goto L110;
+   10859             :             }
+   10860           3 :             if (i__ < j) {
+   10861             :                 tmp = d__[i__];
+   10862           0 :                 d__[i__] = d__[j];
+   10863           0 :                 d__[j] = tmp;
+   10864           0 :                 goto L90;
+   10865             :             }
+   10866           3 :             if (j - start > endd - j - 1) {
+   10867             :                 ++stkpnt;
+   10868             :                 stack[(stkpnt << 1) - 2] = start;
+   10869           2 :                 stack[(stkpnt << 1) - 1] = j;
+   10870           2 :                 ++stkpnt;
+   10871           2 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10872           2 :                 stack[(stkpnt << 1) - 1] = endd;
+   10873             :             } else {
+   10874             :                 ++stkpnt;
+   10875           1 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10876           1 :                 stack[(stkpnt << 1) - 1] = endd;
+   10877           1 :                 ++stkpnt;
+   10878           1 :                 stack[(stkpnt << 1) - 2] = start;
+   10879           1 :                 stack[(stkpnt << 1) - 1] = j;
+   10880             :             }
+   10881             :         }
+   10882             :     }
+   10883      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       14906 :                 for (j = i__; j >= i__2; --j) {
+   10972       14840 :                     if (d__[j] < d__[j - 1]) {
+   10973             :                         dmnmx = d__[j];
+   10974       14140 :                         d__[j] = d__[j - 1];
+   10975       14140 :                         d__[j - 1] = dmnmx;
+   10976       14140 :                         tmpkey = key[j];
+   10977       14140 :                         key[j] = key[j - 1];
+   10978       14140 :                         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       14895 :                 for (j = i__; j >= i__2; --j) {
+   15497       14829 :                     if (d__[j] < d__[j - 1]) {
+   15498             :                         dmnmx = d__[j];
+   15499       14138 :                         d__[j] = d__[j - 1];
+   15500       14138 :                         d__[j - 1] = dmnmx;
+   15501       14138 :                         tmpkey = key[j];
+   15502       14138 :                         key[j] = key[j - 1];
+   15503       14138 :                         key[j - 1] = tmpkey;
+   15504             :                     } else {
+   15505         691 :                         goto L50;
+   15506             :                     }
+   15507             :                 }
+   15508         757 : L50:
+   15509             :                 ;
+   15510             :             }
+   15511             : 
+   15512             :         }
+   15513             : 
+   15514           0 :     } else if (endd - start > 20) {
+   15515             : 
+   15516           0 :         d1 = d__[start];
+   15517           0 :         d2 = d__[endd];
+   15518           0 :         i__ = (start + endd) / 2;
+   15519           0 :         d3 = d__[i__];
+   15520           0 :         if (d1 < d2) {
+   15521           0 :             if (d3 < d1) {
+   15522             :                 dmnmx = d1;
+   15523             :             } else if (d3 < d2) {
+   15524             :                 dmnmx = d3;
+   15525             :             } else {
+   15526             :                 dmnmx = d2;
+   15527             :             }
+   15528             :         } else {
+   15529           0 :             if (d3 < d2) {
+   15530             :                 dmnmx = d2;
+   15531             :             } else if (d3 < d1) {
+   15532             :                 dmnmx = d3;
+   15533             :             } else {
+   15534             :                 dmnmx = d1;
+   15535             :             }
+   15536             :         }
+   15537             : 
+   15538           0 :         if (dir == 0) {
+   15539             : 
+   15540           0 :             i__ = start - 1;
+   15541           0 :             j = endd + 1;
+   15542           0 : L60:
+   15543           0 : L70:
+   15544           0 :             --j;
+   15545           0 :             if (d__[j] < dmnmx) {
+   15546           0 :                 goto L70;
+   15547             :             }
+   15548           0 : L80:
+   15549           0 :             ++i__;
+   15550           0 :             if (d__[i__] > dmnmx) {
+   15551           0 :                 goto L80;
+   15552             :             }
+   15553           0 :             if (i__ < j) {
+   15554             :                 tmp = d__[i__];
+   15555           0 :                 d__[i__] = d__[j];
+   15556           0 :                 d__[j] = tmp;
+   15557           0 :                 tmpkey = key[j];
+   15558           0 :                 key[j] = key[i__];
+   15559           0 :                 key[i__] = tmpkey;
+   15560           0 :                 goto L60;
+   15561             :             }
+   15562           0 :             if (j - start > endd - j - 1) {
+   15563             :                 ++stkpnt;
+   15564             :                 stack[(stkpnt << 1) - 2] = start;
+   15565           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15566           0 :                 ++stkpnt;
+   15567           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15568           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15569             :             } else {
+   15570             :                 ++stkpnt;
+   15571           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15572           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15573           0 :                 ++stkpnt;
+   15574           0 :                 stack[(stkpnt << 1) - 2] = start;
+   15575           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15576             :             }
+   15577             :         } else {
+   15578             : 
+   15579           0 :             i__ = start - 1;
+   15580           0 :             j = endd + 1;
+   15581           0 : L90:
+   15582           0 : L100:
+   15583           0 :             --j;
+   15584           0 :             if (d__[j] > dmnmx) {
+   15585           0 :                 goto L100;
+   15586             :             }
+   15587           0 : L110:
+   15588           0 :             ++i__;
+   15589           0 :             if (d__[i__] < dmnmx) {
+   15590           0 :                 goto L110;
+   15591             :             }
+   15592           0 :             if (i__ < j) {
+   15593             :                 tmp = d__[i__];
+   15594           0 :                 d__[i__] = d__[j];
+   15595           0 :                 d__[j] = tmp;
+   15596           0 :                 tmpkey = key[j];
+   15597           0 :                 key[j] = key[i__];
+   15598           0 :                 key[i__] = tmpkey;
+   15599           0 :                 goto L90;
+   15600             :             }
+   15601           0 :             if (j - start > endd - j - 1) {
+   15602             :                 ++stkpnt;
+   15603             :                 stack[(stkpnt << 1) - 2] = start;
+   15604           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15605           0 :                 ++stkpnt;
+   15606           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15607           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15608             :             } else {
+   15609             :                 ++stkpnt;
+   15610           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15611           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15612           0 :                 ++stkpnt;
+   15613           0 :                 stack[(stkpnt << 1) - 2] = start;
+   15614           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15615             :             }
+   15616             :         }
+   15617             :     }
+   15618           9 :     if (stkpnt > 0) {
+   15619           0 :         goto L10;
+   15620             :     }
+   15621             : 
+   15622             : 
+   15623             :     return;
+   15624             : }
+   15625             : }
+   15626             : }
+   15627             : #include <cctype>
+   15628             : #include <cmath>
+   15629             : #include "blas/blas.h"
+   15630             : #include "lapack.h"
+   15631             : #include "lapack_limits.h"
+   15632             : 
+   15633             : #include "real.h"
+   15634             : 
+   15635             : #include "blas/blas.h"
+   15636             : namespace PLMD{
+   15637             : namespace lapack{
+   15638             : using namespace blas;
+   15639             : void
+   15640           0 : PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)(const char *uplo, 
+   15641             :         const char *compq, 
+   15642             :         int *n,
+   15643             :         float *d__, 
+   15644             :         float *e, 
+   15645             :         float *u, 
+   15646             :         int *ldu,
+   15647             :         float *vt, 
+   15648             :         int *ldvt,
+   15649             :         float *q,
+   15650             :         int *iq,
+   15651             :         float *work, 
+   15652             :         int *iwork, 
+   15653             :         int *info)
+   15654             : {
+   15655             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   15656             :     int i__, j, k;
+   15657             :     float p, r__;
+   15658             :     int z__, ic, ii, kk;
+   15659             :     float cs;
+   15660             :     int is, iu;
+   15661             :     float sn;
+   15662             :     int nm1;
+   15663             :     float eps;
+   15664             :     int ivt, difl, difr, ierr, perm, mlvl, sqre;
+   15665             :     int poles, iuplo, nsize, start;
+   15666             :     int givcol;
+   15667             :     int icompq;
+   15668             :     float orgnrm;
+   15669             :     int givnum, givptr, qstart, smlsiz, wstart, smlszp;
+   15670           0 :     float zero = 0.0;
+   15671           0 :     float one = 1.0;
+   15672           0 :     int c_0 = 0;
+   15673           0 :     int c_1 = 1;
+   15674             : 
+   15675           0 :     --d__;
+   15676           0 :     --e;
+   15677           0 :     u_dim1 = *ldu;
+   15678           0 :     u_offset = 1 + u_dim1;
+   15679           0 :     u -= u_offset;
+   15680           0 :     vt_dim1 = *ldvt;
+   15681           0 :     vt_offset = 1 + vt_dim1;
+   15682           0 :     vt -= vt_offset;
+   15683           0 :     --q;
+   15684           0 :     --iq;
+   15685           0 :     --work;
+   15686             :     --iwork;
+   15687             : 
+   15688             :     k = iu = z__ = ic = is = ivt = difl = difr = perm = 0;
+   15689             :     poles = givnum = givptr = givcol = 0;
+   15690             :     
+   15691           0 :     smlsiz = DBDSDC_SMALLSIZE;
+   15692           0 :     *info = 0;
+   15693             : 
+   15694           0 :     iuplo = (*uplo=='U' || *uplo=='u') ? 1 : 2;
+   15695             : 
+   15696           0 :     switch(*compq) {
+   15697           0 :     case 'n':
+   15698             :     case 'N':
+   15699           0 :       icompq = 0;
+   15700           0 :       break;
+   15701           0 :     case 'p':
+   15702             :     case 'P':
+   15703           0 :       icompq = 1;
+   15704           0 :       break;
+   15705           0 :     case 'i':
+   15706             :     case 'I':
+   15707           0 :       icompq = 2;
+   15708           0 :       break;
+   15709             :     default:
+   15710             :       return;
+   15711             :     }
+   15712             : 
+   15713           0 :     if (*n <= 0) 
+   15714             :         return;
+   15715             :     
+   15716           0 :     if (*n == 1) {
+   15717           0 :         if (icompq == 1) {
+   15718           0 :           q[1] = (d__[1]>0) ? 1.0 : -1.0;
+   15719           0 :           q[smlsiz * *n + 1] = 1.;
+   15720           0 :         } else if (icompq == 2) {
+   15721           0 :           u[u_dim1 + 1] = (d__[1]>0) ? 1.0 : -1.0;
+   15722           0 :           vt[vt_dim1 + 1] = 1.;
+   15723             :         }
+   15724           0 :         d__[1] = std::abs(d__[1]);
+   15725           0 :         return;
+   15726             :     }
+   15727           0 :     nm1 = *n - 1;
+   15728             :     wstart = 1;
+   15729             :     qstart = 3;
+   15730           0 :     if (icompq == 1) {
+   15731           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &d__[1], &c_1, &q[1], &c_1);
+   15732           0 :         i__1 = *n - 1;
+   15733           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &e[1], &c_1, &q[*n + 1], &c_1);
+   15734             :     }
+   15735           0 :     if (iuplo == 2) {
+   15736             :         qstart = 5;
+   15737           0 :         wstart = (*n << 1) - 1;
+   15738           0 :         i__1 = *n - 1;
+   15739           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   15740           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   15741           0 :             d__[i__] = r__;
+   15742           0 :             e[i__] = sn * d__[i__ + 1];
+   15743           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   15744           0 :             if (icompq == 1) {
+   15745           0 :                 q[i__ + (*n << 1)] = cs;
+   15746           0 :                 q[i__ + *n * 3] = sn;
+   15747           0 :             } else if (icompq == 2) {
+   15748           0 :                 work[i__] = cs;
+   15749           0 :                 work[nm1 + i__] = -sn;
+   15750             :             }
+   15751             :         }
+   15752             :     }
+   15753           0 :     if (icompq == 0) {
+   15754           0 :       PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,&c_0,&c_0,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15755           0 :               &u[u_offset], ldu, &u[u_offset], ldu, &work[wstart], info);
+   15756           0 :         goto L40;
+   15757             :     }
+   15758           0 :     if (*n <= smlsiz) {
+   15759           0 :         if (icompq == 2) {
+   15760           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15761           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15762           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,n,n,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15763           0 :                     &u[u_offset],ldu,&u[u_offset],ldu,&work[wstart],info);
+   15764           0 :         } else if (icompq == 1) {
+   15765             :             iu = 1;
+   15766           0 :             ivt = iu + *n;
+   15767           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[iu + (qstart - 1) * *n], n);
+   15768           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[ivt + (qstart - 1) * *n], n);
+   15769           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &c_0, n, n, n, &c_0, &d__[1], &e[1], 
+   15770           0 :                     &q[ivt + (qstart - 1) * *n], n, &q[iu + (qstart - 1) * *n], 
+   15771           0 :                     n, &q[iu + (qstart - 1) * *n], n, &work[wstart], info);
+   15772             :         }
+   15773           0 :         goto L40;
+   15774             :     }
+   15775             : 
+   15776           0 :     if (icompq == 2) {
+   15777           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15778           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15779             :     }
+   15780             : 
+   15781           0 :     orgnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   15782           0 :     if ( std::abs(orgnrm)<PLUMED_GMX_FLOAT_MIN) {
+   15783             :         return;
+   15784             :     }
+   15785           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, n, &c_1, &d__[1], n, &ierr);
+   15786           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, &nm1, &c_1, &e[1], &nm1, &ierr);
+   15787             : 
+   15788             :     eps = PLUMED_GMX_FLOAT_EPS;
+   15789             : 
+   15790           0 :     mlvl = (int) (std::log((float) (*n) / (float) (smlsiz + 1)) / std::log(2.)) + 1;
+   15791             :     smlszp = smlsiz + 1;
+   15792             : 
+   15793           0 :     if (icompq == 1) {
+   15794             :         iu = 1;
+   15795             :         ivt = smlsiz + 1;
+   15796           0 :         difl = ivt + smlszp;
+   15797           0 :         difr = difl + mlvl;
+   15798           0 :         z__ = difr + (mlvl << 1);
+   15799           0 :         ic = z__ + mlvl;
+   15800           0 :         is = ic + 1;
+   15801           0 :         poles = is + 1;
+   15802           0 :         givnum = poles + (mlvl << 1);
+   15803             : 
+   15804             :         k = 1;
+   15805             :         givptr = 2;
+   15806             :         perm = 3;
+   15807           0 :         givcol = perm + mlvl;
+   15808             :     }
+   15809             : 
+   15810           0 :     i__1 = *n;
+   15811           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15812           0 :         if (std::abs(d__[i__]) < eps) 
+   15813           0 :             d__[i__] = (d__[i__]>0) ? eps : -eps;
+   15814             :     }
+   15815             : 
+   15816             :     start = 1;
+   15817           0 :     sqre = 0;
+   15818             : 
+   15819           0 :     i__1 = nm1;
+   15820           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15821           0 :         if (std::abs(e[i__]) < eps || i__ == nm1) {
+   15822           0 :             if (i__ < nm1) {
+   15823           0 :                 nsize = i__ - start + 1;
+   15824           0 :             } else if (std::abs(e[i__]) >= eps) {
+   15825           0 :                 nsize = *n - start + 1;
+   15826             :             } else {
+   15827           0 :                 nsize = i__ - start + 1;
+   15828           0 :                 if (icompq == 2) {
+   15829           0 :                     u[*n + *n * u_dim1] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15830           0 :                     vt[*n + *n * vt_dim1] = 1.;
+   15831           0 :                 } else if (icompq == 1) {
+   15832           0 :                     q[*n + (qstart - 1) * *n] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15833           0 :                     q[*n + (smlsiz + qstart - 1) * *n] = 1.;
+   15834             :                 }
+   15835           0 :                 d__[*n] = std::abs(d__[*n]);
+   15836             :             }
+   15837           0 :             if (icompq == 2) {
+   15838           0 :                 PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(&nsize, &sqre, &d__[start], &e[start], 
+   15839           0 :                         &u[start + start * u_dim1], ldu, 
+   15840           0 :                         &vt[start + start * vt_dim1], 
+   15841           0 :                         ldvt, &smlsiz, &iwork[1], &work[wstart], info);
+   15842             :             } else {
+   15843           0 :                 PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(&icompq, &smlsiz, &nsize, &sqre, &d__[start], 
+   15844           0 :                         &e[start], &q[start + (iu + qstart - 2) * *n], n, 
+   15845           0 :                         &q[start + (ivt + qstart - 2) * *n], &iq[start + k * *n],
+   15846           0 :                         &q[start + (difl + qstart - 2) * *n], 
+   15847           0 :                         &q[start + (difr + qstart - 2) * *n], 
+   15848           0 :                         &q[start + (z__ + qstart - 2) * *n], 
+   15849           0 :                         &q[start + (poles + qstart - 2) * *n], 
+   15850           0 :                         &iq[start + givptr * *n], &iq[start + givcol * *n], n, 
+   15851           0 :                         &iq[start + perm * *n], 
+   15852           0 :                         &q[start + (givnum + qstart - 2) * *n], 
+   15853           0 :                         &q[start + (ic + qstart - 2) * *n], 
+   15854           0 :                         &q[start + (is + qstart - 2) * *n], &work[wstart], 
+   15855             :                         &iwork[1], info);
+   15856           0 :                 if (*info != 0) {
+   15857             :                     return;
+   15858             :                 }
+   15859             :             }
+   15860           0 :             start = i__ + 1;
+   15861             :         }
+   15862             :     }
+   15863           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &one, &orgnrm, n, &c_1, &d__[1], n, &ierr);
+   15864           0 : L40:
+   15865           0 :     i__1 = *n;
+   15866           0 :     for (ii = 2; ii <= i__1; ++ii) {
+   15867           0 :         i__ = ii - 1;
+   15868             :         kk = i__;
+   15869           0 :         p = d__[i__];
+   15870           0 :         i__2 = *n;
+   15871           0 :         for (j = ii; j <= i__2; ++j) {
+   15872           0 :             if (d__[j] > p) {
+   15873             :                 kk = j;
+   15874             :                 p = d__[j];
+   15875             :             }
+   15876             :         }
+   15877           0 :         if (kk != i__) {
+   15878           0 :             d__[kk] = d__[i__];
+   15879           0 :             d__[i__] = p;
+   15880           0 :             if (icompq == 1) {
+   15881           0 :                 iq[i__] = kk;
+   15882           0 :             } else if (icompq == 2) {
+   15883           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &u[i__ * u_dim1 + 1],&c_1,&u[kk*u_dim1+1],&c_1);
+   15884           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &vt[i__ + vt_dim1], ldvt, &vt[kk + vt_dim1], ldvt);
+   15885             :             }
+   15886           0 :         } else if (icompq == 1) {
+   15887           0 :             iq[i__] = i__;
+   15888             :         }
+   15889             :     }
+   15890           0 :     if (icompq == 1) {
+   15891           0 :         if (iuplo == 1) {
+   15892           0 :             iq[*n] = 1;
+   15893             :         } else {
+   15894           0 :             iq[*n] = 0;
+   15895             :         }
+   15896             :     }
+   15897           0 :     if (iuplo == 2 && icompq == 2) {
+   15898           0 :         PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", n, n, &work[1], &work[*n], &u[u_offset], ldu);
+   15899             :     }
+   15900             : 
+   15901             :     return;
+   15902             : }
+   15903             : }
+   15904             : }
+   15905             : #include <cctype>
+   15906             : #include <cmath>
+   15907             : 
+   15908             : #include "blas/blas.h"
+   15909             : #include "lapack.h"
+   15910             : 
+   15911             : #include "real.h"
+   15912             : 
+   15913             : #include "blas/blas.h"
+   15914             : namespace PLMD{
+   15915             : namespace lapack{
+   15916             : using namespace blas;
+   15917             : void 
+   15918           0 : PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)(const char *uplo,
+   15919             :                         int *n,
+   15920             :                         int *ncvt,
+   15921             :                         int *nru, 
+   15922             :                         int *ncc, 
+   15923             :                         float *d__,
+   15924             :                         float *e,
+   15925             :                         float *vt, 
+   15926             :                         int *ldvt,
+   15927             :                         float *u, 
+   15928             :                         int *ldu,
+   15929             :                         float *c__, 
+   15930             :                         int *ldc,
+   15931             :                         float *work,
+   15932             :                         int *info)
+   15933             : {
+   15934           0 :     const char xuplo = std::toupper(*uplo);
+   15935             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   15936             :             i__2;
+   15937             :     float r__1, r__2, r__3, r__4;
+   15938             :     float c_b15 = -.125;
+   15939             : 
+   15940           0 :     int c__1 = 1;
+   15941             :     float c_b49 = 1.f;
+   15942           0 :     float c_b72 = -1.f;
+   15943             : 
+   15944             :     float f, g, h__;
+   15945             :     int i__, j, m;
+   15946             :     float r__, cs;
+   15947             :     int ll;
+   15948             :     float sn, mu;
+   15949             :     int nm1, nm12, nm13, lll;
+   15950             :     float eps, sll, tol, abse;
+   15951             :     int idir;
+   15952             :     float abss;
+   15953             :     int oldm;
+   15954             :     float cosl;
+   15955             :     int isub, iter;
+   15956             :     float unfl, sinl, cosr, smin, smax, sinr;
+   15957             :     float oldcs;
+   15958             :     int oldll;
+   15959           0 :     float shift, sigmn, oldsn = 0.;
+   15960             :     int maxit;
+   15961             :     float sminl;
+   15962             :     float sigmx;
+   15963             :     int lower;
+   15964             :     float sminoa;
+   15965             :     float thresh;
+   15966             :     int rotate;
+   15967             :     float tolmul;
+   15968             :     int itmp1,itmp2;
+   15969             :     
+   15970           0 :     --d__;
+   15971           0 :     --e;
+   15972           0 :     vt_dim1 = *ldvt;
+   15973           0 :     vt_offset = 1 + vt_dim1;
+   15974           0 :     vt -= vt_offset;
+   15975           0 :     u_dim1 = *ldu;
+   15976           0 :     u_offset = 1 + u_dim1;
+   15977           0 :     u -= u_offset;
+   15978           0 :     c_dim1 = *ldc;
+   15979           0 :     c_offset = 1 + c_dim1;
+   15980           0 :     c__ -= c_offset;
+   15981           0 :     --work;
+   15982             : 
+   15983           0 :     *info = 0;
+   15984             :     
+   15985           0 :     itmp1 = (*n > 1) ? *n : 1;
+   15986           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   15987             :     
+   15988             :     lower = (xuplo == 'L');
+   15989           0 :     if ( (xuplo!='U') && !lower) {
+   15990           0 :         *info = -1;
+   15991           0 :     } else if (*n < 0) {
+   15992           0 :         *info = -2;
+   15993           0 :     } else if (*ncvt < 0) {
+   15994           0 :         *info = -3;
+   15995           0 :     } else if (*nru < 0) {
+   15996           0 :         *info = -4;
+   15997           0 :     } else if (*ncc < 0) {
+   15998           0 :         *info = -5;
+   15999           0 :     } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
+   16000           0 :         *info = -9;
+   16001           0 :     } else if (*ldu < itmp2) {
+   16002           0 :         *info = -11;
+   16003           0 :     } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
+   16004           0 :         *info = -13;
+   16005             :     }
+   16006           0 :     if (*info != 0) {
+   16007             :         return;
+   16008             :     }
+   16009           0 :     if (*n == 0) {
+   16010             :         return;
+   16011             :     }
+   16012           0 :     if (*n == 1) {
+   16013           0 :         goto L160;
+   16014             :     }
+   16015             : 
+   16016           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   16017             : 
+   16018             :     if (! rotate) {
+   16019           0 :         PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(n, &d__[1], &e[1], &work[1], info);
+   16020           0 :         return;
+   16021             :     }
+   16022             : 
+   16023           0 :     nm1 = *n - 1;
+   16024           0 :     nm12 = nm1 + nm1;
+   16025           0 :     nm13 = nm12 + nm1;
+   16026             :     idir = 0;
+   16027             : 
+   16028             :     eps = PLUMED_GMX_FLOAT_EPS;
+   16029             :     unfl = PLUMED_GMX_FLOAT_MIN/PLUMED_GMX_FLOAT_EPS;
+   16030             : 
+   16031           0 :     if (lower) {
+   16032           0 :         i__1 = *n - 1;
+   16033           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   16034           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   16035           0 :             d__[i__] = r__;
+   16036           0 :             e[i__] = sn * d__[i__ + 1];
+   16037           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   16038           0 :             work[i__] = cs;
+   16039           0 :             work[nm1 + i__] = sn;
+   16040             :         }
+   16041             : 
+   16042           0 :         if (*nru > 0) {
+   16043           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset], 
+   16044             :                     ldu);
+   16045             :         }
+   16046           0 :         if (*ncc > 0) {
+   16047           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset],
+   16048             :                      ldc);
+   16049             :         }
+   16050             :     }
+   16051             : 
+   16052             :     r__3 = 100.f, r__4 = std::pow(static_cast<float>(PLUMED_GMX_FLOAT_EPS),c_b15);
+   16053           0 :     r__1 = 10.f, r__2 = (r__3<r__4) ? r__3 : r__4;
+   16054             :     tolmul = (r__1>r__2) ? r__1 : r__2;
+   16055             :     tol = tolmul * eps;
+   16056             :     smax = 0.f;
+   16057           0 :     i__1 = *n;
+   16058           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16059           0 :         r__2 = smax, r__3 = (r__1 = d__[i__], std::abs(r__1));
+   16060           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16061             :     }
+   16062           0 :     i__1 = *n - 1;
+   16063           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16064           0 :         r__2 = smax, r__3 = (r__1 = e[i__], std::abs(r__1));
+   16065           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16066             :     }
+   16067             :     sminl = 0.f;
+   16068             :     if (tol >= 0.f) {
+   16069           0 :         sminoa = std::abs(d__[1]);
+   16070           0 :         if (sminoa == 0.f) {
+   16071           0 :             goto L50;
+   16072             :         }
+   16073             :         mu = sminoa;
+   16074           0 :         i__1 = *n;
+   16075           0 :         for (i__ = 2; i__ <= i__1; ++i__) {
+   16076           0 :             mu = (r__2 = d__[i__], std::abs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
+   16077           0 :                     1], std::abs(r__1))));
+   16078           0 :             sminoa = (sminoa<mu) ? sminoa : mu;
+   16079           0 :             if (sminoa == 0.f) {
+   16080           0 :                 goto L50;
+   16081             :             }
+   16082             :         }
+   16083           0 : L50:
+   16084           0 :         sminoa /=  std::sqrt((float) (*n));
+   16085           0 :         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
+   16086           0 :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16087             :     } else {
+   16088             :         r__1 = std::abs(tol) * smax, r__2 = *n * 6 * *n * unfl;
+   16089             :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16090             :     }
+   16091             :     maxit = *n * 6 * *n;
+   16092             :     iter = 0;
+   16093             :     oldll = -1;
+   16094             :     oldm = -1;
+   16095             :     m = *n;
+   16096             : 
+   16097           0 : L60:
+   16098             : 
+   16099           0 :     if (m <= 1) {
+   16100           0 :         goto L160;
+   16101             :     }
+   16102           0 :     if (iter > maxit) {
+   16103           0 :         goto L200;
+   16104             :     }
+   16105             : 
+   16106             :     if (tol < 0.f && (r__1 = d__[m], std::abs(r__1)) <= thresh) {
+   16107             :         d__[m] = 0.f;
+   16108             :     }
+   16109           0 :     smax = (r__1 = d__[m], std::abs(r__1));
+   16110             :     smin = smax;
+   16111           0 :     i__1 = m - 1;
+   16112           0 :     for (lll = 1; lll <= i__1; ++lll) {
+   16113           0 :         ll = m - lll;
+   16114           0 :         abss = (r__1 = d__[ll], std::abs(r__1));
+   16115           0 :         abse = (r__1 = e[ll], std::abs(r__1));
+   16116             :         if (tol < 0.f && abss <= thresh) {
+   16117             :             d__[ll] = 0.f;
+   16118             :         }
+   16119           0 :         if (abse <= thresh) {
+   16120           0 :             goto L80;
+   16121             :         }
+   16122           0 :         smin = (smin<abss) ? smin : abss;
+   16123           0 :         r__1 = (smax>abss) ? smax : abss;
+   16124           0 :         smax = (r__1>abse) ? r__1 : abse;
+   16125             :     }
+   16126             :     ll = 0;
+   16127           0 :     goto L90;
+   16128             : L80:
+   16129           0 :     e[ll] = 0.f;
+   16130           0 :     if (ll == m - 1) {
+   16131             :         --m;
+   16132           0 :         goto L60;
+   16133             :     }
+   16134           0 : L90:
+   16135           0 :     ++ll;
+   16136           0 :     if (ll == m - 1) {
+   16137           0 :         PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
+   16138             :                  &sinl, &cosl);
+   16139           0 :         d__[m - 1] = sigmx;
+   16140           0 :         e[m - 1] = 0.f;
+   16141           0 :         d__[m] = sigmn;
+   16142           0 :         if (*ncvt > 0) {
+   16143           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
+   16144             :                     cosr, &sinr);
+   16145             :         }
+   16146           0 :         if (*nru > 0) {
+   16147           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
+   16148             :                     c__1, &cosl, &sinl);
+   16149             :         }
+   16150           0 :         if (*ncc > 0) {
+   16151           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
+   16152             :                     cosl, &sinl);
+   16153             :         }
+   16154           0 :         m += -2;
+   16155           0 :         goto L60;
+   16156             :     }
+   16157           0 :     if (ll > oldm || m < oldll) {
+   16158           0 :         if ((r__1 = d__[ll], std::abs(r__1)) >= (r__2 = d__[m], std::abs(r__2))) {
+   16159             :             idir = 1;
+   16160             :         } else {
+   16161             :             idir = 2;
+   16162             :         }
+   16163             :     }
+   16164           0 :     if (idir == 1) {
+   16165             : 
+   16166           0 :         if( (std::abs(e[m-1]) <= std::abs(tol) * std::abs(d__[m])) ||
+   16167             :             (tol<0.0 && std::abs(e[m-1])<=thresh)) {
+   16168           0 :             e[m - 1] = 0.f;
+   16169           0 :             goto L60;
+   16170             :         }
+   16171             :         if (tol >= 0.f) {
+   16172           0 :             mu = (r__1 = d__[ll], std::abs(r__1));
+   16173             :             sminl = mu;
+   16174             :             i__1 = m - 1;
+   16175           0 :             for (lll = ll; lll <= i__1; ++lll) {
+   16176           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16177           0 :                     e[lll] = 0.f;
+   16178           0 :                     goto L60;
+   16179             :                 }
+   16180           0 :                 mu = (r__2 = d__[lll + 1], std::abs(r__2)) * (mu / (mu + (r__1 = 
+   16181             :                         e[lll], std::abs(r__1))));
+   16182           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16183             :             }
+   16184             :         }
+   16185             :     } else {
+   16186           0 :         if( (std::abs(e[ll]) <= std::abs(tol)*std::abs(d__[ll])) ||
+   16187             :             (tol<0.0 && std::abs(e[ll])<=thresh)) {
+   16188           0 :             e[ll] = 0.f;
+   16189           0 :             goto L60;
+   16190             :         }
+   16191             :         if (tol >= 0.f) {
+   16192           0 :             mu = (r__1 = d__[m], std::abs(r__1));
+   16193             :             sminl = mu;
+   16194           0 :             i__1 = ll;
+   16195           0 :             for (lll = m - 1; lll >= i__1; --lll) {
+   16196           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16197           0 :                     e[lll] = 0.f;
+   16198           0 :                     goto L60;
+   16199             :                 }
+   16200           0 :                 mu = (r__2 = d__[lll], std::abs(r__2)) * (mu / (mu + (r__1 = e[
+   16201             :                         lll], std::abs(r__1))));
+   16202           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16203             :             }
+   16204             :         }
+   16205             :     }
+   16206             :     oldll = ll;
+   16207             :     oldm = m;
+   16208             : 
+   16209           0 :     r__1 = eps, r__2 = tol * .01f;
+   16210           0 :     if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
+   16211           0 :         shift = 0.f;
+   16212             :     } else {
+   16213           0 :         if (idir == 1) {
+   16214           0 :             sll = (r__1 = d__[ll], std::abs(r__1));
+   16215           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
+   16216             :         } else {
+   16217           0 :             sll = (r__1 = d__[m], std::abs(r__1));
+   16218           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
+   16219             :         }
+   16220           0 :         if (sll > 0.f) {
+   16221           0 :             r__1 = shift / sll;
+   16222           0 :             if (r__1 * r__1 < eps) {
+   16223           0 :                 shift = 0.f;
+   16224             :             }
+   16225             :         }
+   16226             :     }
+   16227           0 :     iter = iter + m - ll;
+   16228           0 :     if (shift == 0.f) {
+   16229           0 :         if (idir == 1) {
+   16230           0 :             cs = 1.f;
+   16231           0 :             oldcs = 1.f;
+   16232           0 :             i__1 = m - 1;
+   16233           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16234           0 :                 r__1 = d__[i__] * cs;
+   16235           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
+   16236           0 :                 if (i__ > ll) {
+   16237           0 :                     e[i__ - 1] = oldsn * r__;
+   16238             :                 }
+   16239           0 :                 r__1 = oldcs * r__;
+   16240           0 :                 r__2 = d__[i__ + 1] * sn;
+   16241           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16242           0 :                 work[i__ - ll + 1] = cs;
+   16243           0 :                 work[i__ - ll + 1 + nm1] = sn;
+   16244           0 :                 work[i__ - ll + 1 + nm12] = oldcs;
+   16245           0 :                 work[i__ - ll + 1 + nm13] = oldsn;
+   16246             :             }
+   16247           0 :             h__ = d__[m] * cs;
+   16248           0 :             d__[m] = h__ * oldcs;
+   16249           0 :             e[m - 1] = h__ * oldsn;
+   16250           0 :             if (*ncvt > 0) {
+   16251           0 :                 i__1 = m - ll + 1;
+   16252           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16253           0 :                         ll + vt_dim1], ldvt);
+   16254             :             }
+   16255           0 :             if (*nru > 0) {
+   16256           0 :                 i__1 = m - ll + 1;
+   16257           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16258           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16259             :             }
+   16260           0 :             if (*ncc > 0) {
+   16261           0 :                 i__1 = m - ll + 1;
+   16262           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16263           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16264             :             }
+   16265           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16266           0 :                 e[m - 1] = 0.f;
+   16267             :             }
+   16268             :         } else {
+   16269           0 :             cs = 1.f;
+   16270           0 :             oldcs = 1.f;
+   16271           0 :             i__1 = ll + 1;
+   16272           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16273           0 :                 r__1 = d__[i__] * cs;
+   16274           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__ - 1], &cs, &sn, &r__);
+   16275           0 :                 if (i__ < m) {
+   16276           0 :                     e[i__] = oldsn * r__;
+   16277             :                 }
+   16278           0 :                 r__1 = oldcs * r__;
+   16279           0 :                 r__2 = d__[i__ - 1] * sn;
+   16280           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16281           0 :                 work[i__ - ll] = cs;
+   16282           0 :                 work[i__ - ll + nm1] = -sn;
+   16283           0 :                 work[i__ - ll + nm12] = oldcs;
+   16284           0 :                 work[i__ - ll + nm13] = -oldsn;
+   16285             :             }
+   16286           0 :             h__ = d__[ll] * cs;
+   16287           0 :             d__[ll] = h__ * oldcs;
+   16288           0 :             e[ll] = h__ * oldsn;
+   16289           0 :             if (*ncvt > 0) {
+   16290           0 :                 i__1 = m - ll + 1;
+   16291           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16292           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16293             :             }
+   16294           0 :             if (*nru > 0) {
+   16295           0 :                 i__1 = m - ll + 1;
+   16296           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16297           0 :                          u_dim1 + 1], ldu);
+   16298             :             }
+   16299           0 :             if (*ncc > 0) {
+   16300           0 :                 i__1 = m - ll + 1;
+   16301           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16302           0 :                         ll + c_dim1], ldc);
+   16303             :             }
+   16304           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16305           0 :                 e[ll] = 0.f;
+   16306             :             }
+   16307             :         }
+   16308             :     } else {
+   16309             : 
+   16310           0 :         if (idir == 1) {
+   16311           0 :             f = ((r__1 = d__[ll], std::abs(r__1)) - shift) * ( ((d__[ll] > 0) ? c_b49 : -c_b49) + shift / d__[ll]);
+   16312           0 :             g = e[ll];
+   16313           0 :             i__1 = m - 1;
+   16314           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16315           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16316           0 :                 if (i__ > ll) {
+   16317           0 :                     e[i__ - 1] = r__;
+   16318             :                 }
+   16319           0 :                 f = cosr * d__[i__] + sinr * e[i__];
+   16320           0 :                 e[i__] = cosr * e[i__] - sinr * d__[i__];
+   16321           0 :                 g = sinr * d__[i__ + 1];
+   16322           0 :                 d__[i__ + 1] = cosr * d__[i__ + 1];
+   16323           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16324           0 :                 d__[i__] = r__;
+   16325           0 :                 f = cosl * e[i__] + sinl * d__[i__ + 1];
+   16326           0 :                 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
+   16327           0 :                 if (i__ < m - 1) {
+   16328           0 :                     g = sinl * e[i__ + 1];
+   16329           0 :                     e[i__ + 1] = cosl * e[i__ + 1];
+   16330             :                 }
+   16331           0 :                 work[i__ - ll + 1] = cosr;
+   16332           0 :                 work[i__ - ll + 1 + nm1] = sinr;
+   16333           0 :                 work[i__ - ll + 1 + nm12] = cosl;
+   16334           0 :                 work[i__ - ll + 1 + nm13] = sinl;
+   16335             :             }
+   16336           0 :             e[m - 1] = f;
+   16337             : 
+   16338           0 :             if (*ncvt > 0) {
+   16339           0 :                 i__1 = m - ll + 1;
+   16340           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16341           0 :                         ll + vt_dim1], ldvt);
+   16342             :             }
+   16343           0 :             if (*nru > 0) {
+   16344           0 :                 i__1 = m - ll + 1;
+   16345           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16346           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16347             :             }
+   16348           0 :             if (*ncc > 0) {
+   16349           0 :                 i__1 = m - ll + 1;
+   16350           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16351           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16352             :             }
+   16353           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16354           0 :                 e[m - 1] = 0.f;
+   16355             :             }
+   16356             :         } else {
+   16357             : 
+   16358           0 :             f = ((r__1 = d__[m], std::abs(r__1)) - shift) * ( ((d__[m] > 0) ? c_b49 : -c_b49) + shift / d__[m]);
+   16359           0 :             g = e[m - 1];
+   16360           0 :             i__1 = ll + 1;
+   16361           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16362           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16363           0 :                 if (i__ < m) {
+   16364           0 :                     e[i__] = r__;
+   16365             :                 }
+   16366           0 :                 f = cosr * d__[i__] + sinr * e[i__ - 1];
+   16367           0 :                 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
+   16368           0 :                 g = sinr * d__[i__ - 1];
+   16369           0 :                 d__[i__ - 1] = cosr * d__[i__ - 1];
+   16370           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16371           0 :                 d__[i__] = r__;
+   16372           0 :                 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
+   16373           0 :                 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
+   16374           0 :                 if (i__ > ll + 1) {
+   16375           0 :                     g = sinl * e[i__ - 2];
+   16376           0 :                     e[i__ - 2] = cosl * e[i__ - 2];
+   16377             :                 }
+   16378           0 :                 work[i__ - ll] = cosr;
+   16379           0 :                 work[i__ - ll + nm1] = -sinr;
+   16380           0 :                 work[i__ - ll + nm12] = cosl;
+   16381           0 :                 work[i__ - ll + nm13] = -sinl;
+   16382             :             }
+   16383           0 :             e[ll] = f;
+   16384             : 
+   16385           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16386           0 :                 e[ll] = 0.f;
+   16387             :             }
+   16388           0 :             if (*ncvt > 0) {
+   16389           0 :                 i__1 = m - ll + 1;
+   16390           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16391           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16392             :             }
+   16393           0 :             if (*nru > 0) {
+   16394           0 :                 i__1 = m - ll + 1;
+   16395           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16396           0 :                          u_dim1 + 1], ldu);
+   16397             :             }
+   16398           0 :             if (*ncc > 0) {
+   16399           0 :                 i__1 = m - ll + 1;
+   16400           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16401           0 :                         ll + c_dim1], ldc);
+   16402             :             }
+   16403             :         }
+   16404             :     }
+   16405             : 
+   16406           0 :     goto L60;
+   16407             : 
+   16408           0 : L160:
+   16409           0 :     i__1 = *n;
+   16410           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16411           0 :         if (d__[i__] < 0.f) {
+   16412           0 :             d__[i__] = -d__[i__];
+   16413             : 
+   16414           0 :             if (*ncvt > 0) {
+   16415           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
+   16416             :             }
+   16417             :         }
+   16418             :     }
+   16419             : 
+   16420           0 :     i__1 = *n - 1;
+   16421           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16422             : 
+   16423             :         isub = 1;
+   16424           0 :         smin = d__[1];
+   16425           0 :         i__2 = *n + 1 - i__;
+   16426           0 :         for (j = 2; j <= i__2; ++j) {
+   16427           0 :             if (d__[j] <= smin) {
+   16428             :                 isub = j;
+   16429             :                 smin = d__[j];
+   16430             :             }
+   16431             :         }
+   16432           0 :         if (isub != *n + 1 - i__) {
+   16433           0 :             d__[isub] = d__[*n + 1 - i__];
+   16434           0 :             d__[*n + 1 - i__] = smin;
+   16435           0 :             if (*ncvt > 0) {
+   16436           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ + 
+   16437           0 :                         vt_dim1], ldvt);
+   16438             :             }
+   16439           0 :             if (*nru > 0) {
+   16440           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) * 
+   16441           0 :                         u_dim1 + 1], &c__1);
+   16442             :             }
+   16443           0 :             if (*ncc > 0) {
+   16444           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ + 
+   16445           0 :                         c_dim1], ldc);
+   16446             :             }
+   16447             :         }
+   16448             :     }
+   16449           0 :     goto L220;
+   16450             : 
+   16451             : L200:
+   16452           0 :     *info = 0;
+   16453           0 :     i__1 = *n - 1;
+   16454           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16455           0 :         if (e[i__] != 0.f) {
+   16456           0 :             ++(*info);
+   16457             :         }
+   16458             :     }
+   16459           0 : L220:
+   16460             :     return;
+   16461             : 
+   16462             : }
+   16463             : 
+   16464             : 
+   16465             : }
+   16466             : }
+   16467             : #include "lapack.h"
+   16468             : 
+   16469             : #include "blas/blas.h"
+   16470             : namespace PLMD{
+   16471             : namespace lapack{
+   16472             : using namespace blas;
+   16473             : void
+   16474           0 : PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(int *m,
+   16475             :         int *n,
+   16476             :         float *a,
+   16477             :         int *lda,
+   16478             :         float *d,
+   16479             :         float *e,
+   16480             :         float *tauq,
+   16481             :         float *taup,
+   16482             :         float *work,
+   16483             :         int *info)
+   16484             : {
+   16485             : 
+   16486             :   int i,i1,i2,i3;
+   16487             : 
+   16488           0 :     *info = 0;
+   16489             : 
+   16490           0 :   if(*m>=*n) {
+   16491             :     /* reduce to upper bidiag. form */
+   16492           0 :     for(i=0;i<*n;i++) {
+   16493           0 :       i1 = *m - i;
+   16494           0 :       i2 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16495           0 :       i3 = 1;
+   16496           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16497           0 :       d[i] = a[i*(*lda)+i];
+   16498           0 :       a[i*(*lda)+i] = 1.0;
+   16499           0 :       i2 = *n - i - 1;
+   16500           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i]),lda,work);
+   16501           0 :       a[i*(*lda)+i] = d[i];
+   16502             : 
+   16503           0 :       if(i<(*n-1)) {
+   16504             : 
+   16505           0 :         i1 = *n - i -1;
+   16506           0 :         i2 = ( (i+2) < (*n-1)) ? (i+2) : (*n-1); 
+   16507           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i+1)*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16508             : 
+   16509           0 :         e[i] = a[(i+1)*(*lda)+i];
+   16510           0 :         a[(i+1)*(*lda)+i] = 1.0;
+   16511             : 
+   16512           0 :         i1 = *m - i - 1;
+   16513           0 :         i2 = *n - i - 1;
+   16514           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i1,&i2,&(a[(i+1)*(*lda)+i]),lda,&(taup[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16515           0 :         a[(i+1)*(*lda)+i] = e[i];
+   16516             :       } else
+   16517           0 :         taup[i] = 0.0;
+   16518             :     }
+   16519             :   } else {
+   16520             :     /* reduce to lower bidiag. form */
+   16521           0 :     for(i=0;i<*m;i++) {
+   16522           0 :       i1 = *n - i;
+   16523           0 :       i2 = ( (i+1) < (*n-1)) ? (i+1) : (*n-1);
+   16524           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16525           0 :       d[i] = a[i*(*lda)+i];
+   16526           0 :       a[i*(*lda)+i] = 1.0;
+   16527             : 
+   16528           0 :       i2 = *m - i - 1;
+   16529           0 :       i3 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16530           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i2,&i1,&(a[i*(*lda)+i]),lda,&(taup[i]),&(a[(i)*(*lda)+i3]),lda,work);
+   16531           0 :       a[i*(*lda)+i] = d[i];
+   16532             : 
+   16533           0 :       if(i<(*m-1)) {
+   16534             : 
+   16535           0 :         i1 = *m - i - 1;
+   16536           0 :         i2 = ( (i+2) < (*m-1)) ? (i+2) : (*m-1);
+   16537           0 :         i3 = 1;
+   16538           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i)*(*lda)+i+1]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16539             : 
+   16540           0 :         e[i] = a[(i)*(*lda)+i+1];
+   16541           0 :         a[(i)*(*lda)+i+1] = 1.0;
+   16542             : 
+   16543           0 :         i1 = *m - i - 1;
+   16544           0 :         i2 = *n - i - 1;
+   16545           0 :         i3 = 1;
+   16546           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[(i)*(*lda)+i+1]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16547           0 :         a[(i)*(*lda)+i+1] = e[i];
+   16548             :       } else
+   16549           0 :         tauq[i] = 0.0;
+   16550             :     }
+   16551             :   }
+   16552           0 :   return;
+   16553             : }
+   16554             : }
+   16555             : }
+   16556             : #include "lapack.h"
+   16557             : #include "blas/blas.h"
+   16558             : #include "lapack_limits.h"
+   16559             : 
+   16560             : 
+   16561             : #include "blas/blas.h"
+   16562             : namespace PLMD{
+   16563             : namespace lapack{
+   16564             : using namespace blas;
+   16565             : void
+   16566           0 : PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(int *m, 
+   16567             :         int *n, 
+   16568             :         float *a, 
+   16569             :         int *lda, 
+   16570             :         float *d__, 
+   16571             :         float *e,
+   16572             :         float *tauq, 
+   16573             :         float *taup,
+   16574             :         float *work, 
+   16575             :         int *lwork,
+   16576             :         int *info)
+   16577             : {
+   16578             :     /* System generated locals */
+   16579             :     int a_dim1, a_offset, i_1, i_2, i_3, i_4;
+   16580             : 
+   16581             :     /* Local variables */
+   16582             :     int i_, j, nx,nb;
+   16583             :     float ws;
+   16584             :     int nbmin, iinfo, minmn;
+   16585             :     int ldwrkx, ldwrky;
+   16586           0 :     float one = 1.0;
+   16587           0 :     float minusone = -1.0;
+   16588             : 
+   16589           0 :     a_dim1 = *lda;
+   16590           0 :     a_offset = 1 + a_dim1;
+   16591           0 :     a -= a_offset;
+   16592           0 :     --d__;
+   16593           0 :     --e;
+   16594           0 :     --tauq;
+   16595           0 :     --taup;
+   16596           0 :     --work;
+   16597             : 
+   16598           0 :     nb = DGEBRD_BLOCKSIZE;
+   16599           0 :     *info = 0;
+   16600           0 :     if (*lwork==-1) {
+   16601           0 :       work[1] = (float) ( (*m + *n) * nb);
+   16602           0 :       return;
+   16603             :     }
+   16604           0 :     minmn = (*m < *n) ? *m : *n;
+   16605           0 :     if (minmn == 0) {
+   16606           0 :       work[1] = 1.;
+   16607           0 :       return;
+   16608             :     }
+   16609             : 
+   16610           0 :     ws = (*m > *n) ? *m : *n;
+   16611           0 :     ldwrkx = *m;
+   16612           0 :     ldwrky = *n;
+   16613             : 
+   16614           0 :     if (nb > 1 && nb < minmn) {
+   16615             :         nx = DGEBRD_CROSSOVER;
+   16616           0 :         if (nx < minmn) {
+   16617           0 :             ws = (float) ((*m + *n) * nb);
+   16618           0 :             if ((float) (*lwork) < ws) {
+   16619             :               nbmin = DGEBRD_MINBLOCKSIZE;
+   16620           0 :                 if (*lwork >= (*m + *n) * nbmin) {
+   16621           0 :                     nb = *lwork / (*m + *n);
+   16622             :                 } else {
+   16623           0 :                     nb = 1;
+   16624             :                     nx = minmn;
+   16625             :                 }
+   16626             :             }
+   16627             :         }
+   16628             :     } else {
+   16629             :         nx = minmn;
+   16630             :     }
+   16631             : 
+   16632           0 :     i_1 = minmn - nx;
+   16633           0 :     i_2 = nb;
+   16634           0 :     for (i_ = 1; i_2 < 0 ? i_ >= i_1 : i_ <= i_1; i_ += i_2) {
+   16635             : 
+   16636           0 :         i_3 = *m - i_ + 1;
+   16637           0 :         i_4 = *n - i_ + 1;
+   16638           0 :         PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(&i_3, &i_4, &nb, &a[i_ + i_ * a_dim1], lda, &d__[i_], 
+   16639           0 :                 &e[i_], &tauq[i_], &taup[i_], &work[1], &ldwrkx, 
+   16640           0 :                 &work[ldwrkx * nb + 1], &ldwrky);
+   16641             : 
+   16642           0 :         i_3 = *m - i_ - nb + 1;
+   16643           0 :         i_4 = *n - i_ - nb + 1;
+   16644           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "T", &i_3, &i_4, &nb, &minusone, 
+   16645           0 :                &a[i_ + nb + i_ * a_dim1], lda, &work[ldwrkx * nb + nb + 1],
+   16646           0 :                &ldwrky, &one, &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16647           0 :         i_3 = *m - i_ - nb + 1;
+   16648           0 :         i_4 = *n - i_ - nb + 1;
+   16649           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &i_3, &i_4, &nb, &minusone, &work[nb + 1], &ldwrkx,
+   16650           0 :                &a[i_ + (i_ + nb) * a_dim1], lda, &one, 
+   16651           0 :                &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16652             : 
+   16653           0 :         if (*m >= *n) {
+   16654           0 :             i_3 = i_ + nb - 1;
+   16655           0 :             for (j = i_; j <= i_3; ++j) {
+   16656           0 :                 a[j + j * a_dim1] = d__[j];
+   16657           0 :                 a[j + (j + 1) * a_dim1] = e[j];
+   16658             :             }
+   16659             :         } else {
+   16660           0 :             i_3 = i_ + nb - 1;
+   16661           0 :             for (j = i_; j <= i_3; ++j) {
+   16662           0 :                 a[j + j * a_dim1] = d__[j];
+   16663           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   16664             :             }
+   16665             :         }
+   16666             :     }
+   16667             : 
+   16668           0 :     i_2 = *m - i_ + 1;
+   16669           0 :     i_1 = *n - i_ + 1;
+   16670           0 :     PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
+   16671           0 :             tauq[i_], &taup[i_], &work[1], &iinfo);
+   16672           0 :     work[1] = ws;
+   16673           0 :     return;
+   16674             : 
+   16675             : }
+   16676             : }
+   16677             : }
+   16678             : #include "lapack.h"
+   16679             : 
+   16680             : #include "blas/blas.h"
+   16681             : namespace PLMD{
+   16682             : namespace lapack{
+   16683             : using namespace blas;
+   16684             : void 
+   16685           0 : PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(int *m, 
+   16686             :                         int *n, 
+   16687             :                         float *a,
+   16688             :                         int *lda, 
+   16689             :                         float *tau, 
+   16690             :                         float *work, 
+   16691             :                         int *info)
+   16692             : {
+   16693             :     /* System generated locals */
+   16694             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16695             : 
+   16696             :     /* Local variables */
+   16697             :     int i__, k;
+   16698             :     float aii;
+   16699             : 
+   16700           0 :     a_dim1 = *lda;
+   16701           0 :     a_offset = 1 + a_dim1;
+   16702           0 :     a -= a_offset;
+   16703           0 :     --tau;
+   16704             :     --work;
+   16705             : 
+   16706           0 :     *info = 0;
+   16707             :     
+   16708           0 :     i__4 = (*m > 1) ? *m : 1;
+   16709             :     
+   16710           0 :     if (*m < 0) {
+   16711           0 :         *info = -1;
+   16712           0 :     } else if (*n < 0) {
+   16713           0 :         *info = -2;
+   16714           0 :     } else if (*lda < i__4) {
+   16715           0 :         *info = -4;
+   16716             :     }
+   16717           0 :     if (*info != 0) {
+   16718             :         return;
+   16719             :     }
+   16720             : 
+   16721             :     
+   16722           0 :     k = (*m < *n ) ? *m : *n;
+   16723             :     i__1 = k;
+   16724           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16725           0 :         i__2 = *n - i__ + 1;
+   16726           0 :         i__3 = i__ + 1;
+   16727             :     i__4 = (i__3 < *n) ? i__3 : *n;
+   16728           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__ + i__4 * a_dim1],
+   16729           0 :             lda, &tau[i__]);
+   16730           0 :         if (i__ < *m) {
+   16731           0 :             aii = a[i__ + i__ * a_dim1];
+   16732           0 :             a[i__ + i__ * a_dim1] = 1.f;
+   16733           0 :             i__2 = *m - i__;
+   16734           0 :             i__3 = *n - i__ + 1;
+   16735           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__2, &i__3, &a[i__ + i__ * a_dim1], lda, 
+   16736           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   16737           0 :             a[i__ + i__ * a_dim1] = aii;
+   16738             :         }
+   16739             :     }
+   16740             :     return;
+   16741             : }
+   16742             : 
+   16743             : 
+   16744             : }
+   16745             : }
+   16746             : #include <cmath>
+   16747             : #include "lapack.h"
+   16748             : #include "lapack_limits.h"
+   16749             : 
+   16750             : 
+   16751             : 
+   16752             : #include "blas/blas.h"
+   16753             : namespace PLMD{
+   16754             : namespace lapack{
+   16755             : using namespace blas;
+   16756             : void
+   16757           0 : PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(int *m,
+   16758             :         int *n, 
+   16759             :         float *a, 
+   16760             :         int *lda, 
+   16761             :         float *tau,
+   16762             :         float *work, 
+   16763             :         int *lwork, 
+   16764             :         int *info)
+   16765             : {
+   16766             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16767             : 
+   16768             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16769             :     int ldwork, lwkopt;
+   16770             : 
+   16771           0 :     a_dim1 = *lda;
+   16772           0 :     a_offset = 1 + a_dim1;
+   16773           0 :     a -= a_offset;
+   16774           0 :     --tau;
+   16775             :     --work;
+   16776             : 
+   16777           0 :     *info = 0;
+   16778             :     nb = DGELQF_BLOCKSIZE;
+   16779           0 :     lwkopt = *m * nb;
+   16780           0 :     work[1] = (float) lwkopt;
+   16781             : 
+   16782           0 :     if (*lwork==-1) {
+   16783             :         return;
+   16784             :     }
+   16785             : 
+   16786           0 :     k =(*m < *n) ? *m : *n;
+   16787           0 :     if (k == 0) {
+   16788           0 :         work[1] = 1.;
+   16789           0 :         return;
+   16790             :     }
+   16791             : 
+   16792             :     nbmin = 2;
+   16793             :     nx = 0;
+   16794             :     iws = *m;
+   16795           0 :     if (nb > 1 && nb < k) {
+   16796             :         nx = DGELQF_CROSSOVER;
+   16797           0 :         if (nx < k) {
+   16798           0 :             ldwork = *m;
+   16799           0 :             iws = ldwork * nb;
+   16800           0 :             if (*lwork < iws) {
+   16801             : 
+   16802           0 :                 nb = *lwork / ldwork;
+   16803             :                 nbmin = DGELQF_MINBLOCKSIZE;
+   16804             :             }
+   16805             :         }
+   16806             :     }
+   16807             : 
+   16808           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16809             : 
+   16810           0 :         i__1 = k - nx;
+   16811           0 :         i__2 = nb;
+   16812           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16813           0 :             i__3 = k - i__ + 1;
+   16814           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16815             : 
+   16816           0 :             i__3 = *n - i__ + 1;
+   16817           0 :             PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&ib, &i__3, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16818             :                     1], &iinfo);
+   16819           0 :             if (i__ + ib <= *m) {
+   16820             : 
+   16821           0 :                 i__3 = *n - i__ + 1;
+   16822           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__3, &ib, &a[i__ + i__ * 
+   16823             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16824             : 
+   16825           0 :                 i__3 = *m - i__ - ib + 1;
+   16826           0 :                 i__4 = *n - i__ + 1;
+   16827           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "No transpose", "Forward", "Rowwise", &i__3, 
+   16828             :                         &i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16829           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   16830           0 :                         1], &ldwork);
+   16831             :             }
+   16832             :         }
+   16833             :     } else {
+   16834             :         i__ = 1;
+   16835             :     }
+   16836             : 
+   16837           0 :     if (i__ <= k) {
+   16838           0 :         i__2 = *m - i__ + 1;
+   16839           0 :         i__1 = *n - i__ + 1;
+   16840           0 :         PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16841             :                 , &iinfo);
+   16842             :     }
+   16843             : 
+   16844           0 :     work[1] = (float) iws;
+   16845           0 :     return;
+   16846             : 
+   16847             : }
+   16848             : }
+   16849             : }
+   16850             : #include "lapack.h"
+   16851             : 
+   16852             : 
+   16853             : #include "blas/blas.h"
+   16854             : namespace PLMD{
+   16855             : namespace lapack{
+   16856             : using namespace blas;
+   16857             : void
+   16858           0 : PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(int *m,
+   16859             :         int *n,
+   16860             :         float *a,
+   16861             :         int *lda,
+   16862             :         float *tau,
+   16863             :         float *work,
+   16864             :         int *info)
+   16865             : {
+   16866           0 :   int k = (*m < *n) ? *m : *n;
+   16867             :   int i,i1,i2,i3;
+   16868             :   float aii;
+   16869             : 
+   16870           0 :   *info = 0;
+   16871             :   
+   16872           0 :   for(i=0;i<k;i++) {
+   16873           0 :     i1 = *m - i;
+   16874           0 :     i2 = ( (i+1) < (*m-1) ) ? (i+1) : (*m-1);
+   16875           0 :     i3 = 1;
+   16876           0 :     PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tau[i]));
+   16877           0 :     if(i<(*n-1)) {
+   16878           0 :       aii = a[i*(*lda)+i];
+   16879           0 :       a[i*(*lda)+i] = 1.0;
+   16880           0 :       i2 = *n - i - 1;
+   16881           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tau[i]),
+   16882           0 :              &(a[(i+1)*(*lda)+i]),lda,work);
+   16883           0 :       a[i*(*lda)+i] = aii;
+   16884             :     }
+   16885             :   }
+   16886           0 :   return;
+   16887             : }
+   16888             : }
+   16889             : }
+   16890             : #include "lapack.h"
+   16891             : #include "lapack_limits.h"
+   16892             : 
+   16893             : #include "blas/blas.h"
+   16894             : namespace PLMD{
+   16895             : namespace lapack{
+   16896             : using namespace blas;
+   16897             : void 
+   16898           0 : PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(int *m, 
+   16899             :         int *n, 
+   16900             :         float *a, 
+   16901             :         int *lda, 
+   16902             :         float *tau,
+   16903             :         float *work, 
+   16904             :         int *lwork, 
+   16905             :         int *info)
+   16906             : {
+   16907             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16908             : 
+   16909             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16910             :     int ldwork, lwkopt;
+   16911             : 
+   16912           0 :     a_dim1 = *lda;
+   16913           0 :     a_offset = 1 + a_dim1;
+   16914           0 :     a -= a_offset;
+   16915           0 :     --tau;
+   16916             :     --work;
+   16917             : 
+   16918           0 :     *info = 0;
+   16919             :     nb = DGEQRF_BLOCKSIZE;
+   16920           0 :     lwkopt = *n * nb;
+   16921           0 :     work[1] = (float) lwkopt;
+   16922           0 :         if (*lwork==-1)
+   16923             :         return;
+   16924             :     
+   16925             : 
+   16926           0 :     k = (*m < *n) ? *m : *n;
+   16927           0 :     if (k == 0) {
+   16928           0 :         work[1] = 1.;
+   16929           0 :         return;
+   16930             :     }
+   16931             : 
+   16932             :     nbmin = 2;
+   16933             :     nx = 0;
+   16934             :     iws = *n;
+   16935           0 :     if (nb > 1 && nb < k) {
+   16936             :         
+   16937             :       nx = DGEQRF_CROSSOVER;
+   16938           0 :         if (nx < k) {
+   16939             : 
+   16940           0 :             ldwork = *n;
+   16941           0 :             iws = ldwork * nb;
+   16942           0 :             if (*lwork < iws) {
+   16943             : 
+   16944           0 :                 nb = *lwork / ldwork;
+   16945             :                 nbmin = DGEQRF_MINBLOCKSIZE;
+   16946             :             }
+   16947             :         }
+   16948             :     }
+   16949             : 
+   16950           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16951           0 :         i__1 = k - nx;
+   16952           0 :         i__2 = nb;
+   16953           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16954             : 
+   16955           0 :             i__3 = k - i__ + 1;
+   16956           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16957             : 
+   16958           0 :             i__3 = *m - i__ + 1;
+   16959           0 :             PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__3, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16960             :                     1], &iinfo);
+   16961           0 :             if (i__ + ib <= *n) {
+   16962             : 
+   16963           0 :                 i__3 = *m - i__ + 1;
+   16964           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__3, &ib, &a[i__ + i__ * 
+   16965             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16966             : 
+   16967           0 :                 i__3 = *m - i__ + 1;
+   16968           0 :                 i__4 = *n - i__ - ib + 1;
+   16969           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "Transpose", "Forward", "Columnwise", &i__3, &
+   16970             :                         i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16971           0 :                         ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &work[ib 
+   16972           0 :                         + 1], &ldwork);
+   16973             :             }
+   16974             :         }
+   16975             :     } else {
+   16976             :         i__ = 1;
+   16977             :     }
+   16978             : 
+   16979           0 :     if (i__ <= k) {
+   16980           0 :         i__2 = *m - i__ + 1;
+   16981           0 :         i__1 = *n - i__ + 1;
+   16982           0 :         PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16983             :                 , &iinfo);
+   16984             :     }
+   16985             : 
+   16986           0 :     work[1] = (float) iws;
+   16987           0 :     return;
+   16988             : 
+   16989             : } 
+   16990             : 
+   16991             : }
+   16992             : }
+   16993             : #include <cmath>
+   16994             : #include "real.h"
+   16995             : 
+   16996             : 
+   16997             : #include "blas/blas.h"
+   16998             : #include "lapack.h"
+   16999             : #include "lapack_limits.h"
+   17000             : 
+   17001             : #include "blas/blas.h"
+   17002             : namespace PLMD{
+   17003             : namespace lapack{
+   17004             : using namespace blas;
+   17005             : void
+   17006           0 : PLUMED_BLAS_F77_FUNC(sgesdd,SGESDD)(const char *jobz, 
+   17007             :                         int *m, 
+   17008             :                         int *n, 
+   17009             :                         float *a, 
+   17010             :                         int *lda, 
+   17011             :                         float *s,
+   17012             :                         float *u, 
+   17013             :                         int *ldu, 
+   17014             :                         float *vt, 
+   17015             :                         int *ldvt, 
+   17016             :                         float *work,
+   17017             :                         int *lwork, 
+   17018             :                         int *iwork, 
+   17019             :                         int *info)
+   17020             : {
+   17021             :     int a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   17022             : 
+   17023             :     int ie, iu;
+   17024             :     float dum[1], eps;
+   17025             :     int ivt, iscl;
+   17026             :     float anrm;
+   17027             :     int idum[1], ierr, itau;
+   17028             :     int minmn, wrkbl, itaup, itauq, mnthr;
+   17029             :     int nwork;
+   17030             :     int wntqn;
+   17031             :     int bdspac;
+   17032             :     float bignum;
+   17033             :     int ldwrku, maxwrk, ldwkvt;
+   17034             :     float smlnum,minval, safemin;
+   17035             :     int lquery;
+   17036           0 :     int c__0 = 0;
+   17037           0 :     int c__1 = 1;
+   17038           0 :     float zero = 0.0;
+   17039           0 :     float one = 1.0;
+   17040             : 
+   17041             : 
+   17042           0 :     a_dim1 = *lda;
+   17043           0 :     a_offset = 1 + a_dim1;
+   17044           0 :     a -= a_offset;
+   17045             :     --s;
+   17046           0 :     u_dim1 = *ldu;
+   17047           0 :     u_offset = 1 + u_dim1;
+   17048           0 :     u -= u_offset;
+   17049           0 :     vt_dim1 = *ldvt;
+   17050           0 :     vt_offset = 1 + vt_dim1;
+   17051           0 :     vt -= vt_offset;
+   17052           0 :     --work;
+   17053             :     --iwork;
+   17054             : 
+   17055           0 :     *info = 0;
+   17056           0 :     minmn = (*m < *n) ? *m : *n;
+   17057           0 :     mnthr = (int) (minmn * 11. / 6.);
+   17058           0 :     wntqn = (*jobz=='o' || *jobz=='O');
+   17059             : 
+   17060             :     maxwrk = 1;
+   17061           0 :     lquery = *lwork == -1;
+   17062             : 
+   17063           0 :     if (*info == 0 && *m > 0 && *n > 0) {
+   17064           0 :         if (*m >= *n) {
+   17065             : 
+   17066           0 :             if (wntqn) {
+   17067           0 :                 bdspac = *n * 7;
+   17068             :             } else {
+   17069           0 :                 bdspac = *n * 3 * *n + (*n << 2);
+   17070             :             }
+   17071           0 :             if (*m >= mnthr) {
+   17072           0 :                 if (wntqn) {
+   17073             : 
+   17074           0 :                     wrkbl = *n * 67;
+   17075           0 :                     i__1 = wrkbl, i__2 = bdspac + *n;
+   17076             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17077             :                 } else {
+   17078             : 
+   17079           0 :                     wrkbl = *n * 67;
+   17080           0 :                     i__1 = wrkbl, i__2 = *n + (*m << 5);
+   17081             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17082           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17083             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17084           0 :                     maxwrk = wrkbl + *n * *n;
+   17085             :                 }
+   17086             :             } else {
+   17087             : 
+   17088           0 :                 wrkbl = *n * 3 + (*m + *n*32);
+   17089           0 :                 if (wntqn) {
+   17090           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17091             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17092             :                 } else {
+   17093           0 :                     i__1 = maxwrk, i__2 = bdspac + *n * 3;
+   17094             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17095             :                 }
+   17096             :             }
+   17097             :         } else {
+   17098             : 
+   17099           0 :             if (wntqn) {
+   17100           0 :                 bdspac = *m * 7;
+   17101             :             } else {
+   17102           0 :                 bdspac = *m * 3 * *m + (*m*4);
+   17103             :             }
+   17104           0 :             if (*n >= mnthr) {
+   17105           0 :                 if (wntqn) {
+   17106             : 
+   17107           0 :                     wrkbl = *m * 67;
+   17108           0 :                     i__1 = wrkbl, i__2 = bdspac + *m;
+   17109             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17110             :                 } else {
+   17111             : 
+   17112           0 :                     wrkbl = *m * 67;
+   17113           0 :                     i__1 = wrkbl, i__2 = *m + (*n*32);
+   17114             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17115             : 
+   17116           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17117             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17118           0 :                     maxwrk = wrkbl + *m * *m;
+   17119             :                 }
+   17120             :             } else {
+   17121           0 :                 wrkbl = *m * 3 + (*m + *n*32);
+   17122           0 :                 if (wntqn) {
+   17123           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17124             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17125             :                 } else {
+   17126           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17127             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17128             :                 }
+   17129             :             }
+   17130             :         }
+   17131           0 :         work[1] = (float) maxwrk;
+   17132             :     }
+   17133             :     
+   17134           0 :     if( lquery != 0)
+   17135             :     {
+   17136             :         return;
+   17137             :     }
+   17138             :     
+   17139           0 :     if (*m == 0 || *n == 0) {
+   17140           0 :         if (*lwork >= 1) {
+   17141           0 :             work[1] = 1.;
+   17142             :         }
+   17143           0 :         return;
+   17144             :     }
+   17145             :     eps = PLUMED_GMX_FLOAT_EPS;
+   17146             :     minval = PLUMED_GMX_FLOAT_MIN;
+   17147             :     safemin = minval / eps;
+   17148           0 :     smlnum =  std::sqrt(safemin) / eps;
+   17149             : 
+   17150             : 
+   17151           0 :     bignum = 1. / smlnum;
+   17152             : 
+   17153             : 
+   17154           0 :     anrm = PLUMED_BLAS_F77_FUNC(slange,SLANGE)("M", m, n, &a[a_offset], lda, dum);
+   17155             :     iscl = 0;
+   17156           0 :     if (anrm > 0. && anrm < smlnum) {
+   17157             :         iscl = 1;
+   17158           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&smlnum,m,n,&a[a_offset],lda,&ierr);
+   17159           0 :     } else if (anrm > bignum) {
+   17160             :         iscl = 1;
+   17161           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&bignum,m,n,&a[a_offset],lda,&ierr);
+   17162             :     }
+   17163             : 
+   17164           0 :     if (*m >= *n) {
+   17165           0 :         if (*m >= mnthr) {
+   17166             : 
+   17167           0 :             if (wntqn) {
+   17168             : 
+   17169             :                 itau = 1;
+   17170           0 :                 nwork = itau + *n;
+   17171             : 
+   17172           0 :                 i__1 = *lwork - nwork + 1;
+   17173           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17174             :                         i__1, &ierr);
+   17175             : 
+   17176           0 :                 i__1 = *n - 1;
+   17177           0 :                 i__2 = *n - 1;
+   17178           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17179             :                         lda);
+   17180             :                 ie = 1;
+   17181           0 :                 itauq = ie + *n;
+   17182           0 :                 itaup = itauq + *n;
+   17183           0 :                 nwork = itaup + *n;
+   17184             : 
+   17185           0 :                 i__1 = *lwork - nwork + 1;
+   17186           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17187           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17188           0 :                 nwork = ie + *n;
+   17189             : 
+   17190           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17191           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17192             : 
+   17193             :             } else {
+   17194             :                 iu = 1;
+   17195             : 
+   17196           0 :                 ldwrku = *n;
+   17197           0 :                 itau = iu + ldwrku * *n;
+   17198           0 :                 nwork = itau + *n;
+   17199             : 
+   17200           0 :                 i__1 = *lwork - nwork + 1;
+   17201           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17202             :                         i__1, &ierr);
+   17203           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17204             : 
+   17205           0 :                 i__1 = *lwork - nwork + 1;
+   17206           0 :                 PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
+   17207             :                          &i__1, &ierr);
+   17208             : 
+   17209           0 :                 i__1 = *n - 1;
+   17210           0 :                 i__2 = *n - 1;
+   17211           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17212             :                         lda);
+   17213             :                 ie = itau;
+   17214           0 :                 itauq = ie + *n;
+   17215           0 :                 itaup = itauq + *n;
+   17216           0 :                 nwork = itaup + *n;
+   17217             : 
+   17218           0 :                 i__1 = *lwork - nwork + 1;
+   17219           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17220           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17221             : 
+   17222           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
+   17223             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17224             :                         info);
+   17225             : 
+   17226           0 :                 i__1 = *lwork - nwork + 1;
+   17227           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
+   17228             :                         itauq], &work[iu], &ldwrku, &work[nwork], &i__1, &
+   17229             :                         ierr);
+   17230           0 :                 i__1 = *lwork - nwork + 1;
+   17231           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
+   17232             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17233             :                         ierr);
+   17234             : 
+   17235           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, n, &one, &u[u_offset], ldu, &work[iu]
+   17236             :                         , &ldwrku, &zero, &a[a_offset], lda);
+   17237             : 
+   17238           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17239             : 
+   17240             :             }
+   17241             : 
+   17242             :         } else {
+   17243             :             ie = 1;
+   17244           0 :             itauq = ie + *n;
+   17245           0 :             itaup = itauq + *n;
+   17246           0 :             nwork = itaup + *n;
+   17247             : 
+   17248           0 :             i__1 = *lwork - nwork + 1;
+   17249           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17250           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17251           0 :             if (wntqn) {
+   17252             : 
+   17253           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17254             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17255             :             } else {
+   17256             : 
+   17257           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", m, m, &zero, &zero, &u[u_offset], ldu);
+   17258           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17259             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17260             :                         info);
+   17261             : 
+   17262           0 :                 i__1 = *m - *n;
+   17263           0 :                 i__2 = *m - *n;
+   17264           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &u[*n + 1 + (*n + 
+   17265           0 :                         1) * u_dim1], ldu);
+   17266             : 
+   17267           0 :                 i__1 = *lwork - nwork + 1;
+   17268           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17269             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17270           0 :                 i__1 = *lwork - nwork + 1;
+   17271           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17272             :                         itaup], &vt[vt_offset],ldvt,&work[nwork],&i__1,&ierr);
+   17273             :             }
+   17274             : 
+   17275             :         }
+   17276             : 
+   17277             :     } else {
+   17278             : 
+   17279           0 :         if (*n >= mnthr) {
+   17280             : 
+   17281           0 :             if (wntqn) {
+   17282             : 
+   17283             :                 itau = 1;
+   17284           0 :                 nwork = itau + *m;
+   17285             : 
+   17286           0 :                 i__1 = *lwork - nwork + 1;
+   17287           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17288             :                         i__1, &ierr);
+   17289             : 
+   17290           0 :                 i__1 = *m - 1;
+   17291           0 :                 i__2 = *m - 1;
+   17292           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17293           0 :                         1], lda);
+   17294             :                 ie = 1;
+   17295           0 :                 itauq = ie + *m;
+   17296           0 :                 itaup = itauq + *m;
+   17297           0 :                 nwork = itaup + *m;
+   17298             : 
+   17299           0 :                 i__1 = *lwork - nwork + 1;
+   17300           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17301           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17302           0 :                 nwork = ie + *m;
+   17303             : 
+   17304           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17305           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17306             : 
+   17307             :             } else {
+   17308             : 
+   17309             :                 ivt = 1;
+   17310             : 
+   17311           0 :                 ldwkvt = *m;
+   17312           0 :                 itau = ivt + ldwkvt * *m;
+   17313           0 :                 nwork = itau + *m;
+   17314             : 
+   17315           0 :                 i__1 = *lwork - nwork + 1;
+   17316           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17317             :                         i__1, &ierr);
+   17318           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17319             : 
+   17320           0 :                 i__1 = *lwork - nwork + 1;
+   17321           0 :                 PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
+   17322             :                         nwork], &i__1, &ierr);
+   17323             : 
+   17324           0 :                 i__1 = *m - 1;
+   17325           0 :                 i__2 = *m - 1;
+   17326           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17327           0 :                         1], lda);
+   17328             :                 ie = itau;
+   17329           0 :                 itauq = ie + *m;
+   17330           0 :                 itaup = itauq + *m;
+   17331           0 :                 nwork = itaup + *m;
+   17332             : 
+   17333           0 :                 i__1 = *lwork - nwork + 1;
+   17334           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17335           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17336             : 
+   17337           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
+   17338             :                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
+   17339             :                         , info);
+   17340             : 
+   17341           0 :                 i__1 = *lwork - nwork + 1;
+   17342           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
+   17343             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17344           0 :                 i__1 = *lwork - nwork + 1;
+   17345           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
+   17346             :                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__1, &
+   17347             :                         ierr);
+   17348             : 
+   17349           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, m, &one, &work[ivt], &ldwkvt, &vt[
+   17350             :                         vt_offset], ldvt, &zero, &a[a_offset], lda);
+   17351             : 
+   17352           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17353             : 
+   17354             :             }
+   17355             : 
+   17356             :         } else {
+   17357             : 
+   17358             :             ie = 1;
+   17359           0 :             itauq = ie + *m;
+   17360           0 :             itaup = itauq + *m;
+   17361           0 :             nwork = itaup + *m;
+   17362             : 
+   17363           0 :             i__1 = *lwork - nwork + 1;
+   17364           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17365           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17366           0 :             if (wntqn) {
+   17367             : 
+   17368           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17369             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17370             :             } else {
+   17371           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", n, n, &zero, &zero, &vt[vt_offset], ldvt);
+   17372           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17373             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17374             :                         info);
+   17375             : 
+   17376           0 :                 i__1 = *n - *m;
+   17377           0 :                 i__2 = *n - *m;
+   17378           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &vt[*m + 1 + (*m + 
+   17379           0 :                         1) * vt_dim1], ldvt);
+   17380             : 
+   17381           0 :                 i__1 = *lwork - nwork + 1;
+   17382           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17383             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17384           0 :                 i__1 = *lwork - nwork + 1;
+   17385           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17386             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17387             :                         ierr);
+   17388             :             }
+   17389             : 
+   17390             :         }
+   17391             : 
+   17392             :     }
+   17393             : 
+   17394           0 :     if (iscl == 1) {
+   17395           0 :         if (anrm > bignum) {
+   17396           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
+   17397             :                     minmn, &ierr);
+   17398             :         }
+   17399           0 :         if (anrm < smlnum) {
+   17400           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
+   17401             :                     minmn, &ierr);
+   17402             :         }
+   17403             :     }
+   17404             : 
+   17405           0 :     work[1] = (float) maxwrk;
+   17406             : 
+   17407           0 :     return;
+   17408             : 
+   17409             : }
+   17410             : 
+   17411             : 
+   17412             : }
+   17413             : }
+   17414             : #include <cmath>
+   17415             : #include "real.h"
+   17416             : 
+   17417             : #include "blas/blas.h"
+   17418             : #include "lapack.h"
+   17419             : 
+   17420             : 
+   17421             : #include "blas/blas.h"
+   17422             : namespace PLMD{
+   17423             : namespace lapack{
+   17424             : using namespace blas;
+   17425             : void
+   17426           0 : PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(int *m,
+   17427             :         int *n,
+   17428             :         float *a,
+   17429             :         int *lda,
+   17430             :         int *ipiv,
+   17431             :         int *info)
+   17432             : {
+   17433             :   int j,jp,k,t1,t2,t3;
+   17434             :   float minusone;
+   17435             :   float tmp;
+   17436             : 
+   17437           0 :   minusone = -1.0;
+   17438             : 
+   17439           0 :   if(*m<=0 || *n<=0)
+   17440             :     return;
+   17441             : 
+   17442             :   k = (*m < *n) ? *m : *n;
+   17443           0 :   for(j=1;j<=k;j++) {
+   17444           0 :     t1 = *m-j+1;
+   17445           0 :     t2 = 1;
+   17446           0 :     jp = j - 1 + PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&t1,&(a[(j-1)*(*lda)+(j-1)]),&t2);
+   17447           0 :     ipiv[j-1] = jp;
+   17448           0 :     if( std::abs(a[(j-1)*(*lda)+(jp-1)])>PLUMED_GMX_FLOAT_MIN ) {
+   17449           0 :       if(jp != j)
+   17450           0 :         PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n,&(a[ j-1 ]),lda,&(a[ jp-1 ]),lda);
+   17451             :       
+   17452           0 :       if(j<*m) {
+   17453           0 :         t1 = *m-j;
+   17454           0 :         t2 = 1;
+   17455           0 :         tmp = 1.0/a[(j-1)*(*lda)+(j-1)];
+   17456           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&t1,&tmp,&(a[(j-1)*(*lda)+(j)]),&t2);
+   17457             :       }
+   17458             :     } else {
+   17459           0 :       *info = j;
+   17460             :     }
+   17461             : 
+   17462           0 :     if(j<k) {
+   17463           0 :       t1 = *m-j;
+   17464           0 :       t2 = *n-j;
+   17465           0 :       t3 = 1;
+   17466           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(&t1,&t2,&minusone,&(a[(j-1)*(*lda)+(j)]),&t3,
+   17467           0 :             &(a[(j)*(*lda)+(j-1)]),lda, &(a[(j)*(*lda)+(j)]),lda);
+   17468             :     }
+   17469             :   }
+   17470             :   return;
+   17471             : }
+   17472             : }
+   17473             : }
+   17474             : #include "blas/blas.h"
+   17475             : #include "lapack.h"
+   17476             : #include "lapack_limits.h"
+   17477             : 
+   17478             : #include "blas/blas.h"
+   17479             : namespace PLMD{
+   17480             : namespace lapack{
+   17481             : using namespace blas;
+   17482             : void
+   17483           0 : PLUMED_BLAS_F77_FUNC(sgetrf,SGETRF)(int *m,
+   17484             :         int *n,
+   17485             :         float *a,
+   17486             :         int *lda,
+   17487             :         int *ipiv,
+   17488             :         int *info)
+   17489             : {
+   17490             :   int mindim,jb;
+   17491             :   int i,j,k,l;
+   17492             :   int iinfo;
+   17493           0 :   float minusone = -1.0;
+   17494           0 :   float one = 1.0;
+   17495             : 
+   17496           0 :   if(*m<=0 || *n<=0)
+   17497           0 :     return;
+   17498             : 
+   17499           0 :   *info = 0;
+   17500             : 
+   17501           0 :   mindim = (*m < *n) ? *m : *n;
+   17502             : 
+   17503           0 :   if(DGETRF_BLOCKSIZE>=mindim) {
+   17504             : 
+   17505             :     /* unblocked code */
+   17506           0 :     PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(m,n,a,lda,ipiv,info);
+   17507             : 
+   17508             :   } else {
+   17509             : 
+   17510             :     /* blocked case */
+   17511             : 
+   17512           0 :     for(j=1;j<=mindim;j+=DGETRF_BLOCKSIZE) {
+   17513           0 :       jb = ( DGETRF_BLOCKSIZE < (mindim-j+1)) ? DGETRF_BLOCKSIZE : (mindim-j+1);
+   17514             :       /* factor diag. and subdiag blocks and test for singularity */
+   17515           0 :       k = *m-j+1;
+   17516           0 :       PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(&k,&jb,&(a[(j-1)*(*lda)+(j-1)]),lda,&(ipiv[j-1]),&iinfo);
+   17517             :       
+   17518           0 :       if(*info==0 && iinfo>0)
+   17519           0 :         *info = iinfo + j - 1;
+   17520             : 
+   17521             :       /* adjust pivot indices */
+   17522           0 :       k = (*m < (j+jb-1)) ? *m : (j+jb-1);
+   17523           0 :       for(i=j;i<=k;i++)
+   17524           0 :         ipiv[i-1] += j - 1;
+   17525             : 
+   17526             :       /* Apply to columns 1 throughj j-1 */
+   17527           0 :       k = j - 1;
+   17528           0 :       i = j + jb - 1;
+   17529           0 :       l = 1;
+   17530           0 :       PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,a,lda,&j,&i,ipiv,&l);
+   17531           0 :       if((j+jb)<=*n) {
+   17532             :         /* Apply to cols. j+jb through n */
+   17533           0 :         k = *n-j-jb+1;
+   17534           0 :         i = j+jb-1;
+   17535           0 :         l = 1;
+   17536           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,&(a[(j+jb-1)*(*lda)+0]),lda,&j,&i,ipiv,&l);
+   17537             :         /* Compute block row of U */
+   17538           0 :         k = *n-j-jb+1;
+   17539           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left","Lower","No transpose","Unit",&jb,&k,&one,
+   17540           0 :                &(a[(j-1)*(*lda)+(j-1)]),lda,&(a[(j+jb-1)*(*lda)+(j-1)]),lda);
+   17541             : 
+   17542           0 :         if((j+jb)<=*m) {
+   17543             :           /* Update trailing submatrix */
+   17544           0 :           k = *m-j-jb+1;
+   17545           0 :           i = *n-j-jb+1;
+   17546           0 :           PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose","No transpose",&k,&i,&jb,&minusone,
+   17547           0 :                  &(a[(j-1)*(*lda)+(j+jb-1)]),lda,
+   17548           0 :                  &(a[(j+jb-1)*(*lda)+(j-1)]),lda,&one,
+   17549           0 :                  &(a[(j+jb-1)*(*lda)+(j+jb-1)]),lda);
+   17550             :         }
+   17551             : 
+   17552             :       }
+   17553             :     }
+   17554             :   }
+   17555             : }
+   17556             : }
+   17557             : }
+   17558             : #include "blas/blas.h"
+   17559             : #include "lapack.h"
+   17560             : #include "lapack_limits.h"
+   17561             : 
+   17562             : #include "blas/blas.h"
+   17563             : namespace PLMD{
+   17564             : namespace lapack{
+   17565             : using namespace blas;
+   17566             : void
+   17567           0 : PLUMED_BLAS_F77_FUNC(sgetri,SGETRI)(int *n, 
+   17568             :         float *a, 
+   17569             :         int *lda, 
+   17570             :         int *ipiv, 
+   17571             :         float *work, 
+   17572             :         int *lwork, 
+   17573             :         int *info)
+   17574             : {
+   17575             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   17576             : 
+   17577             :     int i__, j, jb, nb, jj, jp, nn, iws;
+   17578             :     int nbmin;
+   17579             :     int ldwork;
+   17580             :     int lwkopt;
+   17581           0 :     int c__1 = 1;
+   17582           0 :     float c_b20 = -1.;
+   17583           0 :     float c_b22 = 1.;
+   17584             : 
+   17585           0 :     a_dim1 = *lda;
+   17586           0 :     a_offset = 1 + a_dim1;
+   17587           0 :     a -= a_offset;
+   17588             :     --ipiv;
+   17589           0 :     --work;
+   17590             : 
+   17591           0 :     *info = 0;
+   17592             :     nb = DGETRI_BLOCKSIZE;
+   17593           0 :     lwkopt = *n * nb;
+   17594           0 :     work[1] = (float) lwkopt;
+   17595             : 
+   17596           0 :     if (*n < 0) {
+   17597           0 :         *info = -1;
+   17598           0 :     } else if (*lda < (*n)) {
+   17599           0 :         *info = -3;
+   17600           0 :     } else if (*lwork < (*n) && *lwork!=-1) {
+   17601           0 :         *info = -6;
+   17602             :     }
+   17603           0 :     if (*info != 0) {
+   17604             :         i__1 = -(*info);
+   17605             :         return;
+   17606           0 :     } else if (*lwork == -1) {
+   17607             :         return;
+   17608             :     }
+   17609             : 
+   17610           0 :     if (*n == 0) {
+   17611             :         return;
+   17612             :     }
+   17613             : 
+   17614           0 :     PLUMED_BLAS_F77_FUNC(strtri,STRTRI)("Upper", "Non-unit", n, &a[a_offset], lda, info);
+   17615           0 :     if (*info > 0) {
+   17616             :         return;
+   17617             :     }
+   17618             : 
+   17619             :     nbmin = 2;
+   17620           0 :     ldwork = *n;
+   17621           0 :     if (nb > 1 && nb < *n) {
+   17622           0 :         i__1 = ldwork * nb;
+   17623           0 :         iws = (i__1>1) ? i__1 : 1;
+   17624           0 :         if (*lwork < iws) {
+   17625           0 :             nb = *lwork / ldwork;
+   17626             :             nbmin = DGETRI_MINBLOCKSIZE;
+   17627             :         }
+   17628             :     } else {
+   17629             :         iws = *n;
+   17630             :     }
+   17631             : 
+   17632           0 :     if (nb < nbmin || nb >= *n) {
+   17633             : 
+   17634           0 :         for (j = *n; j >= 1; --j) {
+   17635             : 
+   17636           0 :             i__1 = *n;
+   17637           0 :             for (i__ = j + 1; i__ <= i__1; ++i__) {
+   17638           0 :                 work[i__] = a[i__ + j * a_dim1];
+   17639           0 :                 a[i__ + j * a_dim1] = 0.;
+   17640             :             }
+   17641             : 
+   17642           0 :             if (j < *n) {
+   17643           0 :                 i__1 = *n - j;
+   17644           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1 
+   17645           0 :                         + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1 
+   17646           0 :                         + 1], &c__1);
+   17647             :             }
+   17648             :         }
+   17649             :     } else {
+   17650             : 
+   17651           0 :         nn = (*n - 1) / nb * nb + 1;
+   17652           0 :         i__1 = -nb;
+   17653           0 :         for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) {
+   17654           0 :             i__2 = nb, i__3 = *n - j + 1;
+   17655           0 :             jb = (i__2<i__3) ? i__2 : i__3;
+   17656             : 
+   17657           0 :             i__2 = j + jb - 1;
+   17658           0 :             for (jj = j; jj <= i__2; ++jj) {
+   17659           0 :                 i__3 = *n;
+   17660           0 :                 for (i__ = jj + 1; i__ <= i__3; ++i__) {
+   17661           0 :                     work[i__ + (jj - j) * ldwork] = a[i__ + jj * a_dim1];
+   17662           0 :                     a[i__ + jj * a_dim1] = 0.;
+   17663             :                 }
+   17664             :             }
+   17665             : 
+   17666           0 :             if (j + jb <= *n) {
+   17667           0 :                 i__2 = *n - j - jb + 1;
+   17668           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", n, &jb, &i__2, &c_b20, 
+   17669           0 :                         &a[(j + jb) * a_dim1 + 1], lda, &work[j + jb], &
+   17670           0 :                         ldwork, &c_b22, &a[j * a_dim1 + 1], lda);
+   17671             :             }
+   17672           0 :             PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &
+   17673           0 :                     work[j], &ldwork, &a[j * a_dim1 + 1], lda);
+   17674             :         }
+   17675             :     }
+   17676             : 
+   17677           0 :     for (j = *n - 1; j >= 1; --j) {
+   17678           0 :         jp = ipiv[j];
+   17679           0 :         if (jp != j) {
+   17680           0 :             PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &a[j * a_dim1 + 1], &c__1, &a[jp * a_dim1 + 1], &c__1);
+   17681             :         }
+   17682             :     }
+   17683             : 
+   17684           0 :     work[1] = (float) iws;
+   17685           0 :     return;
+   17686             : 
+   17687             : }
+   17688             : 
+   17689             : 
+   17690             : }
+   17691             : }
+   17692             : #include "blas/blas.h"
+   17693             : #include "lapack.h"
+   17694             : 
+   17695             : #include "blas/blas.h"
+   17696             : namespace PLMD{
+   17697             : namespace lapack{
+   17698             : using namespace blas;
+   17699             : void
+   17700           0 : PLUMED_BLAS_F77_FUNC(sgetrs,SGETRS)(const char *trans, 
+   17701             :         int *n, 
+   17702             :         int *nrhs, 
+   17703             :         float *a, 
+   17704             :         int *lda, 
+   17705             :         int *ipiv,
+   17706             :         float *b, 
+   17707             :         int *ldb, 
+   17708             :         int *info)
+   17709             : {
+   17710             :     int a_dim1, a_offset, b_dim1, b_offset;
+   17711             :     int notran;
+   17712           0 :     int c__1 = 1;
+   17713           0 :     int c_n1 = -1;
+   17714           0 :     float one = 1.0;
+   17715             : 
+   17716             :     a_dim1 = *lda;
+   17717             :     a_offset = 1 + a_dim1;
+   17718             :     a -= a_offset;
+   17719             :     --ipiv;
+   17720             :     b_dim1 = *ldb;
+   17721             :     b_offset = 1 + b_dim1;
+   17722             :     b -= b_offset;
+   17723             : 
+   17724           0 :     *info = 0;
+   17725           0 :     notran = (*trans=='N' || *trans=='n');
+   17726             : 
+   17727           0 :     if (*n <= 0 || *nrhs <= 0) 
+   17728             :         return;
+   17729             : 
+   17730           0 :     if (notran) {
+   17731           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1);
+   17732           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "No transpose", "Unit", n, nrhs, &one, 
+   17733             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17734             : 
+   17735           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &one, 
+   17736             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17737             :     } else {
+   17738           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &one, 
+   17739             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17740           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "Transpose", "Unit", n, nrhs, &one, 
+   17741             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17742             : 
+   17743           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1);
+   17744             :     }
+   17745             : 
+   17746             :     return;
+   17747             : 
+   17748             : } 
+   17749             : }
+   17750             : }
+   17751             : #include <cmath>
+   17752             : #include "blas/blas.h"
+   17753             : #include "lapack.h"
+   17754             : 
+   17755             : 
+   17756             : #include "blas/blas.h"
+   17757             : namespace PLMD{
+   17758             : namespace lapack{
+   17759             : using namespace blas;
+   17760             : void 
+   17761           0 : PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(int *m, 
+   17762             :         int *n, 
+   17763             :         int *nb,
+   17764             :         float *a, 
+   17765             :         int *lda, 
+   17766             :         float *d__,
+   17767             :         float *e,
+   17768             :         float *tauq, 
+   17769             :         float *taup,
+   17770             :         float *x,
+   17771             :         int *ldx,
+   17772             :         float *y,
+   17773             :         int *ldy)
+   17774             : {
+   17775             :     int a_dim1, a_offset, x_dim1, x_offset, y_dim1, y_offset;
+   17776             :     int i__1, i__2, i__3;
+   17777           0 :     float one = 1.0;
+   17778           0 :     float minusone = -1.0;
+   17779           0 :     float zero = 0.0;
+   17780           0 :     int c__1 = 1;
+   17781             :     int i__;
+   17782             : 
+   17783           0 :     a_dim1 = *lda;
+   17784           0 :     a_offset = 1 + a_dim1;
+   17785           0 :     a -= a_offset;
+   17786           0 :     --d__;
+   17787           0 :     --e;
+   17788           0 :     --tauq;
+   17789           0 :     --taup;
+   17790           0 :     x_dim1 = *ldx;
+   17791           0 :     x_offset = 1 + x_dim1;
+   17792           0 :     x -= x_offset;
+   17793           0 :     y_dim1 = *ldy;
+   17794           0 :     y_offset = 1 + y_dim1;
+   17795           0 :     y -= y_offset;
+   17796             : 
+   17797           0 :     if (*m <= 0 || *n <= 0) {
+   17798             :         return;
+   17799             :     }
+   17800             : 
+   17801           0 :     if (*m >= *n) {
+   17802             : 
+   17803           0 :         i__1 = *nb;
+   17804           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17805             : 
+   17806           0 :             i__2 = *m - i__ + 1;
+   17807           0 :             i__3 = i__ - 1;
+   17808           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + a_dim1], lda,
+   17809           0 :                      &y[i__ + y_dim1], ldy, &one, &a[i__ + i__ * a_dim1], &c__1);
+   17810           0 :             i__2 = *m - i__ + 1;
+   17811           0 :             i__3 = i__ - 1;
+   17812           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + x_dim1], ldx,
+   17813           0 :                    &a[i__*a_dim1+1],&c__1,&one,&a[i__+i__*a_dim1],&c__1);
+   17814             : 
+   17815           0 :             i__2 = *m - i__ + 1;
+   17816           0 :             i__3 = i__ + 1;
+   17817           0 :             if(*m<i__3)
+   17818           0 :               i__3 = *m;
+   17819           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__3 + i__ * a_dim1], 
+   17820           0 :                     &c__1, &tauq[i__]);
+   17821           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17822           0 :             if (i__ < *n) {
+   17823           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17824             : 
+   17825           0 :                 i__2 = *m - i__ + 1;
+   17826           0 :                 i__3 = *n - i__;
+   17827           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + (i__ + 1) * 
+   17828           0 :                         a_dim1], lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &
+   17829           0 :                         y[i__ + 1 + i__ * y_dim1], &c__1);
+   17830           0 :                 i__2 = *m - i__ + 1;
+   17831           0 :                 i__3 = i__ - 1;
+   17832           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + a_dim1], 
+   17833           0 :                         lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17834           0 :                         y_dim1 + 1], &c__1);
+   17835           0 :                 i__2 = *n - i__;
+   17836           0 :                 i__3 = i__ - 1;
+   17837           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17838           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17839           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17840           0 :                 i__2 = *m - i__ + 1;
+   17841           0 :                 i__3 = i__ - 1;
+   17842           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &x[i__ + x_dim1], 
+   17843           0 :                         ldx, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17844           0 :                         y_dim1 + 1], &c__1);
+   17845           0 :                 i__2 = i__ - 1;
+   17846           0 :                 i__3 = *n - i__;
+   17847           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17848           0 :                         a_dim1 + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, 
+   17849           0 :                         &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17850           0 :                 i__2 = *n - i__;
+   17851           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17852             : 
+   17853           0 :                 i__2 = *n - i__;
+   17854           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &y[i__ + 1 + 
+   17855           0 :                         y_dim1], ldy, &a[i__ + a_dim1], lda, &one, &a[i__ + (
+   17856           0 :                         i__ + 1) * a_dim1], lda);
+   17857           0 :                 i__2 = i__ - 1;
+   17858           0 :                 i__3 = *n - i__;
+   17859           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17860           0 :                         a_dim1 + 1], lda, &x[i__ + x_dim1], ldx, &one, &a[
+   17861           0 :                         i__ + (i__ + 1) * a_dim1], lda);
+   17862             : 
+   17863           0 :                 i__2 = *n - i__;
+   17864           0 :                 i__3 = i__ + 2;
+   17865           0 :                 if(*n<i__3)
+   17866           0 :                   i__3 = *n;
+   17867           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + (i__ + 1) * a_dim1], 
+   17868           0 :                         &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17869           0 :                 e[i__] = a[i__ + (i__ + 1) * a_dim1];
+   17870           0 :                 a[i__ + (i__ + 1) * a_dim1] = 1.;
+   17871             : 
+   17872           0 :                 i__2 = *m - i__;
+   17873           0 :                 i__3 = *n - i__;
+   17874           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ 
+   17875           0 :                         + 1) * a_dim1], lda, &a[i__ + (i__ + 1) * a_dim1], 
+   17876           0 :                         lda, &zero, &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17877           0 :                 i__2 = *n - i__;
+   17878           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &y[i__ + 1 + y_dim1], 
+   17879           0 :                         ldy, &a[i__ + (i__ + 1) * a_dim1], lda, &zero, &x[
+   17880           0 :                         i__ * x_dim1 + 1], &c__1);
+   17881           0 :                 i__2 = *m - i__;
+   17882           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &a[i__ + 1 + 
+   17883           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17884           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17885           0 :                 i__2 = i__ - 1;
+   17886           0 :                 i__3 = *n - i__;
+   17887           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[(i__ + 1) * 
+   17888           0 :                         a_dim1 + 1], lda, &a[i__ + (i__ + 1) * a_dim1], lda, &
+   17889           0 :                         zero, &x[i__ * x_dim1 + 1], &c__1);
+   17890           0 :                 i__2 = *m - i__;
+   17891           0 :                 i__3 = i__ - 1;
+   17892           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17893           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17894           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17895           0 :                 i__2 = *m - i__;
+   17896           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17897             :             }
+   17898             :         }
+   17899             :     } else {
+   17900             : 
+   17901           0 :         i__1 = *nb;
+   17902           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17903             : 
+   17904           0 :             i__2 = *n - i__ + 1;
+   17905           0 :             i__3 = i__ - 1;
+   17906           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + y_dim1], ldy,
+   17907           0 :                      &a[i__ + a_dim1], lda, &one, &a[i__ + i__ * a_dim1],lda);
+   17908           0 :             i__2 = i__ - 1;
+   17909           0 :             i__3 = *n - i__ + 1;
+   17910           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[i__ * a_dim1 + 1], 
+   17911           0 :                     lda, &x[i__ + x_dim1], ldx, &one,&a[i__+i__*a_dim1],lda);
+   17912             : 
+   17913           0 :             i__2 = *n - i__ + 1;
+   17914           0 :             i__3 = i__ + 1;
+   17915           0 :             if(*n<i__3)
+   17916           0 :               i__3 = *n;
+   17917           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], 
+   17918           0 :                     &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17919           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17920           0 :             if (i__ < *m) {
+   17921           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17922             : 
+   17923           0 :                 i__2 = *m - i__;
+   17924           0 :                 i__3 = *n - i__ + 1;
+   17925           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose",&i__2,&i__3,&one,&a[i__+1+i__*a_dim1], 
+   17926             :                        lda, &a[i__ + i__ * a_dim1], lda, &zero, 
+   17927           0 :                        &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17928           0 :                 i__2 = *n - i__ + 1;
+   17929           0 :                 i__3 = i__ - 1;
+   17930           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &y[i__ + y_dim1], 
+   17931           0 :                         ldy, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ * 
+   17932           0 :                         x_dim1 + 1], &c__1);
+   17933           0 :                 i__2 = *m - i__;
+   17934           0 :                 i__3 = i__ - 1;
+   17935           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17936           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17937           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17938           0 :                 i__2 = i__ - 1;
+   17939           0 :                 i__3 = *n - i__ + 1;
+   17940           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ * a_dim1 + 
+   17941           0 :                         1], lda, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ *
+   17942           0 :                          x_dim1 + 1], &c__1);
+   17943           0 :                 i__2 = *m - i__;
+   17944           0 :                 i__3 = i__ - 1;
+   17945           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17946           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17947           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17948           0 :                 i__2 = *m - i__;
+   17949           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17950             : 
+   17951           0 :                 i__2 = *m - i__;
+   17952           0 :                 i__3 = i__ - 1;
+   17953           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17954           0 :                         a_dim1], lda, &y[i__ + y_dim1], ldy, &one, &a[i__ + 
+   17955           0 :                         1 + i__ * a_dim1], &c__1);
+   17956           0 :                 i__2 = *m - i__;
+   17957           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &x[i__ + 1 + 
+   17958           0 :                         x_dim1], ldx, &a[i__ * a_dim1 + 1], &c__1, &one, &a[
+   17959           0 :                         i__ + 1 + i__ * a_dim1], &c__1);
+   17960             : 
+   17961           0 :                 i__2 = *m - i__;
+   17962           0 :                 i__3 = i__ + 2;
+   17963           0 :                 if(*m<i__3)
+   17964           0 :                   i__3 = *m;
+   17965           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + 1 + i__ * a_dim1], 
+   17966           0 :                         &a[i__3 + i__ * a_dim1], &c__1, &tauq[i__]);
+   17967           0 :                 e[i__] = a[i__ + 1 + i__ * a_dim1];
+   17968           0 :                 a[i__ + 1 + i__ * a_dim1] = 1.;
+   17969             : 
+   17970           0 :                 i__2 = *m - i__;
+   17971           0 :                 i__3 = *n - i__;
+   17972           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ + 
+   17973           0 :                         1) * a_dim1], lda, &a[i__ + 1 + i__ * a_dim1], &c__1, 
+   17974           0 :                         &zero, &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17975           0 :                 i__2 = *m - i__;
+   17976           0 :                 i__3 = i__ - 1;
+   17977           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + a_dim1],
+   17978           0 :                          lda, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17979           0 :                         i__ * y_dim1 + 1], &c__1);
+   17980           0 :                 i__2 = *n - i__;
+   17981           0 :                 i__3 = i__ - 1;
+   17982           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17983           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17984           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17985           0 :                 i__2 = *m - i__;
+   17986           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &x[i__ + 1 + x_dim1], 
+   17987           0 :                         ldx, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17988           0 :                         i__ * y_dim1 + 1], &c__1);
+   17989           0 :                 i__2 = *n - i__;
+   17990           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__, &i__2, &minusone, &a[(i__ + 1) * a_dim1 
+   17991           0 :                         + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, &y[i__ 
+   17992           0 :                         + 1 + i__ * y_dim1], &c__1);
+   17993           0 :                 i__2 = *n - i__;
+   17994           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17995             :             }
+   17996             :         }
+   17997             :     }
+   17998             :     return;
+   17999             : } 
+   18000             : 
+   18001             : }
+   18002             : }
+   18003             : #include <cctype>
+   18004             : #include "lapack.h"
+   18005             : 
+   18006             : /* LAPACK */
+   18007             : #include "blas/blas.h"
+   18008             : namespace PLMD{
+   18009             : namespace lapack{
+   18010             : using namespace blas;
+   18011             : void
+   18012           0 : PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)(const char *uplo,
+   18013             :         int *m,
+   18014             :         int *n,
+   18015             :         float *a,
+   18016             :         int *lda,
+   18017             :         float *b,
+   18018             :         int *ldb)
+   18019             : {
+   18020             :   int i,j,minjm;
+   18021           0 :   const char ch=std::toupper(*uplo);
+   18022             : 
+   18023           0 :   if(ch=='U') {
+   18024           0 :     for(j=0;j<*n;j++) {
+   18025           0 :       minjm = (j < (*m-1)) ? j : (*m-1);
+   18026           0 :       for(i=0;i<=minjm;i++)
+   18027           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18028             :     }
+   18029           0 :   } else if(ch=='L') {
+   18030           0 :     for(j=0;j<*n;j++) {
+   18031           0 :       for(i=j;i<*m;i++)
+   18032           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18033             :     }
+   18034             :   } else {
+   18035           0 :     for(j=0;j<*n;j++) {
+   18036           0 :       for(i=0;i<*m;i++)
+   18037           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18038             :     }    
+   18039             :   }
+   18040           0 : }
+   18041             : }
+   18042             : }
+   18043             : #include <cmath>
+   18044             : #include "lapack.h"
+   18045             : 
+   18046             : 
+   18047             : #include "blas/blas.h"
+   18048             : namespace PLMD{
+   18049             : namespace lapack{
+   18050             : using namespace blas;
+   18051             : void
+   18052           0 : PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(float *a, 
+   18053             :        float *b,
+   18054             :        float *c__, 
+   18055             :        float *rt1, 
+   18056             :        float *rt2)
+   18057             : {
+   18058             :     float d__1;
+   18059             :     float ab, df, tb, sm, rt, adf, acmn, acmx;
+   18060             : 
+   18061             : 
+   18062           0 :     sm = *a + *c__;
+   18063           0 :     df = *a - *c__;
+   18064             :     adf = std::abs(df);
+   18065           0 :     tb = *b + *b;
+   18066             :     ab = std::abs(tb);
+   18067           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18068             :         acmx = *a;
+   18069             :         acmn = *c__;
+   18070             :     } else {
+   18071             :         acmx = *c__;
+   18072             :         acmn = *a;
+   18073             :     }
+   18074           0 :     if (adf > ab) {
+   18075           0 :         d__1 = ab / adf;
+   18076           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18077           0 :     } else if (adf < ab) {
+   18078           0 :         d__1 = adf / ab;
+   18079           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18080             :     } else {
+   18081             : 
+   18082           0 :         rt = ab *  std::sqrt(2.);
+   18083             :     }
+   18084           0 :     if (sm < 0.) {
+   18085           0 :         *rt1 = (sm - rt) * .5;
+   18086           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18087           0 :     } else if (sm > 0.) {
+   18088           0 :         *rt1 = (sm + rt) * .5;
+   18089           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18090             :     } else {
+   18091           0 :         *rt1 = rt * .5;
+   18092           0 :         *rt2 = rt * -.5;
+   18093             :     }
+   18094           0 :     return;
+   18095             : 
+   18096             : }
+   18097             : 
+   18098             : 
+   18099             : }
+   18100             : }
+   18101             : #include <cmath>
+   18102             : #include "lapack.h"
+   18103             : 
+   18104             : #include "blas/blas.h"
+   18105             : namespace PLMD{
+   18106             : namespace lapack{
+   18107             : using namespace blas;
+   18108             : void
+   18109           0 : PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(int *ijob,
+   18110             :         int *nitmax,
+   18111             :         int *n, 
+   18112             :         int *mmax,
+   18113             :         int *minp,
+   18114             :         int *nbmin,
+   18115             :         float *abstol, 
+   18116             :         float *reltol, 
+   18117             :         float *pivmin, 
+   18118             :         float *d__,
+   18119             :         float *e,
+   18120             :         float *e2, 
+   18121             :         int *nval,
+   18122             :         float *ab, 
+   18123             :         float *c__, 
+   18124             :         int *mout, 
+   18125             :         int *nab,
+   18126             :         float *work,
+   18127             :         int *iwork, 
+   18128             :         int *info)
+   18129             : {
+   18130             :     int nab_dim1, nab_offset, ab_dim1, ab_offset, i__1, i__2, i__3, i__4, 
+   18131             :             i__5, i__6;
+   18132             :     float d__1, d__2, d__3, d__4;
+   18133             : 
+   18134             :     int j, kf, ji, kl, jp, jit;
+   18135             :     float tmp1, tmp2;
+   18136             :     int itmp1, itmp2, kfnew, klnew;
+   18137             : 
+   18138           0 :     nab_dim1 = *mmax;
+   18139           0 :     nab_offset = 1 + nab_dim1;
+   18140           0 :     nab -= nab_offset;
+   18141             :     ab_dim1 = *mmax;
+   18142             :     ab_offset = 1 + ab_dim1;
+   18143           0 :     ab -= ab_offset;
+   18144           0 :     --d__;
+   18145             :     --e;
+   18146           0 :     --e2;
+   18147           0 :     --nval;
+   18148           0 :     --c__;
+   18149           0 :     --work;
+   18150           0 :     --iwork;
+   18151             : 
+   18152           0 :     *info = 0;
+   18153           0 :     if (*ijob < 1 || *ijob > 3) {
+   18154           0 :         *info = -1;
+   18155           0 :         return;
+   18156             :     }
+   18157             : 
+   18158           0 :     if (*ijob == 1) {
+   18159             : 
+   18160           0 :         *mout = 0;
+   18161             : 
+   18162           0 :         i__1 = *minp;
+   18163           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18164           0 :             for (jp = 1; jp <= 2; ++jp) {
+   18165           0 :                 tmp1 = d__[1] - ab[ji + jp * ab_dim1];
+   18166           0 :                 if (std::abs(tmp1) < *pivmin) {
+   18167           0 :                     tmp1 = -(*pivmin);
+   18168             :                 }
+   18169           0 :                 nab[ji + jp * nab_dim1] = 0;
+   18170           0 :                 if (tmp1 <= 0.) {
+   18171           0 :                     nab[ji + jp * nab_dim1] = 1;
+   18172             :                 }
+   18173             : 
+   18174           0 :                 i__2 = *n;
+   18175           0 :                 for (j = 2; j <= i__2; ++j) {
+   18176           0 :                     tmp1 = d__[j] - e2[j - 1] / tmp1 - ab[ji + jp * ab_dim1];
+   18177           0 :                     if (std::abs(tmp1) < *pivmin) {
+   18178           0 :                         tmp1 = -(*pivmin);
+   18179             :                     }
+   18180           0 :                     if (tmp1 <= 0.) {
+   18181           0 :                         ++nab[ji + jp * nab_dim1];
+   18182             :                     }
+   18183             :                 }
+   18184             :             }
+   18185           0 :             *mout = *mout + nab[ji + (nab_dim1 << 1)] - nab[ji + nab_dim1];
+   18186             :         }
+   18187             :         return;
+   18188             :     }
+   18189             : 
+   18190             :     kf = 1;
+   18191           0 :     kl = *minp;
+   18192             : 
+   18193           0 :     if (*ijob == 2) {
+   18194             :         i__1 = *minp;
+   18195           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18196           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18197             :         }
+   18198             :     }
+   18199             : 
+   18200           0 :     i__1 = *nitmax;
+   18201           0 :     for (jit = 1; jit <= i__1; ++jit) {
+   18202             : 
+   18203           0 :         if (kl - kf + 1 >= *nbmin && *nbmin > 0) {
+   18204             : 
+   18205             :             i__2 = kl;
+   18206           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18207             : 
+   18208           0 :                 work[ji] = d__[1] - c__[ji];
+   18209           0 :                 iwork[ji] = 0;
+   18210           0 :                 if (work[ji] <= *pivmin) {
+   18211           0 :                     iwork[ji] = 1;
+   18212           0 :                     d__1 = work[ji], d__2 = -(*pivmin);
+   18213           0 :                     work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18214             :                 }
+   18215             : 
+   18216           0 :                 i__3 = *n;
+   18217           0 :                 for (j = 2; j <= i__3; ++j) {
+   18218           0 :                     work[ji] = d__[j] - e2[j - 1] / work[ji] - c__[ji];
+   18219           0 :                     if (work[ji] <= *pivmin) {
+   18220           0 :                         ++iwork[ji];
+   18221           0 :                         d__1 = work[ji], d__2 = -(*pivmin);
+   18222           0 :                         work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18223             :                     }
+   18224             :                 }
+   18225             :             }
+   18226             : 
+   18227           0 :             if (*ijob <= 2) {
+   18228             : 
+   18229             :                 klnew = kl;
+   18230             :                 i__2 = kl;
+   18231           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18232             : 
+   18233           0 :                   i__5 = nab[ji + nab_dim1];
+   18234           0 :                   i__6 = iwork[ji];
+   18235           0 :                   i__3 = nab[ji + (nab_dim1 << 1)];
+   18236             :                   i__4 = (i__5>i__6) ? i__5 : i__6;
+   18237           0 :                     iwork[ji] = (i__3<i__4) ? i__3 : i__4;
+   18238             : 
+   18239           0 :                     if (iwork[ji] == nab[ji + (nab_dim1 << 1)]) {
+   18240             : 
+   18241           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18242             : 
+   18243           0 :                     } else if (iwork[ji] == nab[ji + nab_dim1]) {
+   18244             : 
+   18245           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18246             :                     } else {
+   18247           0 :                         ++klnew;
+   18248           0 :                         if (klnew <= *mmax) {
+   18249             : 
+   18250           0 :                             ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 
+   18251           0 :                                     1)];
+   18252           0 :                             nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 
+   18253           0 :                                     << 1)];
+   18254           0 :                             ab[klnew + ab_dim1] = c__[ji];
+   18255           0 :                             nab[klnew + nab_dim1] = iwork[ji];
+   18256           0 :                             ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18257           0 :                             nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18258             :                         } else {
+   18259           0 :                             *info = *mmax + 1;
+   18260             :                         }
+   18261             :                     }
+   18262             :                 }
+   18263           0 :                 if (*info != 0) {
+   18264             :                     return;
+   18265             :                 }
+   18266             :                 kl = klnew;
+   18267             :             } else {
+   18268             : 
+   18269             :                 i__2 = kl;
+   18270           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18271           0 :                     if (iwork[ji] <= nval[ji]) {
+   18272           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18273           0 :                         nab[ji + nab_dim1] = iwork[ji];
+   18274             :                     }
+   18275           0 :                     if (iwork[ji] >= nval[ji]) {
+   18276           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18277           0 :                         nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18278             :                     }
+   18279             :                 }
+   18280             :             }
+   18281             : 
+   18282             :         } else {
+   18283             : 
+   18284             :             klnew = kl;
+   18285             :             i__2 = kl;
+   18286           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18287             : 
+   18288           0 :                 tmp1 = c__[ji];
+   18289           0 :                 tmp2 = d__[1] - tmp1;
+   18290             :                 itmp1 = 0;
+   18291           0 :                 if (tmp2 <= *pivmin) {
+   18292             :                     itmp1 = 1;
+   18293           0 :                     d__1 = tmp2, d__2 = -(*pivmin);
+   18294           0 :                     tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18295             :                 }
+   18296             : 
+   18297           0 :                 i__3 = *n;
+   18298           0 :                 for (j = 2; j <= i__3; ++j) {
+   18299           0 :                     tmp2 = d__[j] - e2[j - 1] / tmp2 - tmp1;
+   18300           0 :                     if (tmp2 <= *pivmin) {
+   18301           0 :                         ++itmp1;
+   18302           0 :                         d__1 = tmp2, d__2 = -(*pivmin);
+   18303           0 :                         tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18304             :                     }
+   18305             :                 }
+   18306             : 
+   18307           0 :                 if (*ijob <= 2) {
+   18308             : 
+   18309           0 :                     i__5 = nab[ji + nab_dim1];
+   18310           0 :                     i__3 = nab[ji + (nab_dim1 << 1)];
+   18311             :                     i__4 = (i__5>itmp1) ? i__5 : itmp1;
+   18312             :                     itmp1 = (i__3<i__4) ? i__3 : i__4;
+   18313             : 
+   18314           0 :                     if (itmp1 == nab[ji + (nab_dim1 << 1)]) {
+   18315             : 
+   18316           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18317             : 
+   18318           0 :                     } else if (itmp1 == nab[ji + nab_dim1]) {
+   18319             : 
+   18320           0 :                         ab[ji + ab_dim1] = tmp1;
+   18321           0 :                     } else if (klnew < *mmax) {
+   18322             : 
+   18323           0 :                         ++klnew;
+   18324           0 :                         ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 1)];
+   18325           0 :                         nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 << 
+   18326           0 :                                 1)];
+   18327           0 :                         ab[klnew + ab_dim1] = tmp1;
+   18328           0 :                         nab[klnew + nab_dim1] = itmp1;
+   18329           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18330           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18331             :                     } else {
+   18332           0 :                         *info = *mmax + 1;
+   18333           0 :                         return;
+   18334             :                     }
+   18335             :                 } else {
+   18336             : 
+   18337           0 :                     if (itmp1 <= nval[ji]) {
+   18338           0 :                         ab[ji + ab_dim1] = tmp1;
+   18339           0 :                         nab[ji + nab_dim1] = itmp1;
+   18340             :                     }
+   18341           0 :                     if (itmp1 >= nval[ji]) {
+   18342           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18343           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18344             :                     }
+   18345             :                 }
+   18346             :             }
+   18347             :             kl = klnew;
+   18348             : 
+   18349             :         }
+   18350             : 
+   18351             :         kfnew = kf;
+   18352             :         i__2 = kl;
+   18353           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18354           0 :             tmp1 = std::abs(ab[ji + (ab_dim1 << 1)] - ab[ji + ab_dim1]);
+   18355             :             d__3 = std::abs(ab[ji + (ab_dim1 << 1)]);
+   18356             :             d__4 = std::abs(ab[ji + ab_dim1]);
+   18357           0 :             tmp2 = (d__3>d__4) ? d__3 : d__4;
+   18358           0 :             d__1 = (*abstol>*pivmin) ? *abstol : *pivmin;
+   18359           0 :             d__2 = *reltol * tmp2;
+   18360           0 :             if (tmp1 < ((d__1>d__2) ? d__1 : d__2) || nab[ji + nab_dim1] >= nab[ji + (
+   18361           0 :                     nab_dim1 << 1)]) {
+   18362             : 
+   18363           0 :                 if (ji > kfnew) {
+   18364             :                     tmp1 = ab[ji + ab_dim1];
+   18365             :                     tmp2 = ab[ji + (ab_dim1 << 1)];
+   18366           0 :                     itmp1 = nab[ji + nab_dim1];
+   18367           0 :                     itmp2 = nab[ji + (nab_dim1 << 1)];
+   18368           0 :                     ab[ji + ab_dim1] = ab[kfnew + ab_dim1];
+   18369           0 :                     ab[ji + (ab_dim1 << 1)] = ab[kfnew + (ab_dim1 << 1)];
+   18370           0 :                     nab[ji + nab_dim1] = nab[kfnew + nab_dim1];
+   18371           0 :                     nab[ji + (nab_dim1 << 1)] = nab[kfnew + (nab_dim1 << 1)];
+   18372           0 :                     ab[kfnew + ab_dim1] = tmp1;
+   18373           0 :                     ab[kfnew + (ab_dim1 << 1)] = tmp2;
+   18374           0 :                     nab[kfnew + nab_dim1] = itmp1;
+   18375           0 :                     nab[kfnew + (nab_dim1 << 1)] = itmp2;
+   18376           0 :                     if (*ijob == 3) {
+   18377           0 :                         itmp1 = nval[ji];
+   18378           0 :                         nval[ji] = nval[kfnew];
+   18379           0 :                         nval[kfnew] = itmp1;
+   18380             :                     }
+   18381             :                 }
+   18382           0 :                 ++kfnew;
+   18383             :             }
+   18384             :         }
+   18385             :         kf = kfnew;
+   18386             : 
+   18387             :         i__2 = kl;
+   18388           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18389           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18390             :         }
+   18391             : 
+   18392           0 :         if (kf > kl) {
+   18393             :             break;
+   18394             :         }
+   18395             :     }
+   18396             : 
+   18397           0 :     i__1 = kl + 1 - kf;
+   18398           0 :     if(i__1>0)
+   18399           0 :       *info = i__1;
+   18400             : 
+   18401           0 :     *mout = kl;
+   18402             : 
+   18403           0 :     return;
+   18404             : 
+   18405             : }
+   18406             : 
+   18407             : 
+   18408             : }
+   18409             : }
+   18410             : #include <cmath>
+   18411             : 
+   18412             : #include "lapack.h"
+   18413             : 
+   18414             : #include "real.h"
+   18415             : 
+   18416             : #include "blas/blas.h"
+   18417             : namespace PLMD{
+   18418             : namespace lapack{
+   18419             : using namespace blas;
+   18420             : void
+   18421           0 : PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(int *kniter, 
+   18422             :                         int *orgati, 
+   18423             :                         float *rho, 
+   18424             :                         float *d__,
+   18425             :                         float *z__, 
+   18426             :                         float *finit, 
+   18427             :                         float *tau, 
+   18428             :                         int *info)
+   18429             : {
+   18430             :     int i__1;
+   18431             :     float r__1, r__2, r__3, r__4;
+   18432             : 
+   18433             :     float a, b, c__, f;
+   18434             :     int i__;
+   18435             :     float fc, df, ddf, eta, eps, base;
+   18436             :     int iter;
+   18437             :     float temp, temp1, temp2, temp3, temp4;
+   18438             :     int scale;
+   18439             :     int niter;
+   18440             :     float small1, small2, sminv1, sminv2, dscale[3], sclfac;
+   18441             :     float zscale[3], erretm;
+   18442             :     float safemin;
+   18443             :     float sclinv = 0;
+   18444             :     
+   18445           0 :     --z__;
+   18446           0 :     --d__;
+   18447             : 
+   18448           0 :     *info = 0;
+   18449             : 
+   18450             :     niter = 1;
+   18451           0 :     *tau = 0.f;
+   18452           0 :     if (*kniter == 2) {
+   18453           0 :         if (*orgati) {
+   18454           0 :             temp = (d__[3] - d__[2]) / 2.f;
+   18455           0 :             c__ = *rho + z__[1] / (d__[1] - d__[2] - temp);
+   18456           0 :             a = c__ * (d__[2] + d__[3]) + z__[2] + z__[3];
+   18457           0 :             b = c__ * d__[2] * d__[3] + z__[2] * d__[3] + z__[3] * d__[2];
+   18458             :         } else {
+   18459           0 :             temp = (d__[1] - d__[2]) / 2.f;
+   18460           0 :             c__ = *rho + z__[3] / (d__[3] - d__[2] - temp);
+   18461           0 :             a = c__ * (d__[1] + d__[2]) + z__[1] + z__[2];
+   18462           0 :             b = c__ * d__[1] * d__[2] + z__[1] * d__[2] + z__[2] * d__[1];
+   18463             :         }
+   18464           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18465           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18466           0 :         a /= temp;
+   18467           0 :         b /= temp;
+   18468           0 :         c__ /= temp;
+   18469           0 :         if (c__ == 0.f) {
+   18470           0 :             *tau = b / a;
+   18471           0 :         } else if (a <= 0.f) {
+   18472           0 :             *tau = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / (
+   18473           0 :                     c__ * 2.f);
+   18474             :         } else {
+   18475           0 :             *tau = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1))));
+   18476             :         }
+   18477             : 
+   18478           0 :         temp = *rho + z__[1] / (d__[1] - *tau) + z__[2] / (d__[2] - *tau) + 
+   18479           0 :                 z__[3] / (d__[3] - *tau);
+   18480           0 :         if (std::abs(*finit) <= std::abs(temp)) {
+   18481           0 :             *tau = 0.f;
+   18482             :         }
+   18483             :     }
+   18484             : 
+   18485             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18486             :     base = 2;
+   18487             :     safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   18488             :     i__1 = static_cast<int>(std::log(safemin) / std::log(base) / 3.f);
+   18489             :     small1 = std::pow(base, static_cast<float>(i__1));
+   18490             :     sminv1 = 1.f / small1;
+   18491             :     small2 = small1 * small1;
+   18492             :     sminv2 = sminv1 * sminv1;
+   18493             : 
+   18494           0 :     if (*orgati) {
+   18495           0 :         r__3 = (r__1 = d__[2] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[3] - *
+   18496             :                 tau, std::abs(r__2));
+   18497           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18498             :     } else {
+   18499           0 :         r__3 = (r__1 = d__[1] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[2] - *
+   18500             :                 tau, std::abs(r__2));
+   18501           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18502             :     }
+   18503             :     scale = 0;
+   18504           0 :     if (temp <= small1) {
+   18505             :         scale = 1;
+   18506           0 :         if (temp <= small2) {
+   18507             : 
+   18508             :             sclfac = sminv2;
+   18509             :             sclinv = small2;
+   18510             :         } else {
+   18511             : 
+   18512             :             sclfac = sminv1;
+   18513             :             sclinv = small1;
+   18514             : 
+   18515             :         }
+   18516             : 
+   18517           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18518           0 :             dscale[i__ - 1] = d__[i__] * sclfac;
+   18519           0 :             zscale[i__ - 1] = z__[i__] * sclfac;
+   18520             :         }
+   18521           0 :         *tau *= sclfac;
+   18522             :     } else {
+   18523             : 
+   18524           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18525           0 :             dscale[i__ - 1] = d__[i__];
+   18526           0 :             zscale[i__ - 1] = z__[i__];
+   18527             :         }
+   18528             :     }
+   18529             :     fc = 0.f;
+   18530             :     df = 0.f;
+   18531             :     ddf = 0.f;
+   18532           0 :     for (i__ = 1; i__ <= 3; ++i__) {
+   18533           0 :         temp = 1.f / (dscale[i__ - 1] - *tau);
+   18534           0 :         temp1 = zscale[i__ - 1] * temp;
+   18535           0 :         temp2 = temp1 * temp;
+   18536           0 :         temp3 = temp2 * temp;
+   18537           0 :         fc += temp1 / dscale[i__ - 1];
+   18538           0 :         df += temp2;
+   18539           0 :         ddf += temp3;
+   18540             :     }
+   18541           0 :     f = *finit + *tau * fc;
+   18542             : 
+   18543           0 :     if (std::abs(f) <= 0.f) {
+   18544           0 :         goto L60;
+   18545             :     }
+   18546             :     iter = niter + 1;
+   18547           0 :     for (niter = iter; niter <= 20; ++niter) {
+   18548           0 :         if (*orgati) {
+   18549           0 :             temp1 = dscale[1] - *tau;
+   18550           0 :             temp2 = dscale[2] - *tau;
+   18551             :         } else {
+   18552           0 :             temp1 = dscale[0] - *tau;
+   18553           0 :             temp2 = dscale[1] - *tau;
+   18554             :         }
+   18555           0 :         a = (temp1 + temp2) * f - temp1 * temp2 * df;
+   18556           0 :         b = temp1 * temp2 * f;
+   18557           0 :         c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
+   18558           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18559           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18560           0 :         a /= temp;
+   18561           0 :         b /= temp;
+   18562           0 :         c__ /= temp;
+   18563           0 :         if (c__ == 0.f) {
+   18564           0 :             eta = b / a;
+   18565           0 :         } else if (a <= 0.f) {
+   18566           0 :             eta = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / ( c__ * 2.f);
+   18567             :         } else {
+   18568           0 :             eta = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs( r__1))));
+   18569             :         }
+   18570           0 :         if (f * eta >= 0.f) {
+   18571           0 :             eta = -f / df;
+   18572             :         }
+   18573           0 :         temp = eta + *tau;
+   18574           0 :         if (*orgati) {
+   18575           0 :             if (eta > 0.f && temp >= dscale[2]) {
+   18576           0 :                 eta = (dscale[2] - *tau) / 2.f;
+   18577             :             }
+   18578             : 
+   18579           0 :             if (eta < 0.f && temp <= dscale[1]) {
+   18580           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18581             :             }
+   18582             :         } else {
+   18583           0 :             if (eta > 0.f && temp >= dscale[1]) {
+   18584           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18585             :             }
+   18586           0 :             if (eta < 0.f && temp <= dscale[0]) {
+   18587           0 :                 eta = (dscale[0] - *tau) / 2.f;
+   18588             :             }
+   18589             :         }
+   18590           0 :         *tau += eta;
+   18591             :         fc = 0.f;
+   18592             :         erretm = 0.f;
+   18593             :         df = 0.f;
+   18594             :         ddf = 0.f;
+   18595           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18596           0 :             temp = 1.f / (dscale[i__ - 1] - *tau);
+   18597           0 :             temp1 = zscale[i__ - 1] * temp;
+   18598           0 :             temp2 = temp1 * temp;
+   18599           0 :             temp3 = temp2 * temp;
+   18600           0 :             temp4 = temp1 / dscale[i__ - 1];
+   18601           0 :             fc += temp4;
+   18602           0 :             erretm += std::abs(temp4);
+   18603           0 :             df += temp2;
+   18604           0 :             ddf += temp3;
+   18605             :         }
+   18606           0 :         f = *finit + *tau * fc;
+   18607           0 :         erretm = (std::abs(*finit) + std::abs(*tau) * erretm) * 8.f + std::abs(*tau) * df;
+   18608           0 :         if (std::abs(f) <= eps * erretm) {
+   18609           0 :             goto L60;
+   18610             :         }
+   18611             :     }
+   18612           0 :     *info = 1;
+   18613           0 : L60:
+   18614           0 :     if (scale) {
+   18615           0 :         *tau *= sclinv;
+   18616             :     }
+   18617           0 :     return;
+   18618             : } 
+   18619             : 
+   18620             : 
+   18621             : }
+   18622             : }
+   18623             : #include <cmath>
+   18624             : #include "real.h"
+   18625             : 
+   18626             : #include "lapack.h"
+   18627             : 
+   18628             : 
+   18629             : #include "blas/blas.h"
+   18630             : namespace PLMD{
+   18631             : namespace lapack{
+   18632             : using namespace blas;
+   18633             : void
+   18634           0 : PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(float *   a, 
+   18635             :         float *   b, 
+   18636             :         float *   c__, 
+   18637             :         float *   rt1, 
+   18638             :         float *   rt2, 
+   18639             :         float *   cs1, 
+   18640             :         float *   sn1)
+   18641             : {
+   18642             :     float d__1;
+   18643             : 
+   18644             :     float ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
+   18645             :     int sgn1, sgn2;
+   18646             :     float acmn, acmx;
+   18647             : 
+   18648           0 :     sm = *a + *c__;
+   18649           0 :     df = *a - *c__;
+   18650             :     adf = std::abs(df);
+   18651           0 :     tb = *b + *b;
+   18652             :     ab = std::abs(tb);
+   18653           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18654             :         acmx = *a;
+   18655             :         acmn = *c__;
+   18656             :     } else {
+   18657             :         acmx = *c__;
+   18658             :         acmn = *a;
+   18659             :     }
+   18660           0 :     if (adf > ab) {
+   18661           0 :         d__1 = ab / adf;
+   18662           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18663           0 :     } else if (adf < ab) {
+   18664           0 :         d__1 = adf / ab;
+   18665           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18666             :     } else {
+   18667             : 
+   18668           0 :         rt = ab *  std::sqrt(2.);
+   18669             :     }
+   18670           0 :     if (sm < 0.) {
+   18671           0 :         *rt1 = (sm - rt) * .5;
+   18672             :         sgn1 = -1;
+   18673             : 
+   18674           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18675           0 :     } else if (sm > 0.) {
+   18676           0 :         *rt1 = (sm + rt) * .5;
+   18677             :         sgn1 = 1;
+   18678           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18679             :     } else {
+   18680           0 :         *rt1 = rt * .5;
+   18681           0 :         *rt2 = rt * -.5;
+   18682             :         sgn1 = 1;
+   18683             :     }
+   18684           0 :     if (df >= 0.) {
+   18685           0 :         cs = df + rt;
+   18686             :         sgn2 = 1;
+   18687             :     } else {
+   18688           0 :         cs = df - rt;
+   18689             :         sgn2 = -1;
+   18690             :     }
+   18691             :     acs = std::abs(cs);
+   18692           0 :     if (acs > ab) {
+   18693           0 :         ct = -tb / cs;
+   18694           0 :         *sn1 = 1. /  std::sqrt(ct * ct + 1.);
+   18695           0 :         *cs1 = ct * *sn1;
+   18696             :     } else {
+   18697           0 :         if (std::abs(ab)<PLUMED_GMX_FLOAT_MIN) {
+   18698           0 :             *cs1 = 1.;
+   18699           0 :             *sn1 = 0.;
+   18700             :         } else {
+   18701           0 :             tn = -cs / tb;
+   18702           0 :             *cs1 = 1. /  std::sqrt(tn * tn + 1.);
+   18703           0 :             *sn1 = tn * *cs1;
+   18704             :         }
+   18705             :     }
+   18706           0 :     if (sgn1 == sgn2) {
+   18707           0 :         tn = *cs1;
+   18708           0 :         *cs1 = -(*sn1);
+   18709           0 :         *sn1 = tn;
+   18710             :     }
+   18711           0 :     return;
+   18712             : 
+   18713             : }
+   18714             : 
+   18715             : 
+   18716             : }
+   18717             : }
+   18718             : #include <cmath>
+   18719             : #include "real.h"
+   18720             : 
+   18721             : #include "lapack.h"
+   18722             : #include "lapack_limits.h"
+   18723             : 
+   18724             : 
+   18725             : 
+   18726             : #include "blas/blas.h"
+   18727             : namespace PLMD{
+   18728             : namespace lapack{
+   18729             : using namespace blas;
+   18730             : void
+   18731           0 : PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(int *n, 
+   18732             :         float *a, 
+   18733             :         float *lambda, 
+   18734             :         float *b, 
+   18735             :         float *c__, 
+   18736             :         float *tol, 
+   18737             :         float *d__, 
+   18738             :         int *in, 
+   18739             :         int *info)
+   18740             : {
+   18741             :     int i__1;
+   18742             : 
+   18743             :     int k;
+   18744             :     float tl, eps, piv1, piv2, temp, mult, scale1, scale2;
+   18745             : 
+   18746           0 :     --in;
+   18747           0 :     --d__;
+   18748           0 :     --c__;
+   18749           0 :     --b;
+   18750           0 :     --a;
+   18751             : 
+   18752           0 :     *info = 0;
+   18753           0 :     if (*n < 0) {
+   18754           0 :         *info = -1;
+   18755           0 :         return;
+   18756             :     }
+   18757             : 
+   18758           0 :     if (*n == 0) 
+   18759             :         return;
+   18760             :     
+   18761           0 :     a[1] -= *lambda;
+   18762           0 :     in[*n] = 0;
+   18763           0 :     if (*n == 1) {
+   18764           0 :         if (std::abs(a[1])<PLUMED_GMX_FLOAT_MIN) {
+   18765           0 :             in[1] = 1;
+   18766             :         }
+   18767           0 :         return;
+   18768             :     }
+   18769             : 
+   18770             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18771             : 
+   18772           0 :     tl = (*tol>eps) ? *tol : eps;
+   18773           0 :     scale1 = std::abs(a[1]) + std::abs(b[1]);
+   18774             :     i__1 = *n - 1;
+   18775           0 :     for (k = 1; k <= i__1; ++k) {
+   18776           0 :         a[k + 1] -= *lambda;
+   18777           0 :         scale2 = std::abs(c__[k]) + std::abs(a[k + 1]);
+   18778           0 :         if (k < *n - 1) {
+   18779           0 :             scale2 += std::abs(b[k + 1]);
+   18780             :         }
+   18781           0 :         if (std::abs(a[k])<PLUMED_GMX_FLOAT_MIN) {
+   18782             :             piv1 = 0.;
+   18783             :         } else {
+   18784           0 :             piv1 = std::abs(a[k]) / scale1;
+   18785             :         }
+   18786           0 :         if (std::abs(c__[k])<PLUMED_GMX_FLOAT_MIN) {
+   18787           0 :             in[k] = 0;
+   18788             :             piv2 = 0.;
+   18789             :             scale1 = scale2;
+   18790           0 :             if (k < *n - 1) {
+   18791           0 :                 d__[k] = 0.;
+   18792             :             }
+   18793             :         } else {
+   18794           0 :             piv2 = std::abs(c__[k]) / scale2;
+   18795           0 :             if (piv2 <= piv1) {
+   18796           0 :                 in[k] = 0;
+   18797             :                 scale1 = scale2;
+   18798           0 :                 c__[k] /= a[k];
+   18799           0 :                 a[k + 1] -= c__[k] * b[k];
+   18800           0 :                 if (k < *n - 1) {
+   18801           0 :                     d__[k] = 0.;
+   18802             :                 }
+   18803             :             } else {
+   18804           0 :                 in[k] = 1;
+   18805           0 :                 mult = a[k] / c__[k];
+   18806           0 :                 a[k] = c__[k];
+   18807           0 :                 temp = a[k + 1];
+   18808           0 :                 a[k + 1] = b[k] - mult * temp;
+   18809           0 :                 if (k < *n - 1) {
+   18810           0 :                     d__[k] = b[k + 1];
+   18811           0 :                     b[k + 1] = -mult * d__[k];
+   18812             :                 }
+   18813           0 :                 b[k] = temp;
+   18814           0 :                 c__[k] = mult;
+   18815             :             }
+   18816             :         }
+   18817           0 :         if (((piv1>piv2) ? piv1 : piv2) <= tl && in[*n] == 0) {
+   18818           0 :             in[*n] = k;
+   18819             :         }
+   18820             :     }
+   18821           0 :     if (std::abs(a[*n]) <= scale1 * tl && in[*n] == 0) {
+   18822           0 :         in[*n] = *n;
+   18823             :     }
+   18824             : 
+   18825             :     return;
+   18826             : 
+   18827             : }
+   18828             : 
+   18829             : 
+   18830             : }
+   18831             : }
+   18832             : #include <stdlib.h>
+   18833             : #include <cmath>
+   18834             : #include "real.h"
+   18835             : 
+   18836             : #include "lapack.h"
+   18837             : #include "lapack_limits.h"
+   18838             : 
+   18839             : 
+   18840             : #include "blas/blas.h"
+   18841             : namespace PLMD{
+   18842             : namespace lapack{
+   18843             : using namespace blas;
+   18844             : void
+   18845           0 : PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(int *job, 
+   18846             :         int *n, 
+   18847             :         float *a, 
+   18848             :         float *b, 
+   18849             :         float *c__, 
+   18850             :         float *d__, 
+   18851             :         int *in, 
+   18852             :         float *y, 
+   18853             :         float *tol, 
+   18854             :         int *info)
+   18855             : {
+   18856             :     int i__1;
+   18857             :     float d__1, d__2, d__4, d__5;
+   18858             : 
+   18859             :     int k;
+   18860             :     float ak, eps, temp, pert, absak, sfmin;
+   18861             :     float bignum,minval;
+   18862           0 :     --y;
+   18863           0 :     --in;
+   18864           0 :     --d__;
+   18865           0 :     --c__;
+   18866           0 :     --b;
+   18867           0 :     --a;
+   18868             : 
+   18869           0 :     *info = 0;
+   18870           0 :     if (abs(*job) > 2 || *job == 0) {
+   18871           0 :         *info = -1;
+   18872           0 :     } else if (*n < 0) {
+   18873           0 :         *info = -2;
+   18874             :     }
+   18875           0 :     if (*info != 0) {
+   18876             :         return;
+   18877             :     }
+   18878             : 
+   18879           0 :     if (*n == 0) {
+   18880             :         return;
+   18881             :     }
+   18882             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18883             :     minval = PLUMED_GMX_FLOAT_MIN;
+   18884             :     sfmin = minval / eps;
+   18885             : 
+   18886             :     bignum = 1. / sfmin;
+   18887             : 
+   18888           0 :     if (*job < 0) {
+   18889           0 :         if (*tol <= 0.) {
+   18890           0 :             *tol = std::abs(a[1]);
+   18891           0 :             if (*n > 1) {
+   18892             :                 d__1 = *tol;
+   18893           0 :                 d__2 = std::abs(a[2]);
+   18894           0 :                 d__1 = (d__1>d__2) ? d__1 : d__2;
+   18895           0 :                 d__2 = std::abs(b[1]);
+   18896           0 :                 *tol = (d__1>d__2) ? d__1 : d__2;
+   18897             :             }
+   18898           0 :             i__1 = *n;
+   18899           0 :             for (k = 3; k <= i__1; ++k) {
+   18900           0 :               d__4 = *tol;
+   18901           0 :               d__5 = std::abs(a[k]);
+   18902           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18903           0 :               d__5 = std::abs(b[k - 1]);
+   18904           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18905           0 :               d__5 = std::abs(d__[k - 2]);
+   18906           0 :               *tol = (d__4>d__5) ? d__4 : d__5;
+   18907             :             }
+   18908           0 :             *tol *= eps;
+   18909           0 :             if (std::abs(*tol)<PLUMED_GMX_FLOAT_MIN) {
+   18910           0 :                 *tol = eps;
+   18911             :             }
+   18912             :         }
+   18913             :     }
+   18914             : 
+   18915           0 :     if (1 == abs(*job)) {
+   18916           0 :         i__1 = *n;
+   18917           0 :         for (k = 2; k <= i__1; ++k) {
+   18918           0 :             if (in[k - 1] == 0) {
+   18919           0 :                 y[k] -= c__[k - 1] * y[k - 1];
+   18920             :             } else {
+   18921           0 :                 temp = y[k - 1];
+   18922           0 :                 y[k - 1] = y[k];
+   18923           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   18924             :             }
+   18925             :         }
+   18926           0 :         if (*job == 1) {
+   18927           0 :             for (k = *n; k >= 1; --k) {
+   18928           0 :                 if (k <= *n - 2) {
+   18929           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18930           0 :                 } else if (k == *n - 1) {
+   18931           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18932             :                 } else {
+   18933           0 :                     temp = y[k];
+   18934             :                 }
+   18935           0 :                 ak = a[k];
+   18936             :                 absak = std::abs(ak);
+   18937           0 :                 if (absak < 1.) {
+   18938           0 :                     if (absak < sfmin) {
+   18939           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18940           0 :                             *info = k;
+   18941           0 :                             return;
+   18942             :                         } else {
+   18943           0 :                             temp *= bignum;
+   18944           0 :                             ak *= bignum;
+   18945             :                         }
+   18946           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18947           0 :                         *info = k;
+   18948           0 :                         return;
+   18949             :                     }
+   18950             :                 }
+   18951           0 :                 y[k] = temp / ak;
+   18952             :             }
+   18953             :         } else {
+   18954           0 :             for (k = *n; k >= 1; --k) {
+   18955           0 :                 if (k + 2 <= *n) {
+   18956           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18957           0 :                 } else if (k + 1 == *n) {
+   18958           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18959             :                 } else {
+   18960           0 :                     temp = y[k];
+   18961             :                 }
+   18962           0 :                 ak = a[k];
+   18963             : 
+   18964           0 :                 pert = *tol;
+   18965           0 :                 if(ak<0)
+   18966           0 :                   pert *= -1.0;
+   18967           0 : L40:
+   18968             :                 absak = std::abs(ak);
+   18969           0 :                 if (absak < 1.) {
+   18970           0 :                     if (absak < sfmin) {
+   18971           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18972           0 :                             ak += pert;
+   18973           0 :                             pert *= 2;
+   18974           0 :                             goto L40;
+   18975             :                         } else {
+   18976           0 :                             temp *= bignum;
+   18977           0 :                             ak *= bignum;
+   18978             :                         }
+   18979           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18980           0 :                         ak += pert;
+   18981           0 :                         pert *= 2;
+   18982           0 :                         goto L40;
+   18983             :                     }
+   18984             :                 }
+   18985           0 :                 y[k] = temp / ak;
+   18986             :             }
+   18987             :         }
+   18988             :     } else {
+   18989             : 
+   18990           0 :         if (*job == 2) {
+   18991           0 :             i__1 = *n;
+   18992           0 :             for (k = 1; k <= i__1; ++k) {
+   18993           0 :                 if (k >= 3) {
+   18994           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   18995           0 :                 } else if (k == 2) {
+   18996           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   18997             :                 } else {
+   18998           0 :                     temp = y[k];
+   18999             :                 }
+   19000           0 :                 ak = a[k];
+   19001             :                 absak = std::abs(ak);
+   19002           0 :                 if (absak < 1.) {
+   19003           0 :                     if (absak < sfmin) {
+   19004           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19005           0 :                             *info = k;
+   19006           0 :                             return;
+   19007             :                         } else {
+   19008           0 :                             temp *= bignum;
+   19009           0 :                             ak *= bignum;
+   19010             :                         }
+   19011           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19012           0 :                         *info = k;
+   19013           0 :                         return;
+   19014             :                     }
+   19015             :                 }
+   19016           0 :                 y[k] = temp / ak;
+   19017             :             }
+   19018             :         } else {
+   19019           0 :             i__1 = *n;
+   19020           0 :             for (k = 1; k <= i__1; ++k) {
+   19021           0 :                 if (k >= 3) {
+   19022           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   19023           0 :                 } else if (k == 2) {
+   19024           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   19025             :                 } else {
+   19026           0 :                     temp = y[k];
+   19027             :                 }
+   19028           0 :                 ak = a[k];
+   19029             : 
+   19030           0 :                 pert = *tol;
+   19031           0 :                 if(ak<0)
+   19032           0 :                   pert *= -1.0;
+   19033             : 
+   19034           0 : L70:
+   19035             :                 absak = std::abs(ak);
+   19036           0 :                 if (absak < 1.) {
+   19037           0 :                     if (absak < sfmin) {
+   19038           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19039           0 :                             ak += pert;
+   19040           0 :                             pert *= 2;
+   19041           0 :                             goto L70;
+   19042             :                         } else {
+   19043           0 :                             temp *= bignum;
+   19044           0 :                             ak *= bignum;
+   19045             :                         }
+   19046           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19047           0 :                         ak += pert;
+   19048           0 :                         pert *= 2;
+   19049           0 :                         goto L70;
+   19050             :                     }
+   19051             :                 }
+   19052           0 :                 y[k] = temp / ak;
+   19053             :             }
+   19054             :         }
+   19055             : 
+   19056           0 :         for (k = *n; k >= 2; --k) {
+   19057           0 :             if (in[k - 1] == 0) {
+   19058           0 :                 y[k - 1] -= c__[k - 1] * y[k];
+   19059             :             } else {
+   19060           0 :                 temp = y[k - 1];
+   19061           0 :                 y[k - 1] = y[k];
+   19062           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   19063             :             }
+   19064             :         }
+   19065             :     }
+   19066             : 
+   19067             :     return;
+   19068             : }
+   19069             : 
+   19070             : 
+   19071             : }
+   19072             : }
+   19073             : #include "lapack.h"
+   19074             : 
+   19075             : 
+   19076             : /* LAPACK */
+   19077             : 
+   19078             : 
+   19079             : #include "blas/blas.h"
+   19080             : namespace PLMD{
+   19081             : namespace lapack{
+   19082             : using namespace blas;
+   19083             : void
+   19084           0 : PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(int *n1,
+   19085             :                         int *n2,
+   19086             :                         float *a,
+   19087             :                         int *dtrd1,
+   19088             :                         int *dtrd2,
+   19089             :                         int *index)
+   19090             : {
+   19091           0 :   int n1sv = *n1;
+   19092           0 :   int n2sv = *n2;
+   19093             :   int i,ind1,ind2;
+   19094             : 
+   19095           0 :   if(*dtrd1>0)
+   19096             :     ind1 = 0;
+   19097             :   else
+   19098           0 :     ind1 = *n1-1;
+   19099             : 
+   19100           0 :   if(*dtrd2>0)
+   19101             :     ind2 = *n1;
+   19102             :   else
+   19103           0 :     ind2 = *n1+*n2-1;
+   19104             : 
+   19105             :   i = 0;
+   19106             :   
+   19107           0 :   while(n1sv>0 && n2sv>0) {
+   19108           0 :     if(a[ind1]<=a[ind2]) {
+   19109           0 :       index[i] = ind1 + 1;
+   19110           0 :       i++;
+   19111           0 :       ind1 += *dtrd1;
+   19112           0 :       n1sv--;
+   19113             :     } else {
+   19114           0 :       index[i] = ind2 + 1;
+   19115           0 :       i++;
+   19116           0 :       ind2 += *dtrd2;
+   19117           0 :       n2sv--;
+   19118             :     }
+   19119             :   }
+   19120             : 
+   19121           0 :   if(n1sv==0) {
+   19122           0 :     for(n1sv=1;n1sv<=n2sv;n1sv++) {
+   19123           0 :       index[i] = ind2 + 1;
+   19124           0 :       i++;
+   19125           0 :       ind2 += *dtrd2;
+   19126             :     } 
+   19127             :   } else {
+   19128           0 :     for(n2sv=1;n2sv<=n1sv;n2sv++) {
+   19129           0 :       index[i] = ind1 + 1;
+   19130           0 :       i++;
+   19131           0 :       ind1 += *dtrd1;
+   19132             :     } 
+   19133             :   }
+   19134           0 :   return;
+   19135             : }
+   19136             : }
+   19137             : }
+   19138             : #include <cctype>
+   19139             : #include <cmath>
+   19140             : 
+   19141             : #include "lapack.h"
+   19142             : 
+   19143             : 
+   19144             : #include "blas/blas.h"
+   19145             : namespace PLMD{
+   19146             : namespace lapack{
+   19147             : using namespace blas;
+   19148             : float
+   19149           0 : PLUMED_BLAS_F77_FUNC(slange,SLANGE)(const char *norm,
+   19150             :         int *m,
+   19151             :         int *n,
+   19152             :         float *a,
+   19153             :         int *lda,
+   19154             :         float *work)
+   19155             : {
+   19156           0 :   const char ch=std::toupper(*norm);
+   19157             :   float dtemp,sum,max,val,scale;
+   19158             :   int i,j;
+   19159             : 
+   19160           0 :   switch(ch) {
+   19161             :   case 'M':
+   19162             :     max = 0.0;
+   19163           0 :     for(j=0;j<*n;j++)
+   19164           0 :       for(i=0;i<*m;i++) {
+   19165           0 :         dtemp = std::abs(a[j*(*lda)+i]);
+   19166           0 :         if(dtemp>max)
+   19167             :           max = dtemp;
+   19168             :       }
+   19169             :     val = max;
+   19170             :     break;
+   19171             : 
+   19172             :   case 'O':
+   19173             :   case '1':
+   19174             :     max = 0.0;
+   19175           0 :     for(j=0;j<*n;j++) {
+   19176           0 :       sum = 0.0;
+   19177           0 :       for(i=0;i<*m;i++) 
+   19178           0 :         sum += std::abs(a[j*(*lda)+i]);
+   19179           0 :       if(sum>max)
+   19180             :         max = sum;
+   19181             :     }
+   19182             :     val = max;
+   19183             :     break;
+   19184             : 
+   19185           0 :   case 'I':
+   19186           0 :     for(i=0;i<*m;i++)
+   19187           0 :       work[i] = 0.0;
+   19188           0 :     for(j=0;j<*n;j++)
+   19189           0 :       for(i=0;i<*m;i++)
+   19190           0 :         work[i] += std::abs(a[j*(*lda)+i]);
+   19191             :     max = 0;
+   19192           0 :     for(i=0;i<*m;i++)
+   19193           0 :       if(work[i]>max)
+   19194             :         max=work[i];
+   19195             :     val = max;
+   19196             :     break;
+   19197             : 
+   19198           0 :   case 'F':
+   19199             :   case 'E':
+   19200           0 :     scale = 0.0;
+   19201           0 :     sum   = 1.0;
+   19202           0 :     i = 1;
+   19203           0 :     for(j=0;j<*n;j++) 
+   19204           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(m,&(a[j*(*lda)+0]),&i,&scale,&sum);
+   19205           0 :     val = scale* std::sqrt(sum);
+   19206           0 :     break;
+   19207             : 
+   19208             :   default:
+   19209             :     val = 0.0;
+   19210             :     break;
+   19211             :   }
+   19212           0 :   return val;
+   19213             : }
+   19214             : }
+   19215             : }
+   19216             : #include <cctype>
+   19217             : #include <cmath>
+   19218             : 
+   19219             : #include "lapack.h"
+   19220             : 
+   19221             : 
+   19222             : #include "blas/blas.h"
+   19223             : namespace PLMD{
+   19224             : namespace lapack{
+   19225             : using namespace blas;
+   19226             : float
+   19227           0 : PLUMED_BLAS_F77_FUNC(slanst,SLANST)(const char *norm,
+   19228             :         int *n,
+   19229             :         float *d,
+   19230             :         float *e)
+   19231             : {
+   19232           0 :   const char ch=std::toupper(*norm);
+   19233             :   float dtemp,max,val,scale,sum;
+   19234             :   int i,j;
+   19235             : 
+   19236             : 
+   19237           0 :   if(*n<=0)
+   19238             :     return 0.0;
+   19239             :   
+   19240           0 :   switch(ch) {
+   19241           0 :   case 'M':
+   19242           0 :     max = std::abs(d[*n-1]);
+   19243           0 :       for(i=0;i<(*n-1);i++) {
+   19244           0 :         dtemp = std::abs(d[i]);
+   19245           0 :         if(dtemp>max)
+   19246             :           max = dtemp;
+   19247           0 :         dtemp = std::abs(e[i]);
+   19248           0 :         if(dtemp>max)
+   19249             :           max = dtemp;
+   19250             :       }
+   19251             :     val = max;
+   19252             :     break;
+   19253             :     
+   19254           0 :   case 'O':
+   19255             :   case '1':
+   19256             :   case 'I':
+   19257             : 
+   19258           0 :     if(*n==1)
+   19259           0 :       val = std::abs(d[0]);
+   19260             :     else {
+   19261           0 :       max = std::abs(d[0]) + std::abs(e[0]);
+   19262           0 :       dtemp = std::abs(e[*n-2]) + std::abs(d[*n-1]);
+   19263           0 :       if(dtemp>max)
+   19264             :         max = dtemp;
+   19265           0 :       for(i=1;i<(*n-1);i++) {
+   19266           0 :         dtemp = std::abs(d[i]) + std::abs(e[i]) + std::abs(e[i-1]);
+   19267           0 :         if(dtemp>max)
+   19268             :           max = dtemp;
+   19269             :       }
+   19270             :       val = max;
+   19271             :     }
+   19272             :     break;
+   19273             : 
+   19274           0 :   case 'F':
+   19275             :   case 'E':
+   19276           0 :     scale = 0.0;
+   19277           0 :     sum   = 1.0;
+   19278           0 :     i = *n-1;
+   19279           0 :     j = 1;
+   19280           0 :     if(*n>1) {
+   19281           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i,e,&j,&scale,&sum);
+   19282           0 :       sum *= 2;
+   19283             :     }
+   19284           0 :     PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n,d,&j,&scale,&sum);
+   19285           0 :     val = scale *  std::sqrt(sum);
+   19286           0 :     break;
+   19287             :     
+   19288             :   default:
+   19289             :     val = 0.0;
+   19290             :     break;
+   19291             :   }
+   19292             :   return val;
+   19293             : }
+   19294             : }
+   19295             : }
+   19296             : #include <cmath>
+   19297             : 
+   19298             : 
+   19299             : #include "lapack.h"
+   19300             : 
+   19301             : #include "blas/blas.h"
+   19302             : namespace PLMD{
+   19303             : namespace lapack{
+   19304             : using namespace blas;
+   19305             : float 
+   19306           0 : PLUMED_BLAS_F77_FUNC(slansy,SLANSY)(const char *norm, const char *uplo, int *n, float *a, int 
+   19307             :         *lda, float *work)
+   19308             : {
+   19309             :     /* System generated locals */
+   19310             :     int a_dim1, a_offset, i__1, i__2;
+   19311             :     float ret_val, d__1, d__2, d__3;
+   19312           0 :     int c__1 = 1;
+   19313             : 
+   19314             :     /* Local variables */
+   19315             :     int i__, j;
+   19316             :     float sum, absa, scale;
+   19317             :     float value =0.0;
+   19318             : 
+   19319           0 :     a_dim1 = *lda;
+   19320           0 :     a_offset = 1 + a_dim1;
+   19321           0 :     a -= a_offset;
+   19322           0 :     --work;
+   19323             : 
+   19324           0 :     if (*n == 0) {
+   19325             :         value = 0.;
+   19326           0 :     } else if (*norm=='M' || *norm=='m') {
+   19327             : 
+   19328             :         value = 0.;
+   19329           0 :         if (*uplo=='U' || *uplo=='u') {
+   19330           0 :             i__1 = *n;
+   19331           0 :             for (j = 1; j <= i__1; ++j) {
+   19332             :                 i__2 = j;
+   19333           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19334             :                   d__2 = value;
+   19335           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19336           0 :                   value = (d__2>d__3) ? d__2 : d__3;
+   19337             :                 }
+   19338             :             }
+   19339             :         } else {
+   19340           0 :             i__1 = *n;
+   19341           0 :             for (j = 1; j <= i__1; ++j) {
+   19342             :                 i__2 = *n;
+   19343           0 :                 for (i__ = j; i__ <= i__2; ++i__) {
+   19344             :                   d__2 = value;
+   19345           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19346           0 :                     value =  (d__2>d__3) ? d__2 : d__3;
+   19347             :                 }
+   19348             :             }
+   19349             :         }
+   19350           0 :     } else if (*norm=='I' || *norm=='i' || *norm=='O' || *norm=='o' || *norm=='1') {
+   19351             : 
+   19352             :         value = 0.;
+   19353           0 :         if (*uplo=='U' || *uplo=='u') {
+   19354           0 :             i__1 = *n;
+   19355           0 :             for (j = 1; j <= i__1; ++j) {
+   19356           0 :                 sum = 0.;
+   19357           0 :                 i__2 = j - 1;
+   19358           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19359           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19360           0 :                     sum += absa;
+   19361           0 :                     work[i__] += absa;
+   19362             :                 }
+   19363           0 :                 work[j] = sum + std::abs(a[j + j * a_dim1]);
+   19364             :             }
+   19365           0 :             i__1 = *n;
+   19366           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19367           0 :                 d__1 = value, d__2 = work[i__];
+   19368           0 :                 value =  (d__1>d__2) ? d__1 : d__2;
+   19369             :             }
+   19370             :         } else {
+   19371             :             i__1 = *n;
+   19372           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19373           0 :                 work[i__] = 0.;
+   19374             :             }
+   19375           0 :             i__1 = *n;
+   19376           0 :             for (j = 1; j <= i__1; ++j) {
+   19377           0 :                 sum = work[j] + std::abs(a[j + j * a_dim1]);
+   19378           0 :                 i__2 = *n;
+   19379           0 :                 for (i__ = j + 1; i__ <= i__2; ++i__) {
+   19380           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19381           0 :                     sum += absa;
+   19382           0 :                     work[i__] += absa;
+   19383             :                 }
+   19384           0 :                 if(sum>value)
+   19385             :                   value = sum;
+   19386             :             }
+   19387             :         }
+   19388             :     } else if (*norm=='F' || *norm=='f' || *norm=='E' || *norm=='e') {
+   19389             : 
+   19390           0 :         scale = 0.;
+   19391           0 :         sum = 1.;
+   19392           0 :         if (*uplo=='U' || *uplo=='u') {
+   19393           0 :             i__1 = *n;
+   19394           0 :             for (j = 2; j <= i__1; ++j) {
+   19395           0 :                 i__2 = j - 1;
+   19396           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j * a_dim1 + 1], &c__1, &scale, &sum);
+   19397             :             }
+   19398             :         } else {
+   19399           0 :             i__1 = *n - 1;
+   19400           0 :             for (j = 1; j <= i__1; ++j) {
+   19401           0 :                 i__2 = *n - j;
+   19402           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j + 1 + j * a_dim1], &c__1, &scale, &sum);
+   19403             :             }
+   19404             :         }
+   19405           0 :         sum *= 2;
+   19406           0 :         i__1 = *lda + 1;
+   19407           0 :         PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n, &a[a_offset], &i__1, &scale, &sum);
+   19408           0 :         value = scale *  std::sqrt(sum);
+   19409             :     }
+   19410             : 
+   19411             :     ret_val = value;
+   19412           0 :     return ret_val;
+   19413             : }
+   19414             : 
+   19415             : 
+   19416             : }
+   19417             : }
+   19418             : #include <cmath>
+   19419             : #include "lapack.h"
+   19420             : 
+   19421             : #include "real.h"
+   19422             : 
+   19423             : #include "blas/blas.h"
+   19424             : namespace PLMD{
+   19425             : namespace lapack{
+   19426             : using namespace blas;
+   19427             : float
+   19428           1 : PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(float * x, float * y)
+   19429             : {
+   19430             :   float xabs,yabs;
+   19431             :   float w,z;
+   19432             : 
+   19433           1 :   xabs = std::abs(*x);
+   19434           1 :   yabs = std::abs(*y);
+   19435             :   
+   19436           1 :   if(xabs>yabs) {
+   19437             :     w = xabs;
+   19438             :     z = yabs;
+   19439             :   } else {
+   19440             :     w = yabs;
+   19441             :     z = xabs;
+   19442             :   }
+   19443             : 
+   19444           1 :   if( std::abs(z)<PLUMED_GMX_FLOAT_MIN) 
+   19445             :     return w;
+   19446             :   else {
+   19447           1 :     z = z/w;
+   19448           1 :     return w* std::sqrt(1.0+z*z);
+   19449             :   }
+   19450             : }
+   19451             :   
+   19452             : }
+   19453             : }
+   19454             : #include <cmath>
+   19455             : 
+   19456             : #include "real.h"
+   19457             : 
+   19458             : #include "lapack.h"
+   19459             : #include "lapack_limits.h"
+   19460             : #include "blas/blas.h"
+   19461             : namespace PLMD{
+   19462             : namespace lapack{
+   19463             : using namespace blas;
+   19464             : 
+   19465           0 : void PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(int *n, 
+   19466             :               int *b1, 
+   19467             :               int *bn,
+   19468             :               float *sigma, 
+   19469             :               float *d__, 
+   19470             :               float *l, 
+   19471             :               float *ld, 
+   19472             :               float *lld, 
+   19473             :               float *eval, 
+   19474             :               float *gersch, 
+   19475             :               float *z__, 
+   19476             :               float *ztz, 
+   19477             :               float *mingma, 
+   19478             :               int *r__, 
+   19479             :               int *isuppz, 
+   19480             :               float *work)
+   19481             : {
+   19482             :     int i__1;
+   19483             : 
+   19484             :     int i__, j;
+   19485             :     float s;
+   19486             :     int r1, r2;
+   19487             :     int to;
+   19488             :     float eps, tmp;
+   19489             :     int indp, inds, from;
+   19490             :     float dplus;
+   19491             :     int sawnan;
+   19492             :     int indumn;
+   19493             :     float dminus;
+   19494             : 
+   19495           0 :     --work;
+   19496             :     --isuppz;
+   19497           0 :     --z__;
+   19498           0 :     --gersch;
+   19499           0 :     --lld;
+   19500           0 :     --ld;
+   19501           0 :     --l;
+   19502           0 :     --d__;
+   19503             : 
+   19504             :     /* Function Body */
+   19505             :     eps = PLUMED_GMX_FLOAT_EPS;
+   19506           0 :     if (*r__ == 0) {
+   19507             : 
+   19508           0 :         r1 = *b1;
+   19509           0 :         r2 = *bn;
+   19510             :         i__1 = *bn;
+   19511           0 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+   19512           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19513             :                 r1 = i__;
+   19514           0 :                 goto L20;
+   19515             :             }
+   19516             :         }
+   19517           0 :         goto L40;
+   19518             : L20:
+   19519             :         i__1 = *b1;
+   19520           0 :         for (i__ = *bn; i__ >= i__1; --i__) {
+   19521           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19522             :                 r2 = i__;
+   19523           0 :                 goto L40;
+   19524             :             }
+   19525             :         }
+   19526             :     } else {
+   19527             :         r1 = *r__;
+   19528             :         r2 = *r__;
+   19529             :     }
+   19530             : 
+   19531           0 : L40:
+   19532           0 :     indumn = *n;
+   19533           0 :     inds = (*n << 1) + 1;
+   19534           0 :     indp = *n * 3 + 1;
+   19535             :     sawnan = 0;
+   19536             : 
+   19537           0 :     if (*b1 == 1) {
+   19538           0 :         work[inds] = 0.;
+   19539             :     } else {
+   19540           0 :         work[inds] = lld[*b1 - 1];
+   19541             :     }
+   19542           0 :     s = work[inds] - *sigma;
+   19543             :     i__1 = r2 - 1;
+   19544           0 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+   19545           0 :         dplus = d__[i__] + s;
+   19546           0 :         work[i__] = ld[i__] / dplus;
+   19547           0 :         work[inds + i__] = s * work[i__] * l[i__];
+   19548           0 :         s = work[inds + i__] - *sigma;
+   19549             :     }
+   19550             : 
+   19551           0 :     if (std::isnan(s)) {
+   19552             : 
+   19553             :         sawnan = 1;
+   19554           0 :         j = *b1 + 1;
+   19555           0 : L60:
+   19556           0 :     if (!std::isnan(work[inds + j])) {
+   19557           0 :             ++j;
+   19558           0 :             goto L60;
+   19559             :         }
+   19560           0 :         work[inds + j] = lld[j];
+   19561           0 :         s = work[inds + j] - *sigma;
+   19562             :         i__1 = r2 - 1;
+   19563           0 :         for (i__ = j + 1; i__ <= i__1; ++i__) {
+   19564           0 :             dplus = d__[i__] + s;
+   19565           0 :             work[i__] = ld[i__] / dplus;
+   19566           0 :             if (std::abs(work[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19567           0 :                 work[inds + i__] = lld[i__];
+   19568             :             } else {
+   19569           0 :                 work[inds + i__] = s * work[i__] * l[i__];
+   19570             :             }
+   19571           0 :             s = work[inds + i__] - *sigma;
+   19572             :         }
+   19573             :     }
+   19574             : 
+   19575           0 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+   19576             :     i__1 = r1;
+   19577           0 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+   19578           0 :         dminus = lld[i__] + work[indp + i__];
+   19579           0 :         tmp = d__[i__] / dminus;
+   19580           0 :         work[indumn + i__] = l[i__] * tmp;
+   19581           0 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19582             :     }
+   19583           0 :     tmp = work[indp + r1 - 1];
+   19584           0 :     if (std::isnan(tmp)) {
+   19585             : 
+   19586             :         sawnan = 1;
+   19587           0 :         j = *bn - 3;
+   19588           0 : L90:
+   19589           0 :     if (!std::isnan(work[indp + j])) {
+   19590           0 :             --j;
+   19591           0 :             goto L90;
+   19592             :         }
+   19593           0 :         work[indp + j] = d__[j + 1] - *sigma;
+   19594             :         i__1 = r1;
+   19595           0 :         for (i__ = j; i__ >= i__1; --i__) {
+   19596           0 :             dminus = lld[i__] + work[indp + i__];
+   19597           0 :             tmp = d__[i__] / dminus;
+   19598           0 :             work[indumn + i__] = l[i__] * tmp;
+   19599           0 :             if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19600           0 :                 work[indp + i__ - 1] = d__[i__] - *sigma;
+   19601             :             } else {
+   19602           0 :                 work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19603             :             }
+   19604             :         }
+   19605             :     }
+   19606             : 
+   19607           0 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+   19608           0 :     if (std::abs(*mingma)<PLUMED_GMX_FLOAT_MIN) {
+   19609           0 :         *mingma = eps * work[inds + r1 - 1];
+   19610             :     }
+   19611           0 :     *r__ = r1;
+   19612             :     i__1 = r2 - 1;
+   19613           0 :     for (i__ = r1; i__ <= i__1; ++i__) {
+   19614           0 :         tmp = work[inds + i__] + work[indp + i__];
+   19615           0 :         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19616           0 :             tmp = eps * work[inds + i__];
+   19617             :         }
+   19618           0 :         if (std::abs(tmp) < std::abs(*mingma)) {
+   19619           0 :             *mingma = tmp;
+   19620           0 :             *r__ = i__ + 1;
+   19621             :         }
+   19622             :     }
+   19623             : 
+   19624           0 :     isuppz[1] = *b1;
+   19625           0 :     isuppz[2] = *bn;
+   19626           0 :     z__[*r__] = 1.;
+   19627           0 :     *ztz = 1.;
+   19628           0 :     if (! sawnan) {
+   19629           0 :         from = *r__ - 1;
+   19630           0 :         i__1 = *r__ - 32;
+   19631           0 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+   19632             : L120:
+   19633           0 :         if (from >= *b1) {
+   19634             :             i__1 = to;
+   19635           0 :             for (i__ = from; i__ >= i__1; --i__) {
+   19636           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19637           0 :                 *ztz += z__[i__] * z__[i__];
+   19638             :             }
+   19639           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+   19640           0 :                 isuppz[1] = to + 2;
+   19641             :             } else {
+   19642           0 :                 from = to - 1;
+   19643           0 :                 i__1 = to - 32;
+   19644           0 :                 to = (i__1>*b1) ? i__1 : *b1;
+   19645           0 :                 goto L120;
+   19646             :             }
+   19647             :         }
+   19648           0 :         from = *r__ + 1;
+   19649           0 :         i__1 = *r__ + 32;
+   19650           0 :         to = (i__1<*bn) ? i__1 : *bn;
+   19651             : L140:
+   19652           0 :         if (from <= *bn) {
+   19653             :             i__1 = to;
+   19654           0 :             for (i__ = from; i__ <= i__1; ++i__) {
+   19655           0 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+   19656           0 :                 *ztz += z__[i__] * z__[i__];
+   19657             :             }
+   19658           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+   19659           0 :                 isuppz[2] = to - 2;
+   19660             :             } else {
+   19661           0 :                 from = to + 1;
+   19662           0 :                 i__1 = to + 32;
+   19663           0 :                 to = (i__1<*bn) ? i__1 : *bn;
+   19664           0 :                 goto L140;
+   19665             :             }
+   19666             :         }
+   19667             :     } else {
+   19668           0 :         i__1 = *b1;
+   19669           0 :         for (i__ = *r__ - 1; i__ >= i__1; --i__) {
+   19670           0 :             if (std::abs(z__[i__ + 1])<PLUMED_GMX_FLOAT_MIN) {
+   19671           0 :                 z__[i__] = -(ld[i__ + 1] / ld[i__]) * z__[i__ + 2];
+   19672             :             } else {
+   19673           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19674             :             }
+   19675           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19676           0 :                 isuppz[1] = i__ + 2;
+   19677           0 :                 goto L170;
+   19678             :             }
+   19679           0 :             *ztz += z__[i__] * z__[i__];
+   19680             :         }
+   19681           0 : L170:
+   19682           0 :         i__1 = *bn - 1;
+   19683           0 :         for (i__ = *r__; i__ <= i__1; ++i__) {
+   19684           0 :             if (std::abs(z__[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19685           0 :                 z__[i__ + 1] = -(ld[i__ - 1] / ld[i__]) * z__[i__ - 1];
+   19686             :             } else {
+   19687           0 :                 z__[i__ + 1] = -(work[indumn + i__] * z__[i__]);
+   19688             :             }
+   19689           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19690           0 :                 isuppz[2] = i__ - 1;
+   19691           0 :                 break;
+   19692             :             }
+   19693           0 :             *ztz += z__[i__ + 1] * z__[i__ + 1];
+   19694             :         }
+   19695             :     }
+   19696             : 
+   19697           0 :     return;
+   19698             : 
+   19699             : }
+   19700             : 
+   19701             : 
+   19702             : }
+   19703             : }
+   19704             : #include <cctype>
+   19705             : #include <cmath>
+   19706             : 
+   19707             : #include "blas/blas.h"
+   19708             : #include "lapack.h"
+   19709             : 
+   19710             : #include "real.h"
+   19711             : 
+   19712             : #include "blas/blas.h"
+   19713             : namespace PLMD{
+   19714             : namespace lapack{
+   19715             : using namespace blas;
+   19716             : void
+   19717           0 : PLUMED_BLAS_F77_FUNC(slarf,SLARF)(const char *side,
+   19718             :        int *m,
+   19719             :        int *n,
+   19720             :        float *v,
+   19721             :        int *incv,
+   19722             :        float *tau,
+   19723             :        float *c,
+   19724             :        int *ldc,
+   19725             :        float *work)
+   19726             : {
+   19727           0 :   const char ch=std::toupper(*side);
+   19728           0 :   float one = 1.0;
+   19729           0 :   float zero = 0.0;
+   19730           0 :   float minustau = -(*tau);
+   19731           0 :   int i1 = 1;
+   19732             : 
+   19733             : 
+   19734           0 :   if(ch=='L') {
+   19735           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19736           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19737           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,v,incv,work,&i1,c,ldc);
+   19738             :     }
+   19739             :   } else {
+   19740           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19741           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19742           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,work,&i1,v,incv,c,ldc);
+   19743             :     }
+   19744             :   }
+   19745           0 :   return;
+   19746             : }
+   19747             : }
+   19748             : }
+   19749             : #include "blas/blas.h"
+   19750             : #include "lapack.h"
+   19751             : 
+   19752             : 
+   19753             : #include "blas/blas.h"
+   19754             : namespace PLMD{
+   19755             : namespace lapack{
+   19756             : using namespace blas;
+   19757             : void 
+   19758           0 : PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(const char *side, 
+   19759             :         const char *trans, 
+   19760             :         const char *direct, 
+   19761             :         const char *storev, 
+   19762             :         int *m, 
+   19763             :         int *n, 
+   19764             :         int *k, 
+   19765             :         float *v, 
+   19766             :         int *ldv, 
+   19767             :         float *t, 
+   19768             :         int *ldt, 
+   19769             :         float *c__,
+   19770             :         int *ldc, 
+   19771             :         float *work, 
+   19772             :         int *ldwork)
+   19773             : {
+   19774             :     int c_dim1, c_offset, t_dim1, t_offset, v_dim1, v_offset, work_dim1, 
+   19775             :             work_offset, i__1, i__2;
+   19776             : 
+   19777             :     int i__, j;
+   19778             :     char transt[1];
+   19779           0 :     int c__1 = 1;
+   19780           0 :     float one = 1.0;
+   19781           0 :     float minusone = -1.0;
+   19782             : 
+   19783           0 :     v_dim1 = *ldv;
+   19784           0 :     v_offset = 1 + v_dim1;
+   19785           0 :     v -= v_offset;
+   19786             :     t_dim1 = *ldt;
+   19787             :     t_offset = 1 + t_dim1;
+   19788             :     t -= t_offset;
+   19789           0 :     c_dim1 = *ldc;
+   19790           0 :     c_offset = 1 + c_dim1;
+   19791           0 :     c__ -= c_offset;
+   19792           0 :     work_dim1 = *ldwork;
+   19793           0 :     work_offset = 1 + work_dim1;
+   19794           0 :     work -= work_offset;
+   19795             : 
+   19796           0 :     if (*m <= 0 || *n <= 0) {
+   19797             :         return;
+   19798             :     }
+   19799           0 :     if (*trans=='N' || *trans=='n') {
+   19800           0 :       *(unsigned char *)transt = 'T';
+   19801             :     } else {
+   19802           0 :         *(unsigned char *)transt = 'N';
+   19803             :     }
+   19804             :     
+   19805           0 :     if (*storev=='C' || *storev=='c') {
+   19806             : 
+   19807           0 :         if (*direct=='F' || *direct=='f') {
+   19808           0 :           if (*side=='l' || *side=='L') {
+   19809             : 
+   19810           0 :                 i__1 = *k;
+   19811           0 :                 for (j = 1; j <= i__1; ++j) {
+   19812           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19813             :                              &c__1);
+   19814             :                 }
+   19815             : 
+   19816           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   19817             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19818           0 :                 if (*m > *k) {
+   19819             : 
+   19820           0 :                     i__1 = *m - *k;
+   19821           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19822           0 :                             c__[*k + 1 + c_dim1], ldc, &v[*k + 1 + v_dim1], 
+   19823             :                             ldv, &one, &work[work_offset], ldwork);
+   19824             :                 }
+   19825             : 
+   19826           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19827             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19828             : 
+   19829           0 :                 if (*m > *k) {
+   19830           0 :                     i__1 = *m - *k;
+   19831           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19832           0 :                             v[*k + 1 + v_dim1], ldv, &work[work_offset], 
+   19833           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19834             :                 }
+   19835             : 
+   19836           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   19837             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19838             : 
+   19839           0 :                 i__1 = *k;
+   19840           0 :                 for (j = 1; j <= i__1; ++j) {
+   19841           0 :                     i__2 = *n;
+   19842           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19843           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   19844             :                     }
+   19845             :                 }
+   19846             : 
+   19847           0 :             } else if (*side=='r' || *side=='R') {
+   19848             : 
+   19849           0 :                 i__1 = *k;
+   19850           0 :                 for (j = 1; j <= i__1; ++j) {
+   19851           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   19852           0 :                             work_dim1 + 1], &c__1);
+   19853             :                 }
+   19854             : 
+   19855           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   19856             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19857           0 :                 if (*n > *k) {
+   19858             : 
+   19859           0 :                     i__1 = *n - *k;
+   19860           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19861           0 :                             one, &c__[(*k + 1) * c_dim1 + 1], ldc, &v[*k + 
+   19862           0 :                             1 + v_dim1], ldv, &one, &work[work_offset], 
+   19863             :                             ldwork);
+   19864             :                 }
+   19865             : 
+   19866           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   19867             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19868             : 
+   19869           0 :                 if (*n > *k) {
+   19870           0 :                     i__1 = *n - *k;
+   19871           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19872           0 :                             work[work_offset], ldwork, &v[*k + 1 + v_dim1], 
+   19873           0 :                             ldv, &one, &c__[(*k + 1) * c_dim1 + 1], ldc);
+   19874             :                 }
+   19875             : 
+   19876           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   19877             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19878             : 
+   19879           0 :                 i__1 = *k;
+   19880           0 :                 for (j = 1; j <= i__1; ++j) {
+   19881           0 :                     i__2 = *m;
+   19882           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19883           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   19884             :                     }
+   19885             :                 }
+   19886             :             }
+   19887             : 
+   19888             :         } else {
+   19889             : 
+   19890           0 :           if (*side=='l' || *side=='L') {
+   19891           0 :                 i__1 = *k;
+   19892           0 :                 for (j = 1; j <= i__1; ++j) {
+   19893           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   19894           0 :                             work_dim1 + 1], &c__1);
+   19895             :                 }
+   19896             : 
+   19897           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19898           0 :                          &v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19899             :                         ldwork);
+   19900           0 :                 if (*m > *k) {
+   19901           0 :                     i__1 = *m - *k;
+   19902           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19903             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   19904             :                             work[work_offset], ldwork);
+   19905             :                 }
+   19906             : 
+   19907           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   19908             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19909             : 
+   19910           0 :                 if (*m > *k) {
+   19911             : 
+   19912           0 :                     i__1 = *m - *k;
+   19913           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19914             :                             v[v_offset], ldv, &work[work_offset], ldwork, &
+   19915             :                             one, &c__[c_offset], ldc)
+   19916             :                             ;
+   19917             :                 }
+   19918             : 
+   19919           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19920           0 :                         v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19921             :                         ldwork);
+   19922             : 
+   19923           0 :                 i__1 = *k;
+   19924           0 :                 for (j = 1; j <= i__1; ++j) {
+   19925           0 :                     i__2 = *n;
+   19926           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19927           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   19928           0 :                                 work_dim1];
+   19929             :                     }
+   19930             :                 }
+   19931             : 
+   19932           0 :             } else if (*side=='r' || *side=='R') {
+   19933           0 :                 i__1 = *k;
+   19934           0 :                 for (j = 1; j <= i__1; ++j) {
+   19935           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   19936           0 :                             j * work_dim1 + 1], &c__1);
+   19937             :                 }
+   19938             : 
+   19939           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   19940           0 :                          &v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19941             :                         ldwork);
+   19942           0 :                 if (*n > *k) {
+   19943           0 :                     i__1 = *n - *k;
+   19944           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19945             :                             one, &c__[c_offset], ldc, &v[v_offset], ldv, &
+   19946             :                             one, &work[work_offset], ldwork);
+   19947             :                 }
+   19948           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   19949             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19950           0 :                 if (*n > *k) {
+   19951           0 :                     i__1 = *n - *k;
+   19952           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19953             :                             work[work_offset], ldwork, &v[v_offset], ldv, &
+   19954             :                             one, &c__[c_offset], ldc)
+   19955             :                             ;
+   19956             :                 }
+   19957           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   19958           0 :                         v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19959             :                         ldwork);
+   19960           0 :                 i__1 = *k;
+   19961           0 :                 for (j = 1; j <= i__1; ++j) {
+   19962           0 :                     i__2 = *m;
+   19963           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19964           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   19965           0 :                                 work_dim1];
+   19966             :                     }
+   19967             :                 }
+   19968             :             }
+   19969             :         }
+   19970             : 
+   19971           0 :     } else  if (*storev=='r' || *storev=='R') {
+   19972           0 :       if (*direct=='F' || *direct=='f') {
+   19973           0 :           if (*side=='l' || *side=='L') {
+   19974           0 :                 i__1 = *k;
+   19975           0 :                 for (j = 1; j <= i__1; ++j) {
+   19976           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19977             :                              &c__1);
+   19978             :                 }
+   19979           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19980             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19981           0 :                 if (*m > *k) {
+   19982           0 :                     i__1 = *m - *k;
+   19983           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   19984           0 :                             c__[*k + 1 + c_dim1], ldc, &v[(*k + 1) * v_dim1 + 
+   19985           0 :                             1], ldv, &one, &work[work_offset], ldwork);
+   19986             :                 }
+   19987             : 
+   19988           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19989             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19990           0 :                 if (*m > *k) {
+   19991             : 
+   19992           0 :                     i__1 = *m - *k;
+   19993           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[(
+   19994           0 :                             *k + 1) * v_dim1 + 1], ldv, &work[work_offset], 
+   19995           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19996             :                 }
+   19997             : 
+   19998           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19999             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20000             : 
+   20001           0 :                 i__1 = *k;
+   20002           0 :                 for (j = 1; j <= i__1; ++j) {
+   20003           0 :                     i__2 = *n;
+   20004           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20005           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   20006             :                     }
+   20007             :                 }
+   20008             : 
+   20009           0 :             } else if (*side=='r' || *side=='R') {
+   20010             : 
+   20011           0 :                 i__1 = *k;
+   20012           0 :                 for (j = 1; j <= i__1; ++j) {
+   20013           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   20014           0 :                             work_dim1 + 1], &c__1);
+   20015             :                 }
+   20016             : 
+   20017           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   20018             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   20019           0 :                 if (*n > *k) {
+   20020             : 
+   20021           0 :                     i__1 = *n - *k;
+   20022           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20023           0 :                             c__[(*k + 1) * c_dim1 + 1], ldc, &v[(*k + 1) * 
+   20024           0 :                             v_dim1 + 1], ldv, &one, &work[work_offset], 
+   20025             :                             ldwork);
+   20026             :                 }
+   20027             : 
+   20028           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   20029             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20030             : 
+   20031           0 :                 if (*n > *k) {
+   20032             : 
+   20033           0 :                     i__1 = *n - *k;
+   20034           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20035           0 :                             minusone, &work[work_offset], ldwork, &v[(*k + 1) * 
+   20036           0 :                             v_dim1 + 1], ldv, &one, &c__[(*k + 1) * c_dim1 
+   20037           0 :                             + 1], ldc);
+   20038             :                 }
+   20039           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   20040             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20041           0 :                 i__1 = *k;
+   20042           0 :                 for (j = 1; j <= i__1; ++j) {
+   20043           0 :                     i__2 = *m;
+   20044           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20045           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   20046             :                     }
+   20047             :                 }
+   20048             : 
+   20049             :             }
+   20050             : 
+   20051             :         } else {
+   20052             : 
+   20053           0 :             if (*side=='l' || *side=='L') {
+   20054             : 
+   20055           0 :                 i__1 = *k;
+   20056           0 :                 for (j = 1; j <= i__1; ++j) {
+   20057           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   20058           0 :                             work_dim1 + 1], &c__1);
+   20059             :                 }
+   20060             : 
+   20061           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   20062           0 :                         v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20063             :                         , ldwork);
+   20064           0 :                 if (*m > *k) {
+   20065             : 
+   20066           0 :                     i__1 = *m - *k;
+   20067           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   20068             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20069             :                             work[work_offset], ldwork);
+   20070             :                 }
+   20071             : 
+   20072           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   20073             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20074             : 
+   20075           0 :                 if (*m > *k) {
+   20076             : 
+   20077           0 :                     i__1 = *m - *k;
+   20078           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[
+   20079             :                             v_offset], ldv, &work[work_offset], ldwork, &
+   20080             :                             one, &c__[c_offset], ldc);
+   20081             :                 }
+   20082             : 
+   20083           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   20084           0 :                          &v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[
+   20085             :                         work_offset], ldwork);
+   20086             : 
+   20087           0 :                 i__1 = *k;
+   20088           0 :                 for (j = 1; j <= i__1; ++j) {
+   20089           0 :                     i__2 = *n;
+   20090           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20091           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   20092           0 :                                 work_dim1];
+   20093             :                     }
+   20094             :                 }
+   20095             : 
+   20096           0 :             } else if (*side=='r' || *side=='R') {
+   20097             : 
+   20098           0 :                 i__1 = *k;
+   20099           0 :                 for (j = 1; j <= i__1; ++j) {
+   20100           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   20101           0 :                             j * work_dim1 + 1], &c__1);
+   20102             :                 }
+   20103             : 
+   20104           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   20105           0 :                         v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20106             :                         , ldwork);
+   20107           0 :                 if (*n > *k) {
+   20108             : 
+   20109           0 :                     i__1 = *n - *k;
+   20110           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20111             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20112             :                             work[work_offset], ldwork);
+   20113             :                 }
+   20114             : 
+   20115           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   20116             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20117             : 
+   20118           0 :                 if (*n > *k) {
+   20119             : 
+   20120           0 :                     i__1 = *n - *k;
+   20121           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20122             :                             minusone, &work[work_offset], ldwork, &v[v_offset], 
+   20123             :                             ldv, &one, &c__[c_offset], ldc);
+   20124             :                 }
+   20125             : 
+   20126           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   20127           0 :                          &v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[
+   20128             :                         work_offset], ldwork);
+   20129             : 
+   20130           0 :                 i__1 = *k;
+   20131           0 :                 for (j = 1; j <= i__1; ++j) {
+   20132           0 :                     i__2 = *m;
+   20133           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20134           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   20135           0 :                                 work_dim1];
+   20136             :                     }
+   20137             :                 }
+   20138             : 
+   20139             :             }
+   20140             : 
+   20141             :         }
+   20142             :     }
+   20143             : 
+   20144             :     return;
+   20145             : 
+   20146             : 
+   20147             : }
+   20148             : 
+   20149             : }
+   20150             : }
+   20151             : #include <cmath>
+   20152             : #include "real.h"
+   20153             : 
+   20154             : #include "blas/blas.h"
+   20155             : #include "lapack.h"
+   20156             : #include "lapack_limits.h"
+   20157             : 
+   20158             : 
+   20159             : #include "blas/blas.h"
+   20160             : namespace PLMD{
+   20161             : namespace lapack{
+   20162             : using namespace blas;
+   20163             : void
+   20164           0 : PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(int   *n,
+   20165             :                         float *alpha,
+   20166             :                         float *x,
+   20167             :                         int    *incx,
+   20168             :                         float *tau)
+   20169             : {
+   20170             :   float xnorm,t;
+   20171             :   int    ti1,knt,j;
+   20172             :   float minval,safmin,rsafmn,beta;
+   20173             : 
+   20174           0 :   if(*n<=1) {
+   20175           0 :     *tau = 0;
+   20176           0 :     return;
+   20177             :   }
+   20178             : 
+   20179           0 :   ti1 = *n-1;
+   20180             : 
+   20181           0 :   xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20182             : 
+   20183           0 :   if(std::abs(xnorm)<PLUMED_GMX_FLOAT_MIN) {
+   20184           0 :     *tau = 0.0;
+   20185             :   } else {
+   20186             : 
+   20187           0 :     t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20188             : 
+   20189           0 :     if(*alpha<0)
+   20190             :       beta = t;
+   20191             :     else
+   20192           0 :       beta = -t;
+   20193             : 
+   20194             :     minval = PLUMED_GMX_FLOAT_MIN;
+   20195             :     
+   20196             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS) / PLUMED_GMX_FLOAT_EPS;
+   20197             : 
+   20198             :         
+   20199           0 :     if(std::abs(beta)<safmin) {
+   20200             : 
+   20201             :       knt = 0;
+   20202           0 :       rsafmn = 1.0 / safmin;
+   20203             :       
+   20204           0 :       while(std::abs(beta)<safmin) {
+   20205           0 :         knt++;
+   20206           0 :         ti1 = *n-1;
+   20207           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&rsafmn,x,incx);
+   20208           0 :         beta *= rsafmn;
+   20209           0 :         *alpha *= rsafmn;
+   20210             :       }
+   20211             :       
+   20212             :       /* safmin <= beta <= 1 now */
+   20213           0 :       ti1 = *n-1;
+   20214           0 :       xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20215           0 :       t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20216             :       
+   20217           0 :       if(*alpha<0)
+   20218             :         beta = t;
+   20219             :       else
+   20220           0 :         beta = -t;
+   20221             :       
+   20222           0 :       *tau = (beta-*alpha)/beta;
+   20223             : 
+   20224           0 :       ti1= *n-1;
+   20225           0 :       t = 1.0/(*alpha-beta);
+   20226           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20227             :    
+   20228           0 :       *alpha = beta;
+   20229           0 :       for(j=0;j<knt;j++)
+   20230           0 :         *alpha *= safmin;
+   20231             :     } else {
+   20232           0 :       *tau = (beta-*alpha)/beta;
+   20233           0 :       ti1= *n-1;
+   20234           0 :       t = 1.0/(*alpha-beta);
+   20235           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20236           0 :       *alpha = beta;
+   20237             :     }
+   20238             :   }
+   20239             :    
+   20240             :   return;
+   20241             : }
+   20242             : }
+   20243             : }
+   20244             : #include <cmath>
+   20245             : #include "real.h"
+   20246             : 
+   20247             : #include "blas/blas.h"
+   20248             : #include "lapack.h"
+   20249             : 
+   20250             : #include "blas/blas.h"
+   20251             : namespace PLMD{
+   20252             : namespace lapack{
+   20253             : using namespace blas;
+   20254             : void 
+   20255           0 : PLUMED_BLAS_F77_FUNC(slarft,SLARFT)(const char *direct, 
+   20256             :         const char *storev, 
+   20257             :         int *n, 
+   20258             :         int *k, 
+   20259             :         float *v, 
+   20260             :         int *ldv, 
+   20261             :         float *tau, 
+   20262             :         float *t, 
+   20263             :         int *ldt)
+   20264             : {
+   20265             :     /* System generated locals */
+   20266             :     int t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3;
+   20267             :     float d__1;
+   20268             : 
+   20269             :     /* Local variables */
+   20270             :     int i__, j;
+   20271             :     float vii;
+   20272           0 :     int c__1 = 1;
+   20273           0 :     float zero = 0.0;
+   20274             : 
+   20275           0 :     v_dim1 = *ldv;
+   20276           0 :     v_offset = 1 + v_dim1;
+   20277           0 :     v -= v_offset;
+   20278           0 :     --tau;
+   20279           0 :     t_dim1 = *ldt;
+   20280           0 :     t_offset = 1 + t_dim1;
+   20281           0 :     t -= t_offset;
+   20282             : 
+   20283           0 :     if (*n == 0) {
+   20284             :         return;
+   20285             :     }
+   20286             : 
+   20287           0 :     if (*direct=='F' || *direct=='f') {
+   20288           0 :         i__1 = *k;
+   20289           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   20290           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20291             : 
+   20292           0 :                 i__2 = i__;
+   20293           0 :                 for (j = 1; j <= i__2; ++j) {
+   20294           0 :                     t[j + i__ * t_dim1] = 0.;
+   20295             :                 }
+   20296             :             } else {
+   20297             : 
+   20298           0 :                 vii = v[i__ + i__ * v_dim1];
+   20299           0 :                 v[i__ + i__ * v_dim1] = 1.;
+   20300           0 :                 if (*storev=='C' || *storev=='c') {
+   20301             : 
+   20302           0 :                     i__2 = *n - i__ + 1;
+   20303           0 :                     i__3 = i__ - 1;
+   20304           0 :                     d__1 = -tau[i__];
+   20305           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &d__1, &v[i__ + v_dim1],
+   20306             :                              ldv, &v[i__ + i__ * v_dim1], &c__1, &zero, &t[
+   20307           0 :                             i__ * t_dim1 + 1], &c__1);
+   20308             :                 } else {
+   20309             : 
+   20310           0 :                     i__2 = i__ - 1;
+   20311           0 :                     i__3 = *n - i__ + 1;
+   20312           0 :                     d__1 = -tau[i__];
+   20313           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &d__1, &v[i__ * 
+   20314           0 :                             v_dim1 + 1], ldv, &v[i__ + i__ * v_dim1], ldv, &
+   20315           0 :                             zero, &t[i__ * t_dim1 + 1], &c__1);
+   20316             :                 }
+   20317           0 :                 v[i__ + i__ * v_dim1] = vii;
+   20318             : 
+   20319             : 
+   20320           0 :                 i__2 = i__ - 1;
+   20321           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", "Non-unit", &i__2, &t[
+   20322           0 :                         t_offset], ldt, &t[i__ * t_dim1 + 1], &c__1);
+   20323           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20324             :             }
+   20325             :         }
+   20326             :     } else {
+   20327           0 :         for (i__ = *k; i__ >= 1; --i__) {
+   20328           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20329             : 
+   20330           0 :                 i__1 = *k;
+   20331           0 :                 for (j = i__; j <= i__1; ++j) {
+   20332           0 :                     t[j + i__ * t_dim1] = 0.;
+   20333             :                 }
+   20334             :             } else {
+   20335             : 
+   20336           0 :                 if (i__ < *k) {
+   20337           0 :                     if (*storev=='C' || *storev=='c') {
+   20338           0 :                         vii = v[*n - *k + i__ + i__ * v_dim1];
+   20339           0 :                         v[*n - *k + i__ + i__ * v_dim1] = 1.;
+   20340             : 
+   20341           0 :                         i__1 = *n - *k + i__;
+   20342           0 :                         i__2 = *k - i__;
+   20343           0 :                         d__1 = -tau[i__];
+   20344           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__1, &i__2, &d__1, &v[(i__ + 1) 
+   20345           0 :                                 * v_dim1 + 1], ldv, &v[i__ * v_dim1 + 1], &
+   20346           0 :                                 c__1, &zero, &t[i__ + 1 + i__ * t_dim1], &
+   20347             :                                 c__1);
+   20348           0 :                         v[*n - *k + i__ + i__ * v_dim1] = vii;
+   20349             :                     } else {
+   20350           0 :                         vii = v[i__ + (*n - *k + i__) * v_dim1];
+   20351           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = 1.;
+   20352             : 
+   20353           0 :                         i__1 = *k - i__;
+   20354           0 :                         i__2 = *n - *k + i__;
+   20355           0 :                         d__1 = -tau[i__];
+   20356           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__1, &i__2, &d__1, &v[i__ + 
+   20357           0 :                                 1 + v_dim1], ldv, &v[i__ + v_dim1], ldv, &
+   20358           0 :                                 zero, &t[i__ + 1 + i__ * t_dim1], &c__1);
+   20359           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = vii;
+   20360             :                     }
+   20361             : 
+   20362           0 :                     i__1 = *k - i__;
+   20363           0 :                     PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", "Non-unit", &i__1, &t[i__ 
+   20364           0 :                             + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
+   20365           0 :                              t_dim1], &c__1)
+   20366             :                             ;
+   20367             :                 }
+   20368           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20369             :             }
+   20370             :         }
+   20371             :     }
+   20372             :     return;
+   20373             : 
+   20374             : 
+   20375             : }
+   20376             : }
+   20377             : }
+   20378             : #include <cmath>
+   20379             : #include "lapack.h"
+   20380             : 
+   20381             : #include "blas/blas.h"
+   20382             : namespace PLMD{
+   20383             : namespace lapack{
+   20384             : using namespace blas;
+   20385             : void
+   20386           0 : PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(int *idist, 
+   20387             :         int *iseed, 
+   20388             :         int *n, 
+   20389             :         float *x)
+   20390             : {
+   20391             :     int i__1, i__2, i__3;
+   20392             : 
+   20393             :     int i__;
+   20394             :     float u[128];
+   20395             :     int il, iv, il2;
+   20396             : 
+   20397           0 :     --x;
+   20398             :     --iseed;
+   20399             : 
+   20400           0 :     i__1 = *n;
+   20401           0 :     for (iv = 1; iv <= i__1; iv += 64) {
+   20402           0 :         i__2 = 64, i__3 = *n - iv + 1;
+   20403             :         il = (i__2<i__3) ? i__2 : i__3;
+   20404           0 :         if (*idist == 3) {
+   20405           0 :             il2 = il << 1;
+   20406             :         } else {
+   20407           0 :             il2 = il;
+   20408             :         }
+   20409             : 
+   20410           0 :         PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(&iseed[1], &il2, u);
+   20411             : 
+   20412           0 :         if (*idist == 1) {
+   20413             : 
+   20414             :             i__2 = il;
+   20415           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20416           0 :                 x[iv + i__ - 1] = u[i__ - 1];
+   20417             :             }
+   20418           0 :         } else if (*idist == 2) {
+   20419             : 
+   20420             :             i__2 = il;
+   20421           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20422           0 :                 x[iv + i__ - 1] = u[i__ - 1] * 2. - 1.;
+   20423             :             }
+   20424           0 :         } else if (*idist == 3) {
+   20425             : 
+   20426             :             i__2 = il;
+   20427           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20428           0 :                 x[iv + i__ - 1] =  std::sqrt(std::log(u[(i__ << 1) - 2]) * -2.) * 
+   20429           0 :                   std::cos(u[(i__ << 1) - 1] * (float)6.2831853071795864769252867663);
+   20430             :             }
+   20431             :         }
+   20432             :     }
+   20433           0 :     return;
+   20434             : 
+   20435             : }
+   20436             : }
+   20437             : }
+   20438             : #include <cmath>
+   20439             : 
+   20440             : #include "real.h"
+   20441             : 
+   20442             : #include "lapack.h"
+   20443             : #include "lapack_limits.h"
+   20444             : 
+   20445             : #include "blas/blas.h"
+   20446             : namespace PLMD{
+   20447             : namespace lapack{
+   20448             : using namespace blas;
+   20449             : void
+   20450           0 : PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(int *n, 
+   20451             :          float *d__, 
+   20452             :          float *l, 
+   20453             :          float *ld, 
+   20454             :          float *lld, 
+   20455             :          int *ifirst, 
+   20456             :          int *ilast, 
+   20457             :          float *rtol1, 
+   20458             :          float *rtol2, 
+   20459             :          int *offset, 
+   20460             :          float *w, 
+   20461             :          float *wgap, 
+   20462             :          float *werr, 
+   20463             :          float *work,
+   20464             :          int *iwork, 
+   20465             :          int *info)
+   20466             : {
+   20467             :     int i__1, i__2, i__3;
+   20468             :     float d__1, d__2;
+   20469             : 
+   20470             :     int i__, j, k, p;
+   20471             :     float s;
+   20472             :     int i1, i2, ii, kk;
+   20473             :     float fac, gap, mid;
+   20474             :     int cnt;
+   20475             :     float tmp, left;
+   20476             :     int nint, prev, next, nleft;
+   20477             :     float right, width, dplus;
+   20478             :     int nright, olnint;
+   20479             :     k = 0;
+   20480             :     right = 0.0;
+   20481             : 
+   20482           0 :     --iwork;
+   20483           0 :     --work;
+   20484           0 :     --werr;
+   20485           0 :     --wgap;
+   20486           0 :     --w;
+   20487           0 :     --lld;
+   20488             :     --ld;
+   20489             :     --l;
+   20490           0 :     --d__;
+   20491             : 
+   20492           0 :     *info = 0;
+   20493           0 :     i__1 = *n << 1;
+   20494           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20495           0 :         iwork[i__] = 0;
+   20496             :     }
+   20497           0 :     i1 = *ifirst;
+   20498             :     i2 = *ifirst;
+   20499             :     prev = 0;
+   20500           0 :     i__1 = *ilast;
+   20501           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20502           0 :         k = i__ << 1;
+   20503           0 :         iwork[k - 1] = 1;
+   20504             :         i2 = i__;
+   20505             :     }
+   20506             : 
+   20507             :     i__ = i1;
+   20508             :     nint = 0;
+   20509           0 : L30:
+   20510           0 :     if (i__ <= i2) {
+   20511           0 :         ii = i__ - *offset;
+   20512           0 :         if (iwork[(i__ << 1) - 1] == 1) {
+   20513             :             fac = 1.;
+   20514           0 :             left = w[ii] - werr[ii];
+   20515             : 
+   20516             : 
+   20517           0 : L40:
+   20518           0 :             if (i__ > i1 && left <= right) {
+   20519             :                 left = right;
+   20520           0 :                 cnt = i__ - 1;
+   20521             :             } else {
+   20522           0 :                 s = -left;
+   20523             :                 cnt = 0;
+   20524           0 :                 i__1 = *n - 1;
+   20525           0 :                 for (j = 1; j <= i__1; ++j) {
+   20526           0 :                     dplus = d__[j] + s;
+   20527           0 :                     s = s * lld[j] / dplus - left;
+   20528           0 :                     if (dplus < 0.) {
+   20529           0 :                         ++cnt;
+   20530             :                     }
+   20531             :                 }
+   20532           0 :                 dplus = d__[*n] + s;
+   20533           0 :                 if (dplus < 0.) {
+   20534           0 :                     ++cnt;
+   20535             :                 }
+   20536           0 :                 if (std::isnan(s)) {
+   20537             : 
+   20538             :                     cnt = 0;
+   20539             :                     s = -left;
+   20540             :                     i__1 = *n - 1;
+   20541           0 :                     for (j = 1; j <= i__1; ++j) {
+   20542           0 :                         dplus = d__[j] + s;
+   20543           0 :                         if (dplus < 0.) {
+   20544           0 :                             ++cnt;
+   20545             :                         }
+   20546           0 :                         tmp = lld[j] / dplus;
+   20547           0 :                         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20548           0 :                             s = lld[j] - left;
+   20549             :                         } else {
+   20550           0 :                             s = s * tmp - left;
+   20551             :                         }
+   20552             :                     }
+   20553           0 :                     dplus = d__[*n] + s;
+   20554           0 :                     if (dplus < 0.) {
+   20555           0 :                         ++cnt;
+   20556             :                     }
+   20557             :                 }
+   20558           0 :                 if (cnt > i__ - 1) {
+   20559           0 :                     left -= werr[ii] * fac;
+   20560           0 :                     fac *= 2.;
+   20561           0 :                     goto L40;
+   20562             :                 }
+   20563             :             }
+   20564           0 :             nleft = cnt + 1;
+   20565             :             i1 = (i1<nleft) ? i1 : nleft;
+   20566             :             fac = 1.;
+   20567           0 :             right = w[ii] + werr[ii];
+   20568           0 : L60:
+   20569           0 :             s = -right;
+   20570             :             cnt = 0;
+   20571           0 :             i__1 = *n - 1;
+   20572           0 :             for (j = 1; j <= i__1; ++j) {
+   20573           0 :                 dplus = d__[j] + s;
+   20574           0 :                 s = s * lld[j] / dplus - right;
+   20575           0 :                 if (dplus < 0.) {
+   20576           0 :                     ++cnt;
+   20577             :                 }
+   20578             :             }
+   20579           0 :             dplus = d__[*n] + s;
+   20580           0 :             if (dplus < 0.) {
+   20581           0 :                 ++cnt;
+   20582             :             }
+   20583           0 :             if (std::isnan(s)) {
+   20584             : 
+   20585             :                 cnt = 0;
+   20586             :                 s = -right;
+   20587             :                 i__1 = *n - 1;
+   20588           0 :                 for (j = 1; j <= i__1; ++j) {
+   20589           0 :                     dplus = d__[j] + s;
+   20590           0 :                     if (dplus < 0.) {
+   20591           0 :                         ++cnt;
+   20592             :                     }
+   20593           0 :                     tmp = lld[j] / dplus;
+   20594           0 :                     if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20595           0 :                         s = lld[j] - right;
+   20596             :                     } else {
+   20597           0 :                         s = s * tmp - right;
+   20598             :                     }
+   20599             :                 }
+   20600           0 :                 dplus = d__[*n] + s;
+   20601           0 :                 if (dplus < 0.) {
+   20602           0 :                     ++cnt;
+   20603             :                 }
+   20604             :             }
+   20605           0 :             if (cnt < i__) {
+   20606           0 :                 right += werr[ii] * fac;
+   20607           0 :                 fac *= 2.;
+   20608           0 :                 goto L60;
+   20609             :             }
+   20610             :             cnt = (cnt<i2) ? cnt : i2;
+   20611           0 :             ++nint;
+   20612           0 :             k = nleft << 1;
+   20613           0 :             work[k - 1] = left;
+   20614           0 :             work[k] = right;
+   20615           0 :             i__ = cnt + 1;
+   20616           0 :             iwork[k - 1] = i__;
+   20617           0 :             iwork[k] = cnt;
+   20618           0 :             if (prev != nleft - 1) {
+   20619           0 :                 work[k - 2] = left;
+   20620             :             }
+   20621             :             prev = nleft;
+   20622             :         } else {
+   20623           0 :             right = work[i__ * 2];
+   20624             : 
+   20625           0 :             ++iwork[k - 1];
+   20626             :             prev = i__;
+   20627           0 :             ++i__;
+   20628             :         }
+   20629           0 :         goto L30;
+   20630             :     }
+   20631           0 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+   20632           0 :         work[(i__ << 1) - 1] = work[prev * 2];
+   20633             :     }
+   20634             : 
+   20635           0 : L80:
+   20636           0 :     prev = i1 - 1;
+   20637             :     olnint = nint;
+   20638             :     i__ = i1;
+   20639             :     i__1 = olnint;
+   20640           0 :     for (p = 1; p <= i__1; ++p) {
+   20641           0 :         k = i__ << 1;
+   20642           0 :         left = work[k - 1];
+   20643           0 :         right = work[k];
+   20644           0 :         next = iwork[k - 1];
+   20645           0 :         nright = iwork[k];
+   20646           0 :         mid = (left + right) * .5;
+   20647           0 :         width = right - mid;
+   20648             :         d__1 = std::abs(left);
+   20649             :         d__2 = std::abs(right);
+   20650           0 :         tmp = (d__1>d__2) ? d__1 : d__2;
+   20651             : 
+   20652             :         gap = 0.;
+   20653           0 :         if (i__ == nright) {
+   20654           0 :             if (prev > 0 && next <= *n) {
+   20655           0 :                 d__1 = left - work[k - 2], d__2 = work[k + 1] - right;
+   20656           0 :                 gap = (d__1<d__2) ? d__1 : d__2;
+   20657           0 :             } else if (prev > 0) {
+   20658           0 :                 gap = left - work[k - 2];
+   20659           0 :             } else if (next <= *n) {
+   20660           0 :                 gap = work[k + 1] - right;
+   20661             :             }
+   20662             :         }
+   20663           0 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+   20664           0 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+   20665           0 :             --nint;
+   20666           0 :             iwork[k - 1] = 0;
+   20667             :             kk = k;
+   20668             :             i__2 = nright;
+   20669           0 :             for (j = i__ + 1; j <= i__2; ++j) {
+   20670           0 :                 kk += 2;
+   20671           0 :                 iwork[kk - 1] = 0;
+   20672           0 :                 work[kk - 1] = left;
+   20673           0 :                 work[kk] = right;
+   20674           0 :                 wgap[j - 1 - *offset] = 0.;
+   20675             :             }
+   20676           0 :             if (i1 == i__) {
+   20677             :                 i1 = next;
+   20678             :             } else {
+   20679           0 :                 iwork[(prev << 1) - 1] = next;
+   20680             :             }
+   20681             :             i__ = next;
+   20682           0 :             continue;
+   20683             :         }
+   20684             :         prev = i__;
+   20685             : 
+   20686           0 :         s = -mid;
+   20687             :         cnt = 0;
+   20688           0 :         i__2 = *n - 1;
+   20689           0 :         for (j = 1; j <= i__2; ++j) {
+   20690           0 :             dplus = d__[j] + s;
+   20691           0 :             s = s * lld[j] / dplus - mid;
+   20692           0 :             if (dplus < 0.) {
+   20693           0 :                 ++cnt;
+   20694             :             }
+   20695             :         }
+   20696           0 :         dplus = d__[*n] + s;
+   20697           0 :         if (dplus < 0.) {
+   20698           0 :             ++cnt;
+   20699             :         }
+   20700           0 :         if (std::isnan(s)) {
+   20701             :             cnt = 0;
+   20702             :             s = -mid;
+   20703             :             i__2 = *n - 1;
+   20704           0 :             for (j = 1; j <= i__2; ++j) {
+   20705           0 :                 dplus = d__[j] + s;
+   20706           0 :                 if (dplus < 0.) {
+   20707           0 :                     ++cnt;
+   20708             :                 }
+   20709           0 :                 tmp = lld[j] / dplus;
+   20710           0 :                 if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20711           0 :                     s = lld[j] - mid;
+   20712             :                 } else {
+   20713           0 :                     s = s * tmp - mid;
+   20714             :                 }
+   20715             :             }
+   20716           0 :             dplus = d__[*n] + s;
+   20717           0 :             if (dplus < 0.) {
+   20718           0 :                 ++cnt;
+   20719             :             }
+   20720             :         }
+   20721           0 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+   20722             :         cnt = (i__2>i__3) ? i__2 : i__3;
+   20723           0 :         if (cnt == i__ - 1) {
+   20724           0 :             work[k - 1] = mid;
+   20725           0 :         } else if (cnt == nright) {
+   20726           0 :             work[k] = mid;
+   20727             :         } else {
+   20728           0 :             iwork[k] = cnt;
+   20729           0 :             ++cnt;
+   20730           0 :             iwork[k - 1] = cnt;
+   20731           0 :             kk = cnt << 1;
+   20732           0 :             iwork[kk - 1] = next;
+   20733           0 :             iwork[kk] = nright;
+   20734           0 :             work[k] = mid;
+   20735           0 :             work[kk - 1] = mid;
+   20736           0 :             work[kk] = right;
+   20737             :             prev = cnt;
+   20738           0 :             if (cnt - 1 > i__) {
+   20739           0 :                 work[kk - 2] = mid;
+   20740             :             }
+   20741           0 :             if (cnt > *ifirst && cnt <= *ilast) {
+   20742           0 :                 ++nint;
+   20743           0 :             } else if (cnt <= *ifirst) {
+   20744             :                 i1 = cnt;
+   20745             :             }
+   20746             :         }
+   20747             :         i__ = next;
+   20748             :     }
+   20749           0 :     if (nint > 0) {
+   20750           0 :         goto L80;
+   20751             :     }
+   20752           0 :     i__1 = *ilast;
+   20753           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20754           0 :         k = i__ << 1;
+   20755           0 :         ii = i__ - *offset;
+   20756           0 :         if (iwork[k - 1] != -1) {
+   20757           0 :             w[ii] = (work[k - 1] + work[k]) * .5;
+   20758           0 :             werr[ii] = work[k] - w[ii];
+   20759           0 :             if (i__ != *ilast) {
+   20760           0 :                 wgap[ii] = work[k + 1] - work[k];
+   20761             :             }
+   20762             :         }
+   20763             :     }
+   20764             : 
+   20765           0 :     return;
+   20766             : 
+   20767             : } 
+   20768             : }
+   20769             : }
+   20770             : #include <cctype>
+   20771             : #include <cmath>
+   20772             : 
+   20773             : #include "real.h"
+   20774             : 
+   20775             : #include "blas/blas.h"
+   20776             : #include "lapack.h"
+   20777             : #include "lapack_limits.h"
+   20778             : 
+   20779             : 
+   20780             : 
+   20781             : #include "blas/blas.h"
+   20782             : namespace PLMD{
+   20783             : namespace lapack{
+   20784             : using namespace blas;
+   20785             : void
+   20786           0 : PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(const char *range,
+   20787             :          int *n, 
+   20788             :          float *vl, 
+   20789             :          float *vu, 
+   20790             :          int *il, 
+   20791             :          int *iu, 
+   20792             :          float *d__, 
+   20793             :          float *e, 
+   20794             :          float *tol, 
+   20795             :          int *nsplit, 
+   20796             :          int *isplit, 
+   20797             :          int *m, 
+   20798             :          float *w, 
+   20799             :          int *iblock, 
+   20800             :          int *indexw, 
+   20801             :          float *gersch, 
+   20802             :          float *work,
+   20803             :          int *iwork, 
+   20804             :          int *info)
+   20805             : {
+   20806             :     int i__1, i__2, i__3;
+   20807             :     float d__1, d__2;
+   20808           0 :     int c__1 = 1;
+   20809           0 :     int c__0 = 0;
+   20810             : 
+   20811             :     int i__, j, k;
+   20812             :     float s, gl;
+   20813             :     int in;
+   20814             :     float gu;
+   20815             :     int cnt;
+   20816             :     float eps, tau, nrm, tmp, vvl, vvu, offd;
+   20817             :     int iend, jblk, till, itmp;
+   20818             :     float rtol, delta, sigma;
+   20819             :     int iinfo;
+   20820             :     float width;
+   20821             :     int ibegin;
+   20822             :     int irange;
+   20823             :     float sgndef;
+   20824             :     int maxcnt;
+   20825           0 :     --iwork;
+   20826           0 :     --work;
+   20827           0 :     --gersch;
+   20828           0 :     --indexw;
+   20829           0 :     --iblock;
+   20830           0 :     --w;
+   20831           0 :     --isplit;
+   20832           0 :     --e;
+   20833           0 :     --d__;
+   20834             : 
+   20835             :     sigma = 0;
+   20836             :     irange = 0;
+   20837             :     sgndef = 0;
+   20838             :     maxcnt = 0;
+   20839             : 
+   20840           0 :     *info = 0;
+   20841             : 
+   20842           0 :     if (*range=='A' || *range=='a')
+   20843             :         irange = 1;
+   20844           0 :     else if (*range=='V' || *range=='v')
+   20845             :         irange = 2;
+   20846           0 :     else if (*range=='I' || *range=='i')
+   20847             :         irange = 3;
+   20848             :     
+   20849             : 
+   20850           0 :     *m = 0;
+   20851             :     eps = PLUMED_GMX_FLOAT_EPS;
+   20852             : 
+   20853           0 :     *nsplit = 1;
+   20854           0 :     i__1 = *n - 1;
+   20855           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20856           0 :         if (std::abs(e[i__]) <= *tol) {
+   20857           0 :             isplit[*nsplit] = i__;
+   20858           0 :             ++(*nsplit);
+   20859             :         }
+   20860             :     }
+   20861           0 :     isplit[*nsplit] = *n;
+   20862             : 
+   20863             :     ibegin = 1;
+   20864           0 :     i__1 = *nsplit;
+   20865           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   20866           0 :         iend = isplit[jblk];
+   20867           0 :         if (ibegin == iend) {
+   20868           0 :             ++(*m);
+   20869           0 :             w[*m] = d__[ibegin];
+   20870           0 :             iblock[*m] = jblk;
+   20871           0 :             indexw[*m] = 1;
+   20872           0 :             e[iend] = 0.;
+   20873           0 :             ibegin = iend + 1;
+   20874           0 :             goto L170;
+   20875             :         }
+   20876           0 :         in = iend - ibegin + 1;
+   20877             : 
+   20878           0 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+   20879           0 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+   20880           0 :         gersch[(ibegin << 1) - 1] = gl;
+   20881           0 :         gersch[ibegin * 2] = gu;
+   20882           0 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+   20883           0 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+   20884           0 :         d__1 = gersch[(iend << 1) - 1];
+   20885           0 :         gl = (d__1<gl) ? d__1 : gl;
+   20886             :         d__1 = gersch[iend * 2];
+   20887           0 :         gu = (d__1>gu) ? d__1 : gu;
+   20888           0 :         i__2 = iend - 1;
+   20889           0 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20890           0 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   20891           0 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+   20892             :             d__1 = gersch[(i__ << 1) - 1];
+   20893           0 :             gl = (d__1<gl) ? d__1 : gl;
+   20894           0 :             gersch[i__ * 2] = d__[i__] + offd;
+   20895             :             d__1 = gersch[i__ * 2];
+   20896           0 :             gu = (d__1>gu) ? d__1 : gu;
+   20897             :         }
+   20898             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+   20899           0 :         nrm = (d__1>d__2) ? d__1 : d__2;
+   20900             : 
+   20901           0 :         width = gu - gl;
+   20902             :         i__2 = iend - 1;
+   20903           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   20904           0 :             work[i__] = e[i__] * e[i__];
+   20905             :         }
+   20906           0 :         for (j = 1; j <= 2; ++j) {
+   20907           0 :             if (j == 1) {
+   20908           0 :                 tau = gl + width * .25;
+   20909             :             } else {
+   20910           0 :                 tau = gu - width * .25;
+   20911             :             }
+   20912           0 :             tmp = d__[ibegin] - tau;
+   20913           0 :             if (tmp < 0.) {
+   20914           0 :                 cnt = 1;
+   20915             :             } else {
+   20916           0 :                 cnt = 0;
+   20917             :             }
+   20918           0 :             i__2 = iend;
+   20919           0 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20920           0 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+   20921           0 :                 if (tmp < 0.) {
+   20922           0 :                     ++cnt;
+   20923             :                 }
+   20924             :             }
+   20925           0 :             if (cnt == 0) {
+   20926             :                 gl = tau;
+   20927           0 :             } else if (cnt == in) {
+   20928             :                 gu = tau;
+   20929             :             }
+   20930           0 :             if (j == 1) {
+   20931             :                 maxcnt = cnt;
+   20932             :                 sigma = gl;
+   20933             :                 sgndef = 1.;
+   20934             :             } else {
+   20935           0 :                 if (in - cnt > maxcnt) {
+   20936             :                     sigma = gu;
+   20937             :                     sgndef = -1.;
+   20938             :                 }
+   20939             :             }
+   20940             :         }
+   20941             : 
+   20942           0 :         work[in * 3] = 1.;
+   20943             :         delta = eps;
+   20944           0 :         tau = sgndef * nrm;
+   20945           0 : L60:
+   20946           0 :         sigma -= delta * tau;
+   20947           0 :         work[1] = d__[ibegin] - sigma;
+   20948             :         j = ibegin;
+   20949           0 :         i__2 = in - 1;
+   20950           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20951           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   20952           0 :             tmp = e[j] * work[(in << 1) + i__];
+   20953           0 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+   20954           0 :             work[in + i__] = tmp;
+   20955           0 :             ++j;
+   20956             :         }
+   20957           0 :         for (i__ = in; i__ >= 1; --i__) {
+   20958           0 :             tmp = sgndef * work[i__];
+   20959           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   20960           0 :                 delta *= 2.;
+   20961           0 :                 goto L60;
+   20962             :             }
+   20963             :         }
+   20964             : 
+   20965           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   20966           0 :         i__2 = in - 1;
+   20967           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   20968           0 :         i__2 = in - 1;
+   20969           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20970           0 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+   20971           0 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+   20972             :         }
+   20973           0 :         if (sgndef > 0.) {
+   20974           0 :             cnt = 1;
+   20975           0 :             work[1] = (gl + gu) / 2. - sigma;
+   20976           0 :             work[in + 1] = 0.;
+   20977           0 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+   20978             :         } else {
+   20979           0 :             cnt = in;
+   20980           0 :             work[in] = (gl + gu) / 2. - sigma;
+   20981           0 :             work[in * 2] = 0.;
+   20982           0 :             work[in * 3] = (gu - gl) / 2.;
+   20983             :         }
+   20984           0 :         rtol = eps * 4.;
+   20985           0 :         PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+   20986           0 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+   20987           0 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+   20988             :                 iinfo);
+   20989           0 :         if (sgndef > 0.) {
+   20990           0 :             tau = work[1] - work[(in << 1) + 1];
+   20991             :         } else {
+   20992           0 :             tau = work[in] + work[in * 3];
+   20993             :         }
+   20994             : 
+   20995           0 :         work[in * 3] = 1.;
+   20996             :         delta = eps * 2.;
+   20997           0 : L100:
+   20998           0 :         tau *= 1. - delta;
+   20999             : 
+   21000           0 :         s = -tau;
+   21001             :         j = ibegin;
+   21002           0 :         i__2 = in - 1;
+   21003           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21004           0 :             work[i__] = d__[j] + s;
+   21005           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   21006           0 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+   21007           0 :             s = s * work[in + i__] * e[j] - tau;
+   21008           0 :             ++j;
+   21009             :         }
+   21010           0 :         work[in] = d__[iend] + s;
+   21011             : 
+   21012           0 :         for (i__ = in; i__ >= 1; --i__) {
+   21013           0 :             tmp = sgndef * work[i__];
+   21014           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   21015           0 :                 delta *= 2.;
+   21016           0 :                 goto L100;
+   21017             :             }
+   21018             :         }
+   21019             : 
+   21020           0 :         sigma += tau;
+   21021           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   21022           0 :         i__2 = in - 1;
+   21023           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   21024           0 :         e[iend] = sigma;
+   21025           0 :         tmp = (float) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+   21026             :         i__2 = iend;
+   21027           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   21028           0 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+   21029           0 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+   21030             :         }
+   21031             : 
+   21032             :         j = ibegin;
+   21033           0 :         i__2 = in - 1;
+   21034           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21035           0 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+   21036           0 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+   21037           0 :             ++j;
+   21038             :         }
+   21039           0 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+   21040             : 
+   21041           0 :         PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(&in, &work[1], info);
+   21042           0 :         if (*info != 0) {
+   21043             :             return;
+   21044             :         }
+   21045             : 
+   21046           0 :         if (sgndef > 0.) {
+   21047           0 :             i__2 = in;
+   21048           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21049           0 :                 ++(*m);
+   21050           0 :                 w[*m] = work[in - i__ + 1];
+   21051           0 :                 iblock[*m] = jblk;
+   21052           0 :                 indexw[*m] = i__;
+   21053             :             }
+   21054             :         } else {
+   21055           0 :             i__2 = in;
+   21056           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21057           0 :                 ++(*m);
+   21058           0 :                 w[*m] = -work[i__];
+   21059           0 :                 iblock[*m] = jblk;
+   21060           0 :                 indexw[*m] = i__;
+   21061             :             }
+   21062             :         }
+   21063           0 :         ibegin = iend + 1;
+   21064           0 : L170:
+   21065             :         ;
+   21066             :     }
+   21067           0 :     if (irange == 2) {
+   21068           0 :         *m = 0;
+   21069             :         ibegin = 1;
+   21070           0 :         i__1 = *nsplit;
+   21071           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   21072           0 :             iend = isplit[i__];
+   21073           0 :             vvl = *vl - e[iend];
+   21074           0 :             vvu = *vu - e[iend];
+   21075           0 :             i__2 = iend;
+   21076           0 :             for (j = ibegin; j <= i__2; ++j) {
+   21077           0 :                 if (vvl <= w[j] && w[j] <= vvu) {
+   21078           0 :                     ++(*m);
+   21079           0 :                     w[*m] = w[j];
+   21080           0 :                     iblock[*m] = i__;
+   21081           0 :                     indexw[*m] = j - ibegin + 1;
+   21082             :                 }
+   21083             :             }
+   21084           0 :             ibegin = iend + 1;
+   21085             :         }
+   21086           0 :     } else if (irange == 3) {
+   21087           0 :         *m = *iu - *il + 1;
+   21088           0 :         if (*nsplit == 1) {
+   21089             :             i__1 = *m;
+   21090           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21091           0 :                 w[i__] = w[*il + i__ - 1];
+   21092           0 :                 indexw[i__] = *il + i__ - 1;
+   21093             :             }
+   21094             :         } else {
+   21095             :             ibegin = 1;
+   21096             :             i__1 = *nsplit;
+   21097           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21098           0 :                 iend = isplit[i__];
+   21099           0 :                 i__2 = iend;
+   21100           0 :                 for (j = ibegin; j <= i__2; ++j) {
+   21101           0 :                     work[j] = w[j] + e[iend];
+   21102             :                 }
+   21103           0 :                 ibegin = iend + 1;
+   21104             :             }
+   21105           0 :             i__1 = *n;
+   21106           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21107           0 :                 iwork[i__] = i__;
+   21108           0 :                 iwork[*n + i__] = iblock[i__];
+   21109             :             }
+   21110           0 :             PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+   21111           0 :             i__1 = *m;
+   21112           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21113           0 :                 itmp = iwork[*il + i__ - 1];
+   21114           0 :                 work[i__] = w[itmp];
+   21115           0 :                 iblock[i__] = iwork[*n + itmp];
+   21116             :             }
+   21117           0 :             i__1 = *m;
+   21118           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21119           0 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+   21120           0 :                 iwork[i__] = i__;
+   21121             :             }
+   21122           0 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+   21123             :             j = 1;
+   21124           0 :             itmp = iblock[j];
+   21125           0 :             cnt = iwork[*n + iwork[j]];
+   21126           0 :             if (itmp == 1) {
+   21127             :                 ibegin = 1;
+   21128             :             } else {
+   21129           0 :                 ibegin = isplit[itmp - 1] + 1;
+   21130             :             }
+   21131           0 :             i__1 = *m;
+   21132           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21133           0 :                 w[i__] = work[iwork[i__]];
+   21134           0 :                 if (iblock[i__] != itmp || i__ == *m) {
+   21135           0 :                     if (iblock[i__] == itmp) {
+   21136           0 :                         till = *m;
+   21137             :                     } else {
+   21138           0 :                         till = i__ - 1;
+   21139             :                     }
+   21140           0 :                     i__2 = till - j + 1;
+   21141           0 :                     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", &i__2, &w[j], &iinfo);
+   21142           0 :                     cnt = cnt - ibegin + 1;
+   21143           0 :                     i__2 = till;
+   21144           0 :                     for (k = j; k <= i__2; ++k) {
+   21145           0 :                         indexw[k] = cnt + k - j;
+   21146             :                     }
+   21147             :                     j = i__;
+   21148           0 :                     itmp = iblock[j];
+   21149           0 :                     cnt = iwork[*n + iwork[j]];
+   21150           0 :                     ibegin = isplit[itmp - 1] + 1;
+   21151           0 :                     if (i__ == *m && till < *m) {
+   21152           0 :                         indexw[*m] = cnt - ibegin + 1;
+   21153             :                     }
+   21154             :                 } else {
+   21155           0 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+   21156           0 :                     cnt = (i__2<i__3) ? i__2 : i__3;
+   21157             :                 }
+   21158             :             }
+   21159             :         }
+   21160             :     }
+   21161             : 
+   21162             :     return;
+   21163             : 
+   21164             : }
+   21165             : 
+   21166             : 
+   21167             : }
+   21168             : }
+   21169             : #include <cmath>
+   21170             : 
+   21171             : #include "real.h"
+   21172             : 
+   21173             : #include "blas/blas.h"
+   21174             : #include "lapack.h"
+   21175             : #include "lapack_limits.h"
+   21176             : 
+   21177             : 
+   21178             : #include "blas/blas.h"
+   21179             : namespace PLMD{
+   21180             : namespace lapack{
+   21181             : using namespace blas;
+   21182             : void
+   21183           0 : PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(int *n, 
+   21184             :         float *d__, 
+   21185             :         float *l, 
+   21186             :         float *ld, 
+   21187             :         float *lld, 
+   21188             :         int *ifirst, 
+   21189             :         int *ilast, 
+   21190             :         float *w, 
+   21191             :         float *sigma, 
+   21192             :         float *dplus, 
+   21193             :         float *lplus, 
+   21194             :         float *work,
+   21195             :         int *info)
+   21196             : {
+   21197           0 :     int i1 = 1;
+   21198             :     int i__1;
+   21199             :     float d__2, d__3;
+   21200             : 
+   21201             :     int i__;
+   21202             :     float s, eps, tmp, dmax1, dmax2, delta;
+   21203           0 :     --work;
+   21204           0 :     --lplus;
+   21205           0 :     --dplus;
+   21206           0 :     --w;
+   21207             :     --lld;
+   21208           0 :     --ld;
+   21209           0 :     --l;
+   21210           0 :     --d__;
+   21211           0 :     *info = 0;
+   21212             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21213           0 :     *sigma = w[*ifirst];
+   21214             :     delta = eps * 2.;
+   21215             : 
+   21216           0 : L10:
+   21217           0 :     s = -(*sigma);
+   21218           0 :     dplus[1] = d__[1] + s;
+   21219             :     dmax1 = std::abs(dplus[1]);
+   21220           0 :     i__1 = *n - 1;
+   21221           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21222           0 :         lplus[i__] = ld[i__] / dplus[i__];
+   21223           0 :         s = s * lplus[i__] * l[i__] - *sigma;
+   21224           0 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+   21225             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+   21226           0 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+   21227             :     }
+   21228           0 :     if (std::isnan(dmax1)) {
+   21229           0 :         *sigma -= std::abs(*sigma) * delta;
+   21230           0 :         delta *= 2.;
+   21231           0 :         goto L10;
+   21232             :     }
+   21233             : 
+   21234           0 :     tmp = w[*ilast];
+   21235             :     delta = eps * 2.;
+   21236           0 : L30:
+   21237           0 :     s = -tmp;
+   21238           0 :     work[1] = d__[1] + s;
+   21239             :     dmax2 = std::abs(work[1]);
+   21240           0 :     i__1 = *n - 1;
+   21241           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21242           0 :         work[*n + i__] = ld[i__] / work[i__];
+   21243           0 :         s = s * work[*n + i__] * l[i__] - tmp;
+   21244           0 :         work[i__ + 1] = d__[i__ + 1] + s;
+   21245             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+   21246           0 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+   21247             :     }
+   21248           0 :     if (std::isnan(dmax2)) {
+   21249           0 :         tmp += std::abs(tmp) * delta;
+   21250           0 :         delta *= 2.;
+   21251           0 :         goto L30;
+   21252             :     }
+   21253           0 :     if (dmax2 < dmax1) {
+   21254           0 :         *sigma = tmp;
+   21255           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+   21256           0 :         i__1 = *n - 1;
+   21257           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+   21258             :     }
+   21259             : 
+   21260           0 :     return;
+   21261             : }
+   21262             : }
+   21263             : }
+   21264             : #include <cmath>
+   21265             : 
+   21266             : #include "real.h"
+   21267             : 
+   21268             : #include "blas/blas.h"
+   21269             : #include "lapack.h"
+   21270             : #include "lapack_limits.h"
+   21271             : 
+   21272             : 
+   21273             : #include "blas/blas.h"
+   21274             : namespace PLMD{
+   21275             : namespace lapack{
+   21276             : using namespace blas;
+   21277             : void
+   21278           0 : PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(int *n, 
+   21279             :         float *d__, 
+   21280             :         float *l, 
+   21281             :         int *isplit,
+   21282             :         int *m, 
+   21283             :         float *w,
+   21284             :         int *iblock, 
+   21285             :         int *indexw, 
+   21286             :         float *gersch, 
+   21287             :         float *tol, 
+   21288             :         float *z__, 
+   21289             :         int *ldz, 
+   21290             :         int *isuppz, 
+   21291             :         float *work, 
+   21292             :         int *iwork, 
+   21293             :         int *info)
+   21294             : {
+   21295             :     int z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6;
+   21296             :     float d__1, d__2;
+   21297           0 :     float c_b5 = 0.;
+   21298           0 :     int c__1 = 1;
+   21299           0 :     int c__2 = 2;
+   21300             : 
+   21301             :     int i__, j, k, p, q;
+   21302             :     int im, in;
+   21303             :     float gap, eps, tmp;
+   21304             :     int zto;
+   21305             :     float ztz;
+   21306             :     int iend, jblk;
+   21307             :     int wend, iter, temp[1], ktot;
+   21308             :     int itmp1, itmp2;
+   21309             :     int indld;
+   21310             :     float sigma;
+   21311             :     int ndone, iinfo, iindr;
+   21312             :     float resid;
+   21313             :     int nomgs;
+   21314             :     int nclus;
+   21315             :     int zfrom, iindc1, iindc2;
+   21316             :     float lambda;
+   21317             :     int ibegin;
+   21318             :     int indgap, indlld;
+   21319             :     float mingma;
+   21320             :     int oldien, oldncl, wbegin;
+   21321             :     float relgap;
+   21322             :     int oldcls;
+   21323             :     int ndepth, inderr, iindwk;
+   21324             :     int newcls, oldfst;
+   21325             :     float minrgp=0.0;
+   21326             :     int indwrk, oldlst;
+   21327             :     float reltol;
+   21328             :     int newfrs, newftt, parity;
+   21329             :     float mgstol, nrminv, rqcorr;
+   21330             :     int newlst, newsiz;
+   21331             : 
+   21332             : 
+   21333           0 :     --d__;
+   21334           0 :     --l;
+   21335             :     --isplit;
+   21336           0 :     --w;
+   21337           0 :     --iblock;
+   21338           0 :     --indexw;
+   21339             :     --gersch;
+   21340           0 :     z_dim1 = *ldz;
+   21341           0 :     z_offset = 1 + z_dim1;
+   21342           0 :     z__ -= z_offset;
+   21343           0 :     --isuppz;
+   21344           0 :     --work;
+   21345           0 :     --iwork;
+   21346             : 
+   21347           0 :     inderr = *n;
+   21348           0 :     indld = *n << 1;
+   21349           0 :     indlld = *n * 3;
+   21350           0 :     indgap = *n << 2;
+   21351           0 :     indwrk = *n * 5 + 1;
+   21352             : 
+   21353             :     iindr = *n;
+   21354             :     iindc1 = *n << 1;
+   21355             :     iindc2 = *n * 3;
+   21356           0 :     iindwk = (*n << 2) + 1;
+   21357             : 
+   21358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21359             : 
+   21360             :     i__1 = *n << 1;
+   21361           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21362           0 :         iwork[i__] = 0;
+   21363             :     }
+   21364           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, m, &c_b5, &c_b5, &z__[z_offset], ldz);
+   21365             :     mgstol = eps * 100.;
+   21366             : 
+   21367             :     ibegin = 1;
+   21368             :     wbegin = 1;
+   21369           0 :     i__1 = iblock[*m];
+   21370           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   21371           0 :         iend = isplit[jblk];
+   21372             : 
+   21373           0 :         wend = wbegin - 1;
+   21374           0 : L171:
+   21375           0 :         if (wend < *m) {
+   21376           0 :             if (iblock[wend + 1] == jblk) {
+   21377           0 :                 ++wend;
+   21378           0 :                 goto L171;
+   21379             :             }
+   21380             :         }
+   21381           0 :         if (wend < wbegin) {
+   21382           0 :             ibegin = iend + 1;
+   21383           0 :             continue;
+   21384             :         }
+   21385             : 
+   21386           0 :         if (ibegin == iend) {
+   21387           0 :             z__[ibegin + wbegin * z_dim1] = 1.;
+   21388           0 :             isuppz[(wbegin << 1) - 1] = ibegin;
+   21389           0 :             isuppz[wbegin * 2] = ibegin;
+   21390           0 :             ibegin = iend + 1;
+   21391           0 :             wbegin = wend + 1;
+   21392           0 :             continue;
+   21393             :         }
+   21394           0 :         oldien = ibegin - 1;
+   21395           0 :         in = iend - oldien;
+   21396           0 :         d__1 = .001, d__2 = 1. / (float) in;
+   21397           0 :         reltol = (d__1<d__2) ? d__1 : d__2;
+   21398           0 :         im = wend - wbegin + 1;
+   21399           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+   21400           0 :         i__2 = im - 1;
+   21401           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21402           0 :             work[inderr + i__] = eps * std::abs(work[i__]);
+   21403           0 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+   21404             :         }
+   21405           0 :         work[inderr + im] = eps * std::abs(work[im]);
+   21406           0 :         d__2 = std::abs(work[im]);
+   21407           0 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+   21408             :         ndone = 0;
+   21409             : 
+   21410             :         ndepth = 0;
+   21411             :         parity = 1;
+   21412             :         nclus = 1;
+   21413           0 :         iwork[iindc1 + 1] = 1;
+   21414           0 :         iwork[iindc1 + 2] = im;
+   21415             : 
+   21416           0 : L40:
+   21417           0 :         if (ndone < im) {
+   21418             :             oldncl = nclus;
+   21419             :             nclus = 0;
+   21420           0 :             parity = 1 - parity;
+   21421           0 :             if (parity == 0) {
+   21422             :                 oldcls = iindc1;
+   21423             :                 newcls = iindc2;
+   21424             :             } else {
+   21425             :                 oldcls = iindc2;
+   21426             :                 newcls = iindc1;
+   21427             :             }
+   21428             :             i__2 = oldncl;
+   21429           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21430             : 
+   21431           0 :                 j = oldcls + (i__ << 1);
+   21432           0 :                 oldfst = iwork[j - 1];
+   21433           0 :                 oldlst = iwork[j];
+   21434           0 :                 if (ndepth > 0) {
+   21435           0 :                     j = wbegin + oldfst - 1;
+   21436           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
+   21437             :                             , &c__1);
+   21438           0 :                     i__3 = in - 1;
+   21439           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
+   21440             :                             ibegin], &c__1);
+   21441           0 :                     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j 
+   21442             :                             * z_dim1], ldz);
+   21443             :                 }
+   21444             :                 k = ibegin;
+   21445           0 :                 i__3 = in - 1;
+   21446           0 :                 for (j = 1; j <= i__3; ++j) {
+   21447           0 :                     tmp = d__[k] * l[k];
+   21448           0 :                     work[indld + j] = tmp;
+   21449           0 :                     work[indlld + j] = tmp * l[k];
+   21450           0 :                     ++k;
+   21451             :                 }
+   21452           0 :                 if (ndepth > 0) {
+   21453             : 
+   21454           0 :                     p = indexw[wbegin - 1 + oldfst];
+   21455           0 :                     q = indexw[wbegin - 1 + oldlst];
+   21456           0 :                     d__1 = eps * 4.;
+   21457           0 :                     i__3 = p - oldfst;
+   21458           0 :                     PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
+   21459           0 :                             work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
+   21460           0 :                             work[1], &work[indgap + 1], &work[inderr + 1], &
+   21461           0 :                             work[indwrk + in], &iwork[iindwk], &iinfo);
+   21462             :                 }
+   21463           0 :                 newfrs = oldfst;
+   21464           0 :                 i__3 = oldlst;
+   21465           0 :                 for (j = oldfst; j <= i__3; ++j) {
+   21466           0 :                     if (j == oldlst || work[indgap + j] >= 
+   21467           0 :                         reltol * std::abs(work[j])) {
+   21468           0 :                         newlst = j;
+   21469             :                     } else {
+   21470             : 
+   21471           0 :                         relgap = work[indgap + j] / std::abs(work[j]);
+   21472           0 :                         if (j == newfrs) {
+   21473             :                             minrgp = relgap;
+   21474             :                         } else {
+   21475           0 :                             minrgp = (minrgp<relgap) ? minrgp : relgap;
+   21476             :                         }
+   21477           0 :                         continue;
+   21478             :                     }
+   21479           0 :                     newsiz = newlst - newfrs + 1;
+   21480           0 :                     newftt = wbegin + newfrs - 1;
+   21481           0 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+   21482           0 :                     if (newsiz > 1 && nomgs) {
+   21483             : 
+   21484           0 :                         PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 
+   21485           0 :                                 1], &work[indlld + 1], &newfrs, &newlst, &
+   21486           0 :                                 work[1], &sigma, &z__[ibegin + newftt * 
+   21487           0 :                                 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
+   21488           0 :                                  &work[indwrk], info);
+   21489           0 :                         if (*info == 0) {
+   21490           0 :                             tmp = eps * std::abs(sigma);
+   21491           0 :                             i__4 = newlst;
+   21492           0 :                             for (k = newfrs; k <= i__4; ++k) {
+   21493           0 :                                 work[k] -= sigma;
+   21494           0 :                                 d__1 = work[indgap + k];
+   21495           0 :                                 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
+   21496           0 :                                 work[inderr + k] += tmp;
+   21497             :                             }
+   21498           0 :                             ++nclus;
+   21499           0 :                             k = newcls + (nclus << 1);
+   21500           0 :                             iwork[k - 1] = newfrs;
+   21501           0 :                             iwork[k] = newlst;
+   21502             :                         } else {
+   21503           0 :                             *info = 0;
+   21504           0 :                             if (minrgp < mgstol) {
+   21505             : 
+   21506           0 :                                 work[indwrk] = d__[ibegin];
+   21507           0 :                                 i__4 = in - 1;
+   21508           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21509           0 :                                     work[indwrk + k] = d__[ibegin + k] + work[
+   21510           0 :                                             indlld + k];
+   21511             :                                 }
+   21512           0 :                                 i__4 = newsiz;
+   21513           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21514           0 :                                     iwork[iindwk + k - 1] = 1;
+   21515             :                                 }
+   21516           0 :                                 i__4 = newlst;
+   21517           0 :                                 for (k = newfrs; k <= i__4; ++k) {
+   21518           0 :                                     isuppz[2*(oldien + k) - 1] = 1;
+   21519           0 :                                     isuppz[(oldien + k) * 2] = in;
+   21520             :                                 }
+   21521           0 :                                 temp[0] = in;
+   21522           0 :                                 PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(&in, &work[indwrk], &work[indld + 1], 
+   21523           0 :                                         &newsiz, &work[newfrs], &iwork[iindwk]
+   21524             :                                         , temp, &z__[ibegin + newftt * z_dim1]
+   21525           0 :                                         , ldz, &work[indwrk + in], &iwork[
+   21526           0 :                                         iindwk + in], &iwork[iindwk + (in*2)], &iinfo);
+   21527           0 :                                 if (iinfo != 0) {
+   21528           0 :                                     *info = 2;
+   21529           0 :                                     return;
+   21530             :                                 }
+   21531           0 :                                 ndone += newsiz;
+   21532             :                             }
+   21533             :                         }
+   21534             :                     } else {
+   21535             :                         ktot = newftt;
+   21536             :                         i__4 = newlst;
+   21537           0 :                         for (k = newfrs; k <= i__4; ++k) {
+   21538             :                             iter = 0;
+   21539           0 : L90:
+   21540           0 :                             lambda = work[k];
+   21541             : 
+   21542           0 :                             PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+   21543           0 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+   21544           0 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+   21545           0 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+   21546           0 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+   21547           0 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+   21548           0 :                             tmp = 1. / ztz;
+   21549           0 :                             nrminv =  std::sqrt(tmp);
+   21550           0 :                             resid = std::abs(mingma) * nrminv;
+   21551           0 :                             rqcorr = mingma * tmp;
+   21552           0 :                             if (k == in) {
+   21553           0 :                                 gap = work[indgap + k - 1];
+   21554           0 :                             } else if (k == 1) {
+   21555           0 :                                 gap = work[indgap + k];
+   21556             :                             } else {
+   21557           0 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+   21558           0 :                                         indgap + k];
+   21559           0 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+   21560             :                             }
+   21561           0 :                             ++iter;
+   21562           0 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+   21563           0 :                                      std::abs(lambda)) {
+   21564           0 :                                 work[k] = lambda + rqcorr;
+   21565           0 :                                 if (iter < 8) {
+   21566           0 :                                     goto L90;
+   21567             :                                 }
+   21568             :                             }
+   21569           0 :                             iwork[ktot] = 1;
+   21570           0 :                             if (newsiz == 1) {
+   21571           0 :                                 ++ndone;
+   21572             :                             }
+   21573           0 :                             zfrom = isuppz[(ktot << 1) - 1];
+   21574           0 :                             zto = isuppz[ktot * 2];
+   21575           0 :                             i__5 = zto - zfrom + 1;
+   21576           0 :                             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+   21577           0 :                                     ktot * z_dim1], &c__1);
+   21578           0 :                             ++ktot;
+   21579             :                         }
+   21580           0 :                         if (newsiz > 1) {
+   21581           0 :                             itmp1 = isuppz[(newftt << 1) - 1];
+   21582           0 :                             itmp2 = isuppz[newftt * 2];
+   21583           0 :                             ktot = oldien + newlst;
+   21584             :                             i__4 = ktot;
+   21585           0 :                             for (p = newftt + 1; p <= i__4; ++p) {
+   21586           0 :                                 i__5 = p - 1;
+   21587           0 :                                 for (q = newftt; q <= i__5; ++q) {
+   21588           0 :                                     tmp = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&in, &z__[ibegin + p * 
+   21589           0 :                                             z_dim1], &c__1, &z__[ibegin + q * 
+   21590           0 :                                             z_dim1], &c__1);
+   21591           0 :                                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&in, &tmp, &z__[ibegin + q * 
+   21592           0 :                                             z_dim1], &c__1, &z__[ibegin + p * 
+   21593           0 :                                             z_dim1], &c__1);
+   21594             :                                 }
+   21595           0 :                                 tmp = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&in, &z__[ibegin + p * 
+   21596           0 :                                         z_dim1], &c__1);
+   21597           0 :                                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&in, &tmp, &z__[ibegin + p * z_dim1], &
+   21598             :                                         c__1);
+   21599           0 :                                 i__5 = itmp1, i__6 = isuppz[(p << 1) - 1];
+   21600             :                                 itmp1 = (i__5<i__6) ? i__5 : i__6;
+   21601           0 :                                 i__5 = itmp2, i__6 = isuppz[p * 2];
+   21602             :                                 itmp2 = (i__5>i__6) ? i__5 : i__6;
+   21603             :                             }
+   21604             :                             i__4 = ktot;
+   21605           0 :                             for (p = newftt; p <= i__4; ++p) {
+   21606           0 :                                 isuppz[(p << 1) - 1] = itmp1;
+   21607           0 :                                 isuppz[p * 2] = itmp2;
+   21608             :                             }
+   21609           0 :                             ndone += newsiz;
+   21610             :                         }
+   21611             :                     }
+   21612           0 :                     newfrs = j + 1;
+   21613             :                 }
+   21614             :             }
+   21615           0 :             ++ndepth;
+   21616           0 :             goto L40;
+   21617             :         }
+   21618           0 :         j = wbegin << 1;
+   21619             :         i__2 = wend;
+   21620           0 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+   21621           0 :             isuppz[j - 1] += oldien;
+   21622           0 :             isuppz[j] += oldien;
+   21623           0 :             j += 2;
+   21624             : 
+   21625             :         }
+   21626           0 :         ibegin = iend + 1;
+   21627           0 :         wbegin = wend + 1;
+   21628             :     }
+   21629             : 
+   21630             :     return;
+   21631             : 
+   21632             : } 
+   21633             : }
+   21634             : }
+   21635             : #include <cmath>
+   21636             : #include "lapack.h"
+   21637             : #include "lapack_limits.h"
+   21638             : 
+   21639             : #include "real.h"
+   21640             : 
+   21641             : #include "blas/blas.h"
+   21642             : namespace PLMD{
+   21643             : namespace lapack{
+   21644             : using namespace blas;
+   21645             : void
+   21646           0 : PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(float *f,
+   21647             :         float *g,
+   21648             :         float *cs,
+   21649             :         float *sn,
+   21650             :         float *r)
+   21651             : {
+   21652             :   float minval,safemin, safemin2, safemx2, eps;
+   21653             :   float f1,g1,f1a,g1a,scale;
+   21654             :   int i,n,count;
+   21655             : 
+   21656             :   eps = PLUMED_GMX_FLOAT_EPS;
+   21657             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21658             :   safemin = minval*(1.0+eps);
+   21659             :   n = static_cast<int>(0.5*std::log( safemin/eps ) / std::log(2.0));
+   21660             :   safemin2 = std::pow(static_cast<float>(2.0),static_cast<float>(n));
+   21661             : 
+   21662             :   safemx2 = 1.0 / safemin2;
+   21663             : 
+   21664           0 :   if(std::abs(*g)<PLUMED_GMX_FLOAT_MIN) {
+   21665           0 :     *cs = 1.0;
+   21666           0 :     *sn = 0.0;
+   21667           0 :     *r = *f;
+   21668           0 :   } else if (std::abs(*f)<PLUMED_GMX_FLOAT_MIN) {
+   21669           0 :     *cs = 0.0;
+   21670           0 :     *sn = 1.0;
+   21671           0 :     *r = *g;
+   21672             :   } else {
+   21673             :     f1 = *f;
+   21674             :     g1 = *g;
+   21675             :     f1a = std::abs(f1);
+   21676             :     g1a = std::abs(g1);
+   21677           0 :     scale = (f1a > g1a) ? f1a : g1a;
+   21678           0 :     if(scale >= safemx2) {
+   21679             :       count = 0;
+   21680           0 :       while(scale >= safemx2) {
+   21681           0 :         count++;
+   21682           0 :         f1 *= safemin2;
+   21683           0 :         g1 *= safemin2;
+   21684             :         f1a = std::abs(f1);
+   21685             :         g1a = std::abs(g1);
+   21686           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21687             :       }
+   21688           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21689           0 :       *cs = f1 / *r;
+   21690           0 :       *sn = g1 / *r;
+   21691           0 :       for(i=0;i<count;i++)
+   21692           0 :         *r *= safemx2;
+   21693           0 :     } else if (scale<=safemin2) {
+   21694             :       count = 0;
+   21695           0 :       while(scale <= safemin2) {
+   21696           0 :         count++;
+   21697           0 :         f1 *= safemx2;
+   21698           0 :         g1 *= safemx2;
+   21699             :         f1a = std::abs(f1);
+   21700             :         g1a = std::abs(g1);
+   21701           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21702             :       }
+   21703           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21704           0 :       *cs = f1 / *r;
+   21705           0 :       *sn = g1 / *r;
+   21706           0 :       for(i=0;i<count;i++)
+   21707           0 :         *r *= safemin2;
+   21708             :     } else {
+   21709           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21710           0 :       *cs = f1 / *r;
+   21711           0 :       *sn = g1 / *r;
+   21712             :     }
+   21713           0 :     if(std::abs(*f)>std::abs(*g) && *cs<0.0) {
+   21714           0 :       *cs *= -1.0;
+   21715           0 :       *sn *= -1.0;
+   21716           0 :       *r  *= -1.0;
+   21717             :     }
+   21718             :   }
+   21719           0 :   return;
+   21720             : }
+   21721             :       
+   21722             : }
+   21723             : }
+   21724             : #include <cmath>
+   21725             : #include "lapack.h"
+   21726             : 
+   21727             : #include "blas/blas.h"
+   21728             : namespace PLMD{
+   21729             : namespace lapack{
+   21730             : using namespace blas;
+   21731             : void
+   21732           0 : PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(int *iseed, int *n, float *x)
+   21733             : {
+   21734             :   const int
+   21735           0 :     mm[512] = {
+   21736             :       494,2637,255,2008,1253,
+   21737             :       3344,4084,1739,3143,3468,688,1657,1238,3166,1292,3422,1270,2016,
+   21738             :       154,2862,697,1706,491,931,1444,444,3577,3944,2184,1661,3482,657,
+   21739             :       3023,3618,1267,1828,164,3798,3087,2400,2870,3876,1905,1593,1797,
+   21740             :       1234,3460,328,2861,1950,617,2070,3331,769,1558,2412,2800,189,287,
+   21741             :       2045,1227,2838,209,2770,3654,3993,192,2253,3491,2889,2857,2094,
+   21742             :       1818,688,1407,634,3231,815,3524,1914,516,164,303,2144,3480,119,
+   21743             :       3357,837,2826,2332,2089,3780,1700,3712,150,2000,3375,1621,3090,
+   21744             :       3765,1149,3146,33,3082,2741,359,3316,1749,185,2784,2202,2199,1364,
+   21745             :       1244,2020,3160,2785,2772,1217,1822,1245,2252,3904,2774,997,2573,
+   21746             :       1148,545,322,789,1440,752,2859,123,1848,643,2405,2638,2344,46,
+   21747             :       3814,913,3649,339,3808,822,2832,3078,3633,2970,637,2249,2081,4019,
+   21748             :       1478,242,481,2075,4058,622,3376,812,234,641,4005,1122,3135,2640,
+   21749             :       2302,40,1832,2247,2034,2637,1287,1691,496,1597,2394,2584,1843,336,
+   21750             :       1472,2407,433,2096,1761,2810,566,442,41,1238,1086,603,840,3168,
+   21751             :       1499,1084,3438,2408,1589,2391,288,26,512,1456,171,1677,2657,2270,
+   21752             :       2587,2961,1970,1817,676,1410,3723,2803,3185,184,663,499,3784,1631,
+   21753             :       1925,3912,1398,1349,1441,2224,2411,1907,3192,2786,382,37,759,2948,
+   21754             :       1862,3802,2423,2051,2295,1332,1832,2405,3638,3661,327,3660,716,
+   21755             :       1842,3987,1368,1848,2366,2508,3754,1766,3572,2893,307,1297,3966,
+   21756             :       758,2598,3406,2922,1038,2934,2091,2451,1580,1958,2055,1507,1078,
+   21757             :       3273,17,854,2916,3971,2889,3831,2621,1541,893,736,3992,787,2125,
+   21758             :       2364,2460,257,1574,3912,1216,3248,3401,2124,2762,149,2245,166,466,
+   21759             :       4018,1399,190,2879,153,2320,18,712,2159,2318,2091,3443,1510,449,
+   21760             :       1956,2201,3137,3399,1321,2271,3667,2703,629,2365,2431,1113,3922,
+   21761             :       2554,184,2099,3228,4012,1921,3452,3901,572,3309,3171,817,3039,
+   21762             :       1696,1256,3715,2077,3019,1497,1101,717,51,981,1978,1813,3881,76,
+   21763             :       3846,3694,1682,124,1660,3997,479,1141,886,3514,1301,3604,1888,
+   21764             :       1836,1990,2058,692,1194,20,3285,2046,2107,3508,3525,3801,2549,
+   21765             :       1145,2253,305,3301,1065,3133,2913,3285,1241,1197,3729,2501,1673,
+   21766             :       541,2753,949,2361,1165,4081,2725,3305,3069,3617,3733,409,2157,
+   21767             :       1361,3973,1865,2525,1409,3445,3577,77,3761,2149,1449,3005,225,85,
+   21768             :       3673,3117,3089,1349,2057,413,65,1845,697,3085,3441,1573,3689,2941,
+   21769             :       929,533,2841,4077,721,2821,2249,2397,2817,245,1913,1997,3121,997,
+   21770             :       1833,2877,1633,981,2009,941,2449,197,2441,285,1473,2741,3129,909,
+   21771             :       2801,421,4073,2813,2337,1429,1177,1901,81,1669,2633,2269,129,1141,
+   21772             :       249,3917,2481,3941,2217,2749,3041,1877,345,2861,1809,3141,2825,
+   21773             :       157,2881,3637,1465,2829,2161,3365,361,2685,3745,2325,3609,3821,
+   21774             :       3537,517,3017,2141,1537 
+   21775             :     };
+   21776             : 
+   21777             :     int i__1;
+   21778             : 
+   21779             :     int i__, i1, i2, i3, i4, it1, it2, it3, it4;
+   21780             : 
+   21781             : 
+   21782             :     --iseed;
+   21783             :     --x;
+   21784             : 
+   21785             :     it1 = it2 = it3 = it4 = 0;
+   21786             : 
+   21787           0 :     i1 = iseed[1];
+   21788           0 :     i2 = iseed[2];
+   21789           0 :     i3 = iseed[3];
+   21790           0 :     i4 = iseed[4];
+   21791             : 
+   21792           0 :     i__1 = (*n<128) ? *n : 128;
+   21793           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21794             : 
+   21795           0 :         it4 = i4 * mm[i__ + 383];
+   21796           0 :         it3 = it4 / 4096;
+   21797           0 :         it4 -= it3 << 12;
+   21798           0 :         it3 = it3 + i3 * mm[i__ + 383] + i4 * mm[i__ + 255];
+   21799           0 :         it2 = it3 / 4096;
+   21800           0 :         it3 -= it2 << 12;
+   21801           0 :         it2 = it2 + i2 * mm[i__ + 383] + i3 * mm[i__ + 255] + 
+   21802           0 :           i4 * mm[i__ + 127];
+   21803           0 :         it1 = it2 / 4096;
+   21804           0 :         it2 -= it1 << 12;
+   21805           0 :         it1 = it1 + i1 * mm[i__ + 383] + i2 * mm[i__ + 255] + 
+   21806           0 :           i3 * mm[i__ + 127] + i4 * mm[i__ - 1];
+   21807           0 :         it1 %= 4096;
+   21808             : 
+   21809           0 :         x[i__] = ((float) it1 + ((float) it2 + ((float) it3 + (
+   21810           0 :                 float) it4 * 2.44140625e-4) * 2.44140625e-4) * 
+   21811           0 :                 2.44140625e-4) * 2.44140625e-4;
+   21812             :     }
+   21813             : 
+   21814           0 :     iseed[1] = it1;
+   21815           0 :     iseed[2] = it2;
+   21816           0 :     iseed[3] = it3;
+   21817           0 :     iseed[4] = it4;
+   21818           0 :     return;
+   21819             : 
+   21820             : } 
+   21821             : }
+   21822             : }
+   21823             : #include <cmath>
+   21824             : #include "real.h"
+   21825             : 
+   21826             : #include "lapack.h"
+   21827             : 
+   21828             : #include "blas/blas.h"
+   21829             : namespace PLMD{
+   21830             : namespace lapack{
+   21831             : using namespace blas;
+   21832             : void
+   21833           0 : PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(float *f,
+   21834             :        float *g,
+   21835             :        float *h,
+   21836             :        float *ssmin,
+   21837             :        float *ssmax)
+   21838             : {
+   21839           0 :   float fa = std::abs(*f);
+   21840           0 :   float ga = std::abs(*g);
+   21841           0 :   float ha = std::abs(*h);
+   21842             :   float fhmin,fhmax,tmax,tmin,tmp1,tmp2;
+   21843             :   float as,at,au,c;
+   21844             : 
+   21845           0 :   fhmin = (fa<ha) ? fa : ha;
+   21846           0 :   fhmax = (fa>ha) ? fa : ha;
+   21847             :   
+   21848           0 :   if(std::abs(fhmin)<PLUMED_GMX_FLOAT_MIN) {
+   21849           0 :     *ssmin = 0.0;
+   21850           0 :     if(std::abs(fhmax)<PLUMED_GMX_FLOAT_MIN) 
+   21851           0 :       *ssmax = ga;
+   21852             :     else {
+   21853           0 :       tmax = (fhmax>ga) ? fhmax : ga;
+   21854           0 :       tmin = (fhmax<ga) ? fhmax : ga;
+   21855           0 :       tmp1 = tmin / tmax;
+   21856           0 :       tmp1 = tmp1 * tmp1;
+   21857           0 :       *ssmax = tmax* std::sqrt(1.0 + tmp1);
+   21858             :     }
+   21859             :   } else {
+   21860           0 :     if(ga<fhmax) {
+   21861           0 :       as = 1.0 + fhmin / fhmax;
+   21862           0 :       at = (fhmax-fhmin) / fhmax;
+   21863           0 :       au = (ga/fhmax);
+   21864           0 :       au = au * au;
+   21865           0 :       c = 2.0 / (  std::sqrt(as*as+au) + std::sqrt(at*at+au) );
+   21866           0 :       *ssmin = fhmin * c;
+   21867           0 :       *ssmax = fhmax / c;
+   21868             :     } else {
+   21869           0 :       au = fhmax / ga;
+   21870           0 :       if(std::abs(au)<PLUMED_GMX_FLOAT_MIN) {
+   21871           0 :         *ssmin = (fhmin*fhmax)/ga;
+   21872           0 :         *ssmax = ga;
+   21873             :       } else {
+   21874           0 :         as = 1.0 + fhmin / fhmax;
+   21875           0 :         at = (fhmax-fhmin)/fhmax;
+   21876           0 :         tmp1 = as*au;
+   21877           0 :         tmp2 = at*au;
+   21878           0 :         c = 1.0 / (  std::sqrt(1.0+tmp1*tmp1) + std::sqrt(1.0+tmp2*tmp2));
+   21879           0 :         *ssmin = (fhmin*c)*au;
+   21880           0 :         *ssmin = *ssmin + *ssmin;
+   21881           0 :         *ssmax = ga / (c+c);
+   21882             :       }
+   21883             :     }
+   21884             :   }
+   21885           0 :   return;
+   21886             : }
+   21887             : }
+   21888             : }
+   21889             : #include <cctype>
+   21890             : #include <cmath>
+   21891             : #include "real.h"
+   21892             : 
+   21893             : #include "lapack.h"
+   21894             : #include "lapack_limits.h"
+   21895             : 
+   21896             : 
+   21897             : #include "blas/blas.h"
+   21898             : namespace PLMD{
+   21899             : namespace lapack{
+   21900             : using namespace blas;
+   21901             : void
+   21902           0 : PLUMED_BLAS_F77_FUNC(slascl,SLASCL)(const char *type,
+   21903             :                         int *kl,
+   21904             :                         int *ku,
+   21905             :                         float *cfrom,
+   21906             :                         float *cto,
+   21907             :                         int *m,
+   21908             :                         int *n,
+   21909             :                         float *a,
+   21910             :                         int *lda,
+   21911             :                         int *info)
+   21912             : {
+   21913           0 :   const char ch=std::toupper(*type);
+   21914             :   int i,j,k,l,k1,k2,k3,k4;
+   21915             :   int done=0;
+   21916             :   float minval,smlnum,bignum;
+   21917             :   float cfromc, ctoc, cfrom1, cto1, mul;
+   21918             : 
+   21919           0 :   if(*n<=0 || *m<=0)
+   21920             :     return;
+   21921             : 
+   21922             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21923             :   smlnum = minval / PLUMED_GMX_FLOAT_EPS;
+   21924             :   bignum = 1.0 / smlnum;
+   21925             : 
+   21926           0 :   cfromc = *cfrom;
+   21927           0 :   ctoc   = *cto;
+   21928             : 
+   21929           0 :   while(!done) {
+   21930             :     
+   21931           0 :     cfrom1 = cfromc * smlnum;
+   21932           0 :     cto1   = ctoc / bignum;
+   21933             : 
+   21934           0 :     if(std::abs(cfrom1)>std::abs(ctoc) && std::abs(ctoc)>PLUMED_GMX_FLOAT_MIN) {
+   21935             :       mul = smlnum;
+   21936             :       done = 0;
+   21937             :       cfromc = cfrom1;
+   21938           0 :     } else if(std::abs(cto1)>std::abs(cfromc)) {
+   21939             :       mul = bignum;
+   21940             :       done = 0;
+   21941             :       ctoc = cto1;
+   21942             :     } else {
+   21943           0 :       mul = ctoc / cfromc;
+   21944             :       done = 1;
+   21945             :     }
+   21946             : 
+   21947           0 :     switch(ch) {
+   21948             :     case 'G': 
+   21949             :       /* Full matrix */
+   21950           0 :       for(j=0;j<*n;j++)
+   21951           0 :         for(i=0;i<*m;i++)
+   21952           0 :           a[j*(*lda)+i] *= mul;
+   21953             :       break;
+   21954             : 
+   21955             :     case 'L': 
+   21956             :       /* Lower triangular matrix */
+   21957           0 :       for(j=0;j<*n;j++)
+   21958           0 :         for(i=j;i<*m;i++)
+   21959           0 :           a[j*(*lda)+i] *= mul;
+   21960             :       break;
+   21961             : 
+   21962             :     case 'U': 
+   21963             :       /* Upper triangular matrix */
+   21964           0 :       for(j=0;j<*n;j++) {
+   21965           0 :         k = (j < (*m-1)) ? j : (*m-1);
+   21966           0 :         for(i=0;i<=k;i++)
+   21967           0 :           a[j*(*lda)+i] *= mul;
+   21968             :       }
+   21969             :       break;
+   21970             : 
+   21971             :     case 'H': 
+   21972             :       /* Upper Hessenberg matrix */
+   21973           0 :       for(j=0;j<*n;j++) {
+   21974           0 :         k = ((j+1) < (*m-1)) ? (j+1) : (*m-1);
+   21975           0 :         for(i=0;i<=k;i++)
+   21976           0 :           a[j*(*lda)+i] *= mul;
+   21977             :       }
+   21978             :       break;
+   21979             : 
+   21980           0 :     case 'B': 
+   21981             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21982             :        * only the lower half stored.
+   21983             :        */
+   21984           0 :       k3 = *kl;
+   21985           0 :       k4 = *n - 1;
+   21986           0 :       for(j=0;j<*n;j++) {
+   21987           0 :         k = (k3 < (k4-j)) ? k3 : (k4-j);
+   21988           0 :         for(i=0;i<=k;i++)
+   21989           0 :           a[j*(*lda)+i] *= mul;
+   21990             :       }
+   21991             :       break;
+   21992             : 
+   21993           0 :     case 'Q': 
+   21994             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21995             :        * only the upper half stored.
+   21996             :        */
+   21997           0 :       k1 = *ku;
+   21998             :       k3 = *ku;
+   21999           0 :       for(j=0;j<*n;j++) {
+   22000           0 :         k = ((k1-j) > 0) ? (k1-j) : 0;
+   22001           0 :         for(i=k;i<=k3;i++)
+   22002           0 :           a[j*(*lda)+i] *= mul;
+   22003             :       }
+   22004             :       break;
+   22005             : 
+   22006           0 :     case 'Z': 
+   22007             :       /* Band matrix, lower bandwidth KL, upper KU. */
+   22008             : 
+   22009           0 :       k1 = *kl + *ku;
+   22010             :       k2 = *kl;
+   22011           0 :       k3 = 2*(*kl) + *ku;
+   22012           0 :       k4 = *kl + *ku - 1 + *m;
+   22013           0 :       for(j=0;j<*n;j++) {
+   22014           0 :         k = ((k1-j) > k2) ? (k1-j) : k2;
+   22015           0 :         l = (k3 < (k4-j)) ? k3 : (k4-j);
+   22016           0 :         for(i=k;i<=l;i++)
+   22017           0 :           a[j*(*lda)+i] *= mul;
+   22018             :       }
+   22019             :       break;
+   22020             : 
+   22021           0 :     default:
+   22022           0 :       *info = -1;
+   22023           0 :       return;
+   22024             :     }
+   22025             :   } /* finished */
+   22026             : 
+   22027           0 :   *info = 0;
+   22028           0 :   return;
+   22029             : }
+   22030             : }
+   22031             : }
+   22032             : #include "lapack.h"
+   22033             : 
+   22034             : #include "blas/blas.h"
+   22035             : namespace PLMD{
+   22036             : namespace lapack{
+   22037             : using namespace blas;
+   22038             : void 
+   22039           0 : PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(int *n, 
+   22040             :         int *sqre, 
+   22041             :         float *d__, 
+   22042             :         float *e, 
+   22043             :         float *u, 
+   22044             :         int *ldu, 
+   22045             :         float *vt, 
+   22046             :         int *ldvt,
+   22047             :         int *smlsiz, 
+   22048             :         int *iwork,
+   22049             :         float *work, 
+   22050             :         int *info)
+   22051             : {
+   22052             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   22053             : 
+   22054             :     int i__, j, m, i1, ic, lf, nd, ll, nl, nr, im1, ncc, nlf, nrf, 
+   22055             :             iwk, lvl, ndb1, nlp1, nrp1;
+   22056             :     float beta;
+   22057             :     int idxq, nlvl;
+   22058             :     float alpha;
+   22059             :     int inode, ndiml, idxqc, ndimr, itemp, sqrei;
+   22060           0 :     int c__0 = 0;
+   22061             : 
+   22062             : 
+   22063           0 :     --d__;
+   22064           0 :     --e;
+   22065           0 :     u_dim1 = *ldu;
+   22066           0 :     u_offset = 1 + u_dim1;
+   22067           0 :     u -= u_offset;
+   22068           0 :     vt_dim1 = *ldvt;
+   22069           0 :     vt_offset = 1 + vt_dim1;
+   22070           0 :     vt -= vt_offset;
+   22071           0 :     --iwork;
+   22072             :     --work;
+   22073             : 
+   22074           0 :     *info = 0;
+   22075             : 
+   22076           0 :     if (*n < 0) {
+   22077           0 :         *info = -1;
+   22078           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22079           0 :         *info = -2;
+   22080             :     }
+   22081             : 
+   22082           0 :     m = *n + *sqre;
+   22083             : 
+   22084           0 :     if (*ldu < *n) {
+   22085           0 :         *info = -6;
+   22086           0 :     } else if (*ldvt < m) {
+   22087           0 :         *info = -8;
+   22088           0 :     } else if (*smlsiz < 3) {
+   22089           0 :         *info = -9;
+   22090             :     }
+   22091           0 :     if (*info != 0) {
+   22092             :         return;
+   22093             :     }
+   22094             : 
+   22095           0 :     if (*n <= *smlsiz) {
+   22096           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset], 
+   22097             :                 ldvt, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], info);
+   22098           0 :         return;
+   22099             :     }
+   22100             : 
+   22101             :     inode = 1;
+   22102           0 :     ndiml = inode + *n;
+   22103           0 :     ndimr = ndiml + *n;
+   22104           0 :     idxq = ndimr + *n;
+   22105           0 :     iwk = idxq + *n;
+   22106           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   22107             :             smlsiz);
+   22108             : 
+   22109           0 :     ndb1 = (nd + 1) / 2;
+   22110           0 :     ncc = 0;
+   22111             :     i__1 = nd;
+   22112           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   22113             : 
+   22114           0 :         i1 = i__ - 1;
+   22115           0 :         ic = iwork[inode + i1];
+   22116           0 :         nl = iwork[ndiml + i1];
+   22117           0 :         nlp1 = nl + 1;
+   22118           0 :         nr = iwork[ndimr + i1];
+   22119           0 :         nrp1 = nr + 1;
+   22120           0 :         nlf = ic - nl;
+   22121           0 :         nrf = ic + 1;
+   22122           0 :         sqrei = 1;
+   22123           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &vt[
+   22124           0 :                 nlf + nlf * vt_dim1], ldvt, &u[nlf + nlf * u_dim1], ldu, &u[
+   22125           0 :                 nlf + nlf * u_dim1], ldu, &work[1], info);
+   22126           0 :         if (*info != 0) {
+   22127             :             return;
+   22128             :         }
+   22129           0 :         itemp = idxq + nlf - 2;
+   22130           0 :         i__2 = nl;
+   22131           0 :         for (j = 1; j <= i__2; ++j) {
+   22132           0 :             iwork[itemp + j] = j;
+   22133             :         }
+   22134           0 :         if (i__ == nd) {
+   22135           0 :             sqrei = *sqre;
+   22136             :         } else {
+   22137           0 :             sqrei = 1;
+   22138             :         }
+   22139           0 :         nrp1 = nr + sqrei;
+   22140           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &vt[
+   22141           0 :                 nrf + nrf * vt_dim1], ldvt, &u[nrf + nrf * u_dim1], ldu, &u[
+   22142           0 :                 nrf + nrf * u_dim1], ldu, &work[1], info);
+   22143           0 :         if (*info != 0) {
+   22144             :             return;
+   22145             :         }
+   22146           0 :         itemp = idxq + ic;
+   22147           0 :         i__2 = nr;
+   22148           0 :         for (j = 1; j <= i__2; ++j) {
+   22149           0 :             iwork[itemp + j - 1] = j;
+   22150             :         }
+   22151             :     }
+   22152             : 
+   22153           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   22154             : 
+   22155           0 :         if (lvl == 1) {
+   22156             :             lf = 1;
+   22157             :             ll = 1;
+   22158             :         } else {
+   22159           0 :             i__1 = lvl - 1;
+   22160           0 :             lf = (1 << i__1);
+   22161           0 :             ll = (lf << 1) - 1;
+   22162             :         }
+   22163             :         i__1 = ll;
+   22164           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   22165           0 :             im1 = i__ - 1;
+   22166           0 :             ic = iwork[inode + im1];
+   22167           0 :             nl = iwork[ndiml + im1];
+   22168           0 :             nr = iwork[ndimr + im1];
+   22169           0 :             nlf = ic - nl;
+   22170           0 :             if (*sqre == 0 && i__ == ll) {
+   22171           0 :                 sqrei = *sqre;
+   22172             :             } else {
+   22173           0 :                 sqrei = 1;
+   22174             :             }
+   22175           0 :             idxqc = idxq + nlf - 1;
+   22176           0 :             alpha = d__[ic];
+   22177           0 :             beta = e[ic];
+   22178           0 :             PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(&nl, &nr, &sqrei, &d__[nlf], &alpha, &beta, &u[nlf + nlf *
+   22179           0 :                      u_dim1], ldu, &vt[nlf + nlf * vt_dim1], ldvt, &iwork[
+   22180           0 :                     idxqc], &iwork[iwk], &work[1], info);
+   22181           0 :             if (*info != 0) {
+   22182             :                 return;
+   22183             :             }
+   22184             :         }
+   22185             :     }
+   22186             : 
+   22187             :     return;
+   22188             : 
+   22189             : }
+   22190             : }
+   22191             : }
+   22192             : #include <cmath>
+   22193             : #include "lapack.h"
+   22194             : 
+   22195             : #include "blas/blas.h"
+   22196             : namespace PLMD{
+   22197             : namespace lapack{
+   22198             : using namespace blas;
+   22199             : void 
+   22200           0 : PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(int *nl, 
+   22201             :         int *nr, 
+   22202             :         int *sqre, 
+   22203             :         float *d__, 
+   22204             :         float *alpha, 
+   22205             :         float *beta, 
+   22206             :         float *u, 
+   22207             :         int *ldu, 
+   22208             :         float *vt, 
+   22209             :         int *ldvt, 
+   22210             :         int *idxq, 
+   22211             :         int *iwork, 
+   22212             :         float *work, 
+   22213             :         int *info)
+   22214             : {
+   22215             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1;
+   22216             :     float d__1, d__2;
+   22217             : 
+   22218             :     int i__, k, m, n, n1, n2, iq, iz, iu2, ldq, idx, ldu2, ivt2, 
+   22219             :             idxc, idxp, ldvt2;
+   22220             :     int isigma;
+   22221             :     float orgnrm;
+   22222             :     int coltyp;
+   22223           0 :     int c__0 = 0;
+   22224           0 :     float one = 1.0;
+   22225           0 :     int c__1 = 1;
+   22226           0 :     int c_n1 = -1;
+   22227             : 
+   22228           0 :     --d__;
+   22229             :     u_dim1 = *ldu;
+   22230             :     u_offset = 1 + u_dim1;
+   22231             :     u -= u_offset;
+   22232             :     vt_dim1 = *ldvt;
+   22233             :     vt_offset = 1 + vt_dim1;
+   22234             :     vt -= vt_offset;
+   22235             :     --idxq;
+   22236           0 :     --iwork;
+   22237           0 :     --work;
+   22238             : 
+   22239           0 :     *info = 0;
+   22240             : 
+   22241           0 :     if (*nl < 1) {
+   22242           0 :         *info = -1;
+   22243           0 :     } else if (*nr < 1) {
+   22244           0 :         *info = -2;
+   22245           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22246           0 :         *info = -3;
+   22247             :     }
+   22248           0 :     if (*info != 0) {
+   22249             :         return;
+   22250             :     }
+   22251             : 
+   22252           0 :     n = *nl + *nr + 1;
+   22253           0 :     m = n + *sqre;
+   22254             : 
+   22255             : 
+   22256           0 :     ldu2 = n;
+   22257           0 :     ldvt2 = m;
+   22258             : 
+   22259             :     iz = 1;
+   22260           0 :     isigma = iz + m;
+   22261           0 :     iu2 = isigma + n;
+   22262           0 :     ivt2 = iu2 + ldu2 * n;
+   22263           0 :     iq = ivt2 + ldvt2 * m;
+   22264             : 
+   22265             :     idx = 1;
+   22266           0 :     idxc = idx + n;
+   22267           0 :     coltyp = idxc + n;
+   22268           0 :     idxp = coltyp + n;
+   22269             : 
+   22270           0 :     d__1 = std::abs(*alpha);
+   22271           0 :     d__2 = std::abs(*beta);
+   22272           0 :     orgnrm = (d__1>d__2) ? d__1 : d__2;
+   22273           0 :     d__[*nl + 1] = 0.;
+   22274             :     i__1 = n;
+   22275           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22276           0 :         if (std::abs(d__[i__]) > orgnrm) {
+   22277           0 :             orgnrm = std::abs(d__[i__]);
+   22278             :         }
+   22279             :     }
+   22280           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   22281           0 :     *alpha /= orgnrm;
+   22282           0 :     *beta /= orgnrm;
+   22283             : 
+   22284           0 :     PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(nl, nr, sqre, &k, &d__[1], &work[iz], alpha, beta, &u[u_offset], 
+   22285           0 :             ldu, &vt[vt_offset], ldvt, &work[isigma], &work[iu2], &ldu2, &
+   22286           0 :             work[ivt2], &ldvt2, &iwork[idxp], &iwork[idx], &iwork[idxc], &
+   22287           0 :             idxq[1], &iwork[coltyp], info);
+   22288             : 
+   22289           0 :     ldq = k;
+   22290           0 :     PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(nl, nr, sqre, &k, &d__[1], &work[iq], &ldq, &work[isigma], &u[
+   22291             :             u_offset], ldu, &work[iu2], &ldu2, &vt[vt_offset], ldvt, &work[
+   22292             :             ivt2], &ldvt2, &iwork[idxc], &iwork[coltyp], &work[iz], info);
+   22293           0 :     if (*info != 0) {
+   22294             :         return;
+   22295             :     }
+   22296           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   22297             : 
+   22298           0 :     n1 = k;
+   22299           0 :     n2 = n - k;
+   22300           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   22301             : 
+   22302             :     return;
+   22303             : 
+   22304             : }
+   22305             : }
+   22306             : }
+   22307             : #include <cmath>
+   22308             : #include "blas/blas.h"
+   22309             : #include "lapack.h"
+   22310             : #include "lapack_limits.h"
+   22311             : 
+   22312             : #include "real.h"
+   22313             : 
+   22314             : #include "blas/blas.h"
+   22315             : namespace PLMD{
+   22316             : namespace lapack{
+   22317             : using namespace blas;
+   22318             : void 
+   22319           0 : PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(int *nl, 
+   22320             :                         int *nr, 
+   22321             :                         int *sqre, 
+   22322             :                         int *k, 
+   22323             :                         float *d__, 
+   22324             :                         float *z__, 
+   22325             :                         float *alpha, 
+   22326             :                         float *beta, 
+   22327             :                         float *u, 
+   22328             :                         int *ldu, 
+   22329             :                         float *vt, 
+   22330             :                         int *ldvt, 
+   22331             :                         float *dsigma, 
+   22332             :                         float *u2, 
+   22333             :                         int *ldu2, 
+   22334             :                         float *vt2, 
+   22335             :                         int *ldvt2, 
+   22336             :                         int *idxp, 
+   22337             :                         int *idx, 
+   22338             :                         int *idxc, 
+   22339             :                         int *idxq, 
+   22340             :                         int *coltyp, 
+   22341             :                         int *info)
+   22342             : {
+   22343             :     int u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, vt_offset;
+   22344             :     int vt2_dim1, vt2_offset, i__1;
+   22345             :     float d__1, d__2;
+   22346             : 
+   22347             :     float c__;
+   22348             :     int i__, j, m, n;
+   22349             :     float s;
+   22350             :     int k2;
+   22351             :     float z1;
+   22352             :     int ct, jp;
+   22353             :     float eps, tau, tol;
+   22354             :     int psm[4], nlp1, nlp2, idxi, idxj;
+   22355             :     int ctot[4], idxjp;
+   22356             :     int jprev = 0;
+   22357             :     float hlftol;
+   22358           0 :     float zero = 0.0;
+   22359           0 :     int c__1 = 1;
+   22360             : 
+   22361             : 
+   22362           0 :     --d__;
+   22363           0 :     --z__;
+   22364           0 :     u_dim1 = *ldu;
+   22365           0 :     u_offset = 1 + u_dim1;
+   22366           0 :     u -= u_offset;
+   22367           0 :     vt_dim1 = *ldvt;
+   22368           0 :     vt_offset = 1 + vt_dim1;
+   22369           0 :     vt -= vt_offset;
+   22370           0 :     --dsigma;
+   22371           0 :     u2_dim1 = *ldu2;
+   22372           0 :     u2_offset = 1 + u2_dim1;
+   22373           0 :     u2 -= u2_offset;
+   22374           0 :     vt2_dim1 = *ldvt2;
+   22375           0 :     vt2_offset = 1 + vt2_dim1;
+   22376           0 :     vt2 -= vt2_offset;
+   22377           0 :     --idxp;
+   22378           0 :     --idx;
+   22379           0 :     --idxc;
+   22380           0 :     --idxq;
+   22381           0 :     --coltyp;
+   22382             : 
+   22383           0 :     *info = 0;
+   22384             : 
+   22385           0 :     n = *nl + *nr + 1;
+   22386           0 :     m = n + *sqre;
+   22387             : 
+   22388           0 :     nlp1 = *nl + 1;
+   22389           0 :     nlp2 = *nl + 2;
+   22390             : 
+   22391           0 :     z1 = *alpha * vt[nlp1 + nlp1 * vt_dim1];
+   22392           0 :     z__[1] = z1;
+   22393           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   22394           0 :         z__[i__ + 1] = *alpha * vt[i__ + nlp1 * vt_dim1];
+   22395           0 :         d__[i__ + 1] = d__[i__];
+   22396           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   22397             :     }
+   22398             : 
+   22399             :     i__1 = m;
+   22400           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22401           0 :         z__[i__] = *beta * vt[i__ + nlp2 * vt_dim1];
+   22402             :     }
+   22403             : 
+   22404             :     i__1 = nlp1;
+   22405           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22406           0 :         coltyp[i__] = 1;
+   22407             :     }
+   22408           0 :     i__1 = n;
+   22409           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22410           0 :         coltyp[i__] = 2;
+   22411             :     }
+   22412             : 
+   22413             :     i__1 = n;
+   22414           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22415           0 :         idxq[i__] += nlp1;
+   22416             :     }
+   22417             : 
+   22418             :     i__1 = n;
+   22419           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22420           0 :         dsigma[i__] = d__[idxq[i__]];
+   22421           0 :         u2[i__ + u2_dim1] = z__[idxq[i__]];
+   22422           0 :         idxc[i__] = coltyp[idxq[i__]];
+   22423             :     }
+   22424             : 
+   22425           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   22426             : 
+   22427           0 :     i__1 = n;
+   22428           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22429           0 :         idxi = idx[i__] + 1;
+   22430           0 :         d__[i__] = dsigma[idxi];
+   22431           0 :         z__[i__] = u2[idxi + u2_dim1];
+   22432           0 :         coltyp[i__] = idxc[idxi];
+   22433             :     }
+   22434             : 
+   22435             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22436           0 :     d__1 = std::abs(*alpha), d__2 = std::abs(*beta);
+   22437           0 :     tol = (d__1 > d__2) ? d__1 : d__2;
+   22438           0 :     d__2 = std::abs(d__[n]);
+   22439           0 :     tol = eps * 8. * ((d__2 > tol) ? d__2 : tol);
+   22440             : 
+   22441           0 :     *k = 1;
+   22442           0 :     k2 = n + 1;
+   22443             :     i__1 = n;
+   22444           0 :     for (j = 2; j <= i__1; ++j) {
+   22445           0 :         if (std::abs(z__[j]) <= tol) {
+   22446             : 
+   22447           0 :             --k2;
+   22448           0 :             idxp[k2] = j;
+   22449           0 :             coltyp[j] = 4;
+   22450           0 :             if (j == n) {
+   22451           0 :                 goto L120;
+   22452             :             }
+   22453             :         } else {
+   22454             :             jprev = j;
+   22455           0 :             goto L90;
+   22456             :         }
+   22457             :     }
+   22458           0 : L90:
+   22459             :     j = jprev;
+   22460           0 : L100:
+   22461           0 :     ++j;
+   22462           0 :     if (j > n) {
+   22463           0 :         goto L110;
+   22464             :     }
+   22465           0 :     if (std::abs(z__[j]) <= tol) {
+   22466             : 
+   22467           0 :         --k2;
+   22468           0 :         idxp[k2] = j;
+   22469           0 :         coltyp[j] = 4;
+   22470             :     } else {
+   22471             : 
+   22472           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   22473             : 
+   22474           0 :             s = z__[jprev];
+   22475           0 :             c__ = z__[j];
+   22476             : 
+   22477           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&c__, &s);
+   22478           0 :             c__ /= tau;
+   22479           0 :             s = -s / tau;
+   22480           0 :             z__[j] = tau;
+   22481           0 :             z__[jprev] = 0.;
+   22482             : 
+   22483           0 :             idxjp = idxq[idx[jprev] + 1];
+   22484           0 :             idxj = idxq[idx[j] + 1];
+   22485           0 :             if (idxjp <= nlp1) {
+   22486           0 :                 --idxjp;
+   22487             :             }
+   22488           0 :             if (idxj <= nlp1) {
+   22489           0 :                 --idxj;
+   22490             :             }
+   22491           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&n, &u[idxjp * u_dim1 + 1], &c__1, &u[idxj * u_dim1 + 1], &
+   22492             :                     c__1, &c__, &s);
+   22493           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&m, &vt[idxjp + vt_dim1], ldvt, &vt[idxj + vt_dim1], ldvt, &
+   22494             :                     c__, &s);
+   22495           0 :             if (coltyp[j] != coltyp[jprev]) {
+   22496           0 :                 coltyp[j] = 3;
+   22497             :             }
+   22498           0 :             coltyp[jprev] = 4;
+   22499           0 :             --k2;
+   22500           0 :             idxp[k2] = jprev;
+   22501             :             jprev = j;
+   22502             :         } else {
+   22503           0 :             ++(*k);
+   22504           0 :             u2[*k + u2_dim1] = z__[jprev];
+   22505           0 :             dsigma[*k] = d__[jprev];
+   22506           0 :             idxp[*k] = jprev;
+   22507             :             jprev = j;
+   22508             :         }
+   22509             :     }
+   22510           0 :     goto L100;
+   22511             : L110:
+   22512             : 
+   22513           0 :     ++(*k);
+   22514           0 :     u2[*k + u2_dim1] = z__[jprev];
+   22515           0 :     dsigma[*k] = d__[jprev];
+   22516           0 :     idxp[*k] = jprev;
+   22517             : 
+   22518             : L120:
+   22519             : 
+   22520           0 :     for (j = 1; j <= 4; ++j) {
+   22521           0 :         ctot[j - 1] = 0;
+   22522             :     }
+   22523           0 :     i__1 = n;
+   22524           0 :     for (j = 2; j <= i__1; ++j) {
+   22525           0 :         ct = coltyp[j];
+   22526           0 :         ++ctot[ct - 1];
+   22527             :     }
+   22528             : 
+   22529           0 :     psm[0] = 2;
+   22530           0 :     psm[1] = ctot[0] + 2;
+   22531           0 :     psm[2] = psm[1] + ctot[1];
+   22532           0 :     psm[3] = psm[2] + ctot[2];
+   22533             : 
+   22534             :     i__1 = n;
+   22535           0 :     for (j = 2; j <= i__1; ++j) {
+   22536           0 :         jp = idxp[j];
+   22537           0 :         ct = coltyp[jp];
+   22538           0 :         idxc[psm[ct - 1]] = j;
+   22539           0 :         ++psm[ct - 1];
+   22540             :     }
+   22541             : 
+   22542             :     i__1 = n;
+   22543           0 :     for (j = 2; j <= i__1; ++j) {
+   22544           0 :         jp = idxp[j];
+   22545           0 :         dsigma[j] = d__[jp];
+   22546           0 :         idxj = idxq[idx[idxp[idxc[j]]] + 1];
+   22547           0 :         if (idxj <= nlp1) {
+   22548           0 :             --idxj;
+   22549             :         }
+   22550           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u[idxj * u_dim1 + 1], &c__1, &u2[j * u2_dim1 + 1], &c__1);
+   22551           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[idxj + vt_dim1], ldvt, &vt2[j + vt2_dim1], ldvt2);
+   22552             :     }
+   22553             : 
+   22554           0 :     dsigma[1] = 0.;
+   22555           0 :     hlftol = tol / 2.;
+   22556           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   22557           0 :         dsigma[2] = hlftol;
+   22558             :     }
+   22559           0 :     if (m > n) {
+   22560           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   22561           0 :         if (z__[1] <= tol) {
+   22562           0 :             c__ = 1.;
+   22563           0 :             s = 0.;
+   22564           0 :             z__[1] = tol;
+   22565             :         } else {
+   22566           0 :             c__ = z1 / z__[1];
+   22567           0 :             s = z__[m] / z__[1];
+   22568             :         }
+   22569             :     } else {
+   22570           0 :         if (std::abs(z1) <= tol) {
+   22571           0 :             z__[1] = tol;
+   22572             :         } else {
+   22573           0 :             z__[1] = z1;
+   22574             :         }
+   22575             :     }
+   22576             : 
+   22577           0 :     i__1 = *k - 1;
+   22578           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &u2[u2_dim1 + 2], &c__1, &z__[2], &c__1);
+   22579             : 
+   22580           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &n, &c__1, &zero, &zero, &u2[u2_offset], ldu2);
+   22581           0 :     u2[nlp1 + u2_dim1] = 1.;
+   22582           0 :     if (m > n) {
+   22583             :         i__1 = nlp1;
+   22584           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22585           0 :             vt[m + i__ * vt_dim1] = -s * vt[nlp1 + i__ * vt_dim1];
+   22586           0 :             vt2[i__ * vt2_dim1 + 1] = c__ * vt[nlp1 + i__ * vt_dim1];
+   22587             :         }
+   22588           0 :         i__1 = m;
+   22589           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22590           0 :             vt2[i__ * vt2_dim1 + 1] = s * vt[m + i__ * vt_dim1];
+   22591           0 :             vt[m + i__ * vt_dim1] = c__ * vt[m + i__ * vt_dim1];
+   22592             :         }
+   22593             :     } else {
+   22594           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[nlp1 + vt_dim1], ldvt, &vt2[vt2_dim1 + 1], ldvt2);
+   22595             :     }
+   22596           0 :     if (m > n) {
+   22597           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[m + vt_dim1], ldvt, &vt2[m + vt2_dim1], ldvt2);
+   22598             :     }
+   22599             : 
+   22600           0 :     if (n > *k) {
+   22601           0 :         i__1 = n - *k;
+   22602           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   22603           0 :         i__1 = n - *k;
+   22604           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &n, &i__1, &u2[(*k + 1) * u2_dim1 + 1], ldu2, &u[(*k + 1)
+   22605           0 :                  * u_dim1 + 1], ldu);
+   22606           0 :         i__1 = n - *k;
+   22607           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &i__1, &m, &vt2[*k + 1 + vt2_dim1], ldvt2, &vt[*k + 1 + 
+   22608           0 :                 vt_dim1], ldvt);
+   22609             :     }
+   22610           0 :     for (j = 1; j <= 4; ++j) {
+   22611           0 :         coltyp[j] = ctot[j - 1];
+   22612             :     }
+   22613             : 
+   22614           0 :     return;
+   22615             : 
+   22616             : }
+   22617             : 
+   22618             : 
+   22619             : }
+   22620             : }
+   22621             : #include <cmath>
+   22622             : #include "blas/blas.h"
+   22623             : #include "lapack.h"
+   22624             : 
+   22625             : #include "blas/blas.h"
+   22626             : namespace PLMD{
+   22627             : namespace lapack{
+   22628             : using namespace blas;
+   22629             : void 
+   22630           0 : PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(int *nl, 
+   22631             :         int *nr,
+   22632             :         int *sqre, 
+   22633             :         int *k, 
+   22634             :         float *d__, 
+   22635             :         float *q, 
+   22636             :         int *ldq, 
+   22637             :         float *dsigma, 
+   22638             :         float *u, 
+   22639             :         int *ldu, 
+   22640             :         float *u2, 
+   22641             :         int *ldu2, 
+   22642             :         float *vt, 
+   22643             :         int *ldvt, 
+   22644             :         float *vt2, 
+   22645             :         int *ldvt2, 
+   22646             :         int *idxc, 
+   22647             :         int *ctot, 
+   22648             :         float *z__, 
+   22649             :         int *info)
+   22650             : {
+   22651             :     int q_dim1, q_offset, u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, 
+   22652             :             vt_offset, vt2_dim1, vt2_offset, i__1, i__2;
+   22653             :     float d__2;
+   22654             : 
+   22655             :     int i__, j, m, n, jc;
+   22656             :     float rho;
+   22657             :     int nlp1, nlp2, nrp1;
+   22658             :     float temp;
+   22659             :     int ctemp;
+   22660             :     int ktemp;
+   22661           0 :     int c__1 = 1;
+   22662           0 :     int c__0 = 0;
+   22663           0 :     float zero = 0.0;
+   22664           0 :     float one = 1.0;
+   22665             : 
+   22666             :     --d__;
+   22667           0 :     q_dim1 = *ldq;
+   22668           0 :     q_offset = 1 + q_dim1;
+   22669           0 :     q -= q_offset;
+   22670           0 :     --dsigma;
+   22671           0 :     u_dim1 = *ldu;
+   22672           0 :     u_offset = 1 + u_dim1;
+   22673           0 :     u -= u_offset;
+   22674           0 :     u2_dim1 = *ldu2;
+   22675           0 :     u2_offset = 1 + u2_dim1;
+   22676           0 :     u2 -= u2_offset;
+   22677           0 :     vt_dim1 = *ldvt;
+   22678           0 :     vt_offset = 1 + vt_dim1;
+   22679           0 :     vt -= vt_offset;
+   22680           0 :     vt2_dim1 = *ldvt2;
+   22681           0 :     vt2_offset = 1 + vt2_dim1;
+   22682           0 :     vt2 -= vt2_offset;
+   22683           0 :     --idxc;
+   22684             :     --ctot;
+   22685           0 :     --z__;
+   22686             : 
+   22687             :     /* Function Body */
+   22688           0 :     *info = 0;
+   22689             : 
+   22690           0 :     if (*nl < 1) {
+   22691           0 :         *info = -1;
+   22692           0 :     } else if (*nr < 1) {
+   22693           0 :         *info = -2;
+   22694           0 :     } else if (*sqre != 1 && *sqre != 0) {
+   22695           0 :         *info = -3;
+   22696             :     }
+   22697             : 
+   22698           0 :     n = *nl + *nr + 1;
+   22699           0 :     m = n + *sqre;
+   22700           0 :     nlp1 = *nl + 1;
+   22701           0 :     nlp2 = *nl + 2;
+   22702             : 
+   22703           0 :     if (*k == 1) {
+   22704           0 :         d__[1] = std::abs(z__[1]);
+   22705           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt2[vt2_dim1 + 1], ldvt2, &vt[vt_dim1 + 1], ldvt);
+   22706           0 :         if (z__[1] > 0.) {
+   22707           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u2[u2_dim1 + 1], &c__1, &u[u_dim1 + 1], &c__1);
+   22708             :         } else {
+   22709           0 :             i__1 = n;
+   22710           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   22711           0 :                 u[i__ + u_dim1] = -u2[i__ + u2_dim1];
+   22712             :             }
+   22713             :         }
+   22714           0 :         return;
+   22715             :     }
+   22716             : 
+   22717           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &z__[1], &c__1, &q[q_offset], &c__1);
+   22718             : 
+   22719           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   22720           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   22721           0 :     rho *= rho;
+   22722             : 
+   22723             : 
+   22724           0 :     i__1 = *k;
+   22725           0 :     for (j = 1; j <= i__1; ++j) {
+   22726           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &u[j * u_dim1 + 1], &rho, &d__[j],
+   22727           0 :                  &vt[j * vt_dim1 + 1], info);
+   22728             : 
+   22729           0 :         if (*info != 0) {
+   22730             :             return;
+   22731             :         }
+   22732             :     }
+   22733             : 
+   22734           0 :     i__1 = *k;
+   22735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22736           0 :         z__[i__] = u[i__ + *k * u_dim1] * vt[i__ + *k * vt_dim1];
+   22737             :         i__2 = i__ - 1;
+   22738           0 :         for (j = 1; j <= i__2; ++j) {
+   22739           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22740           0 :                     i__] - dsigma[j]) / (dsigma[i__] + dsigma[j]);
+   22741             :         }
+   22742           0 :         i__2 = *k - 1;
+   22743           0 :         for (j = i__; j <= i__2; ++j) {
+   22744           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22745           0 :                     i__] - dsigma[j + 1]) / (dsigma[i__] + dsigma[j + 1]);
+   22746             :         }
+   22747           0 :         d__2 =  std::sqrt(std::abs(z__[i__]));
+   22748           0 :         z__[i__] = (q[i__ + q_dim1] > 0) ? d__2 : -d__2;
+   22749             :     }
+   22750             : 
+   22751           0 :     i__1 = *k;
+   22752           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22753           0 :         vt[i__ * vt_dim1 + 1] = z__[1] / u[i__ * u_dim1 + 1] / vt[i__ * 
+   22754           0 :                 vt_dim1 + 1];
+   22755           0 :         u[i__ * u_dim1 + 1] = -1.;
+   22756           0 :         i__2 = *k;
+   22757           0 :         for (j = 2; j <= i__2; ++j) {
+   22758           0 :             vt[j + i__ * vt_dim1] = z__[j] / u[j + i__ * u_dim1] / vt[j + i__ 
+   22759           0 :                     * vt_dim1];
+   22760           0 :             u[j + i__ * u_dim1] = dsigma[j] * vt[j + i__ * vt_dim1];
+   22761             :         }
+   22762           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &u[i__ * u_dim1 + 1], &c__1);
+   22763           0 :         q[i__ * q_dim1 + 1] = u[i__ * u_dim1 + 1] / temp;
+   22764           0 :         i__2 = *k;
+   22765           0 :         for (j = 2; j <= i__2; ++j) {
+   22766           0 :             jc = idxc[j];
+   22767           0 :             q[j + i__ * q_dim1] = u[jc + i__ * u_dim1] / temp;
+   22768             :         }
+   22769             :     }
+   22770             : 
+   22771           0 :     if (*k == 2) {
+   22772           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &n, k, k, &one, &u2[u2_offset], ldu2, &q[q_offset],
+   22773             :                  ldq, &zero, &u[u_offset], ldu);
+   22774           0 :         goto L100;
+   22775             :     }
+   22776           0 :     if (ctot[1] > 0) {
+   22777           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[1], &one, &u2[(u2_dim1 << 1) + 1], 
+   22778           0 :                 ldu2, &q[q_dim1 + 2], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22779           0 :         if (ctot[3] > 0) {
+   22780           0 :             ktemp = ctot[1] + 2 + ctot[2];
+   22781           0 :             PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1]
+   22782           0 :                     , ldu2, &q[ktemp + q_dim1], ldq, &one, &u[u_dim1 + 1], 
+   22783             :                     ldu);
+   22784             :         }
+   22785           0 :     } else if (ctot[3] > 0) {
+   22786           0 :         ktemp = ctot[1] + 2 + ctot[2];
+   22787           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1], 
+   22788           0 :                 ldu2, &q[ktemp + q_dim1], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22789             :     } else {
+   22790           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", nl, k, &u2[u2_offset], ldu2, &u[u_offset], ldu);
+   22791             :     }
+   22792           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &q[q_dim1 + 1], ldq, &u[nlp1 + u_dim1], ldu);
+   22793           0 :     ktemp = ctot[1] + 2;
+   22794           0 :     ctemp = ctot[2] + ctot[3];
+   22795           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nr, k, &ctemp, &one, &u2[nlp2 + ktemp * u2_dim1], ldu2,
+   22796           0 :              &q[ktemp + q_dim1], ldq, &zero, &u[nlp2 + u_dim1], ldu);
+   22797             : 
+   22798           0 : L100:
+   22799           0 :     i__1 = *k;
+   22800           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22801           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &vt[i__ * vt_dim1 + 1], &c__1);
+   22802           0 :         q[i__ + q_dim1] = vt[i__ * vt_dim1 + 1] / temp;
+   22803           0 :         i__2 = *k;
+   22804           0 :         for (j = 2; j <= i__2; ++j) {
+   22805           0 :             jc = idxc[j];
+   22806           0 :             q[i__ + j * q_dim1] = vt[jc + i__ * vt_dim1] / temp;
+   22807             :         }
+   22808             :     }
+   22809             : 
+   22810           0 :     if (*k == 2) {
+   22811           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &m, k, &one, &q[q_offset], ldq, &vt2[vt2_offset]
+   22812             :                 , ldvt2, &zero, &vt[vt_offset], ldvt);
+   22813           0 :         return;
+   22814             :     }
+   22815           0 :     ktemp = ctot[1] + 1;
+   22816           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ktemp, &one, &q[q_dim1 + 1], ldq, &vt2[
+   22817           0 :             vt2_dim1 + 1], ldvt2, &zero, &vt[vt_dim1 + 1], ldvt);
+   22818           0 :     ktemp = ctot[1] + 2 + ctot[2];
+   22819           0 :     if (ktemp <= *ldvt2) {
+   22820           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ctot[3], &one, &q[ktemp * q_dim1 + 1], 
+   22821           0 :                 ldq, &vt2[ktemp + vt2_dim1], ldvt2, &one, &vt[vt_dim1 + 1], 
+   22822             :                 ldvt);
+   22823             :     }
+   22824             : 
+   22825           0 :     ktemp = ctot[1] + 1;
+   22826           0 :     nrp1 = *nr + *sqre;
+   22827           0 :     if (ktemp > 1) {
+   22828           0 :         i__1 = *k;
+   22829           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22830           0 :             q[i__ + ktemp * q_dim1] = q[i__ + q_dim1];
+   22831             :         }
+   22832           0 :         i__1 = m;
+   22833           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22834           0 :             vt2[ktemp + i__ * vt2_dim1] = vt2[i__ * vt2_dim1 + 1];
+   22835             :         }
+   22836             :     }
+   22837           0 :     ctemp = ctot[2] + 1 + ctot[3];
+   22838           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nrp1, &ctemp, &one, &q[ktemp * q_dim1 + 1], ldq, &
+   22839           0 :             vt2[ktemp + nlp2 * vt2_dim1], ldvt2, &zero, &vt[nlp2 * vt_dim1 + 
+   22840           0 :             1], ldvt);
+   22841             : 
+   22842             :     return;
+   22843             : 
+   22844             : 
+   22845             : }
+   22846             : 
+   22847             : 
+   22848             : }
+   22849             : }
+   22850             : #include <cmath>
+   22851             : #include "lapack.h"
+   22852             : #include "lapack_limits.h"
+   22853             : 
+   22854             : #include "real.h"
+   22855             : 
+   22856             : #include "blas/blas.h"
+   22857             : namespace PLMD{
+   22858             : namespace lapack{
+   22859             : using namespace blas;
+   22860             : void 
+   22861           0 : PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(int *n, 
+   22862             :         int *i__, 
+   22863             :         float *d__, 
+   22864             :         float *z__, 
+   22865             :         float *delta, 
+   22866             :         float *rho, 
+   22867             :         float *sigma, 
+   22868             :         float *work, 
+   22869             :         int *info)
+   22870             : {
+   22871             :     int i__1;
+   22872             :     float d__1;
+   22873             : 
+   22874             :     float a, b, c__;
+   22875             :     int j;
+   22876             :     float w, dd[3];
+   22877             :     int ii;
+   22878             :     float dw, zz[3];
+   22879             :     int ip1;
+   22880             :     float eta, phi, eps, tau, psi;
+   22881             :     int iim1, iip1;
+   22882             :     float dphi, dpsi;
+   22883             :     int iter;
+   22884             :     float temp, prew, sg2lb, sg2ub, temp1, temp2, dtiim, delsq, 
+   22885             :             dtiip;
+   22886             :     int niter;
+   22887             :     float dtisq;
+   22888             :     int swtch;
+   22889             :     float dtnsq;
+   22890             :     float delsq2, dtnsq1;
+   22891             :     int swtch3;
+   22892             :     int orgati;
+   22893             :     float erretm, dtipsq, rhoinv;
+   22894             : 
+   22895           0 :     --work;
+   22896           0 :     --delta;
+   22897           0 :     --z__;
+   22898           0 :     --d__;
+   22899             : 
+   22900           0 :     *info = 0;
+   22901           0 :     if (*n == 1) {
+   22902             : 
+   22903           0 :         *sigma =  std::sqrt(d__[1] * d__[1] + *rho * z__[1] * z__[1]);
+   22904           0 :         delta[1] = 1.;
+   22905           0 :         work[1] = 1.;
+   22906           0 :         return;
+   22907             :     }
+   22908           0 :     if (*n == 2) {
+   22909           0 :         PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(i__, &d__[1], &z__[1], &delta[1], rho, sigma, &work[1]);
+   22910           0 :         return;
+   22911             :     }
+   22912             : 
+   22913             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22914           0 :     rhoinv = 1. / *rho;
+   22915             : 
+   22916           0 :     if (*i__ == *n) {
+   22917             : 
+   22918           0 :         ii = *n - 1;
+   22919           0 :         niter = 1;
+   22920             : 
+   22921           0 :         temp = *rho / 2.;
+   22922             : 
+   22923           0 :         temp1 = temp / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + temp));
+   22924           0 :         i__1 = *n;
+   22925           0 :         for (j = 1; j <= i__1; ++j) {
+   22926           0 :             work[j] = d__[j] + d__[*n] + temp1;
+   22927           0 :             delta[j] = d__[j] - d__[*n] - temp1;
+   22928             :         }
+   22929             : 
+   22930             :         psi = 0.;
+   22931           0 :         i__1 = *n - 2;
+   22932           0 :         for (j = 1; j <= i__1; ++j) {
+   22933           0 :             psi += z__[j] * z__[j] / (delta[j] * work[j]);
+   22934             :         }
+   22935             : 
+   22936           0 :         c__ = rhoinv + psi;
+   22937           0 :         w = c__ + z__[ii] * z__[ii] / (delta[ii] * work[ii]) + z__[*n] * z__[*
+   22938           0 :                 n] / (delta[*n] * work[*n]);
+   22939             : 
+   22940           0 :         if (w <= 0.) {
+   22941           0 :             temp1 =  std::sqrt(d__[*n] * d__[*n] + *rho);
+   22942           0 :             temp = z__[*n - 1] * z__[*n - 1] / ((d__[*n - 1] + temp1) * (d__[*
+   22943           0 :                     n] - d__[*n - 1] + *rho / (d__[*n] + temp1))) + z__[*n] * 
+   22944           0 :                     z__[*n] / *rho;
+   22945             : 
+   22946           0 :             if (c__ <= temp) {
+   22947             :                 tau = *rho;
+   22948             :             } else {
+   22949           0 :                 delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22950           0 :                 a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*
+   22951             :                         n];
+   22952           0 :                 b = z__[*n] * z__[*n] * delsq;
+   22953           0 :                 if (a < 0.) {
+   22954           0 :                     tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22955             :                 } else {
+   22956           0 :                     tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22957             :                 }
+   22958             :             }
+   22959             : 
+   22960             :         } else {
+   22961           0 :             delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22962           0 :             a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n];
+   22963           0 :             b = z__[*n] * z__[*n] * delsq;
+   22964             : 
+   22965           0 :             if (a < 0.) {
+   22966           0 :                 tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22967             :             } else {
+   22968           0 :                 tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22969             :             }
+   22970             : 
+   22971             :         }
+   22972             : 
+   22973           0 :         eta = tau / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + tau));
+   22974             : 
+   22975           0 :         *sigma = d__[*n] + eta;
+   22976           0 :         i__1 = *n;
+   22977           0 :         for (j = 1; j <= i__1; ++j) {
+   22978           0 :             delta[j] = d__[j] - d__[*i__] - eta;
+   22979           0 :             work[j] = d__[j] + d__[*i__] + eta;
+   22980             :         }
+   22981             : 
+   22982             :         dpsi = 0.;
+   22983             :         psi = 0.;
+   22984             :         erretm = 0.;
+   22985             :         i__1 = ii;
+   22986           0 :         for (j = 1; j <= i__1; ++j) {
+   22987           0 :             temp = z__[j] / (delta[j] * work[j]);
+   22988           0 :             psi += z__[j] * temp;
+   22989           0 :             dpsi += temp * temp;
+   22990           0 :             erretm += psi;
+   22991             :         }
+   22992             :         erretm = std::abs(erretm);
+   22993             : 
+   22994           0 :         temp = z__[*n] / (delta[*n] * work[*n]);
+   22995           0 :         phi = z__[*n] * temp;
+   22996           0 :         dphi = temp * temp;
+   22997           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   22998           0 :                 + dphi);
+   22999             : 
+   23000           0 :         w = rhoinv + phi + psi;
+   23001             : 
+   23002           0 :         if (std::abs(w) <= eps * erretm) {
+   23003           0 :             goto L240;
+   23004             :         }
+   23005             : 
+   23006           0 :         ++niter;
+   23007           0 :         dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23008             :         dtnsq = work[*n] * delta[*n];
+   23009           0 :         c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23010           0 :         a = (dtnsq + dtnsq1) * w - dtnsq * dtnsq1 * (dpsi + dphi);
+   23011           0 :         b = dtnsq * dtnsq1 * w;
+   23012           0 :         if (c__ < 0.) {
+   23013           0 :             c__ = std::abs(c__);
+   23014             :         }
+   23015           0 :         if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23016           0 :             eta = *rho - *sigma * *sigma;
+   23017           0 :         } else if (a >= 0.) {
+   23018           0 :             eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__  * 2.);
+   23019             :         } else {
+   23020           0 :           eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23021             :         }
+   23022             : 
+   23023           0 :         if (w * eta > 0.) {
+   23024           0 :             eta = -w / (dpsi + dphi);
+   23025             :         }
+   23026           0 :         temp = eta - dtnsq;
+   23027           0 :         if (temp > *rho) {
+   23028           0 :             eta = *rho + dtnsq;
+   23029             :         }
+   23030             : 
+   23031           0 :         tau += eta;
+   23032           0 :         eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23033           0 :         i__1 = *n;
+   23034           0 :         for (j = 1; j <= i__1; ++j) {
+   23035           0 :             delta[j] -= eta;
+   23036           0 :             work[j] += eta;
+   23037             :         }
+   23038             : 
+   23039           0 :         *sigma += eta;
+   23040             : 
+   23041             :         dpsi = 0.;
+   23042             :         psi = 0.;
+   23043             :         erretm = 0.;
+   23044             :         i__1 = ii;
+   23045           0 :         for (j = 1; j <= i__1; ++j) {
+   23046           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23047           0 :             psi += z__[j] * temp;
+   23048           0 :             dpsi += temp * temp;
+   23049           0 :             erretm += psi;
+   23050             :         }
+   23051             :         erretm = std::abs(erretm);
+   23052             : 
+   23053           0 :         temp = z__[*n] / (work[*n] * delta[*n]);
+   23054           0 :         phi = z__[*n] * temp;
+   23055           0 :         dphi = temp * temp;
+   23056           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   23057           0 :                 + dphi);
+   23058             : 
+   23059           0 :         w = rhoinv + phi + psi;
+   23060             : 
+   23061             :         iter = niter + 1;
+   23062             : 
+   23063           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23064             : 
+   23065           0 :             if (std::abs(w) <= eps * erretm) {
+   23066           0 :                 goto L240;
+   23067             :             }
+   23068           0 :             dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23069           0 :             dtnsq = work[*n] * delta[*n];
+   23070           0 :             c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23071           0 :             a = (dtnsq + dtnsq1) * w - dtnsq1 * dtnsq * (dpsi + dphi);
+   23072           0 :             b = dtnsq1 * dtnsq * w;
+   23073           0 :             if (a >= 0.) {
+   23074           0 :                 eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23075             :             } else {
+   23076           0 :               eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23077             :             }
+   23078             : 
+   23079           0 :             if (w * eta > 0.) {
+   23080           0 :                 eta = -w / (dpsi + dphi);
+   23081             :             }
+   23082           0 :             temp = eta - dtnsq;
+   23083           0 :             if (temp <= 0.) {
+   23084           0 :                 eta /= 2.;
+   23085             :             }
+   23086             : 
+   23087           0 :             tau += eta;
+   23088           0 :             eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23089           0 :             i__1 = *n;
+   23090           0 :             for (j = 1; j <= i__1; ++j) {
+   23091           0 :                 delta[j] -= eta;
+   23092           0 :                 work[j] += eta;
+   23093             :             }
+   23094             : 
+   23095           0 :             *sigma += eta;
+   23096             : 
+   23097             :             dpsi = 0.;
+   23098             :             psi = 0.;
+   23099             :             erretm = 0.;
+   23100             :             i__1 = ii;
+   23101           0 :             for (j = 1; j <= i__1; ++j) {
+   23102           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23103           0 :                 psi += z__[j] * temp;
+   23104           0 :                 dpsi += temp * temp;
+   23105           0 :                 erretm += psi;
+   23106             :             }
+   23107             :             erretm = std::abs(erretm);
+   23108             : 
+   23109           0 :             temp = z__[*n] / (work[*n] * delta[*n]);
+   23110           0 :             phi = z__[*n] * temp;
+   23111           0 :             dphi = temp * temp;
+   23112           0 :             erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (
+   23113           0 :                     dpsi + dphi);
+   23114             : 
+   23115           0 :             w = rhoinv + phi + psi;
+   23116             :         }
+   23117             : 
+   23118           0 :         *info = 1;
+   23119           0 :         goto L240;
+   23120             : 
+   23121             :     } else {
+   23122             : 
+   23123           0 :         niter = 1;
+   23124           0 :         ip1 = *i__ + 1;
+   23125             : 
+   23126           0 :         delsq = (d__[ip1] - d__[*i__]) * (d__[ip1] + d__[*i__]);
+   23127           0 :         delsq2 = delsq / 2.;
+   23128           0 :         temp = delsq2 / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + delsq2));
+   23129           0 :         i__1 = *n;
+   23130           0 :         for (j = 1; j <= i__1; ++j) {
+   23131           0 :             work[j] = d__[j] + d__[*i__] + temp;
+   23132           0 :             delta[j] = d__[j] - d__[*i__] - temp;
+   23133             :         }
+   23134             : 
+   23135             :         psi = 0.;
+   23136           0 :         i__1 = *i__ - 1;
+   23137           0 :         for (j = 1; j <= i__1; ++j) {
+   23138           0 :             psi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23139             :         }
+   23140             : 
+   23141             :         phi = 0.;
+   23142           0 :         i__1 = *i__ + 2;
+   23143           0 :         for (j = *n; j >= i__1; --j) {
+   23144           0 :             phi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23145             :         }
+   23146           0 :         c__ = rhoinv + psi + phi;
+   23147           0 :         w = c__ + z__[*i__] * z__[*i__] / (work[*i__] * delta[*i__]) + z__[
+   23148           0 :                 ip1] * z__[ip1] / (work[ip1] * delta[ip1]);
+   23149             : 
+   23150           0 :         if (w > 0.) {
+   23151             : 
+   23152           0 :             orgati = 1;
+   23153             :             sg2lb = 0.;
+   23154             :             sg2ub = delsq2;
+   23155           0 :             a = c__ * delsq + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1];
+   23156           0 :             b = z__[*i__] * z__[*i__] * delsq;
+   23157           0 :             if (a > 0.) {
+   23158           0 :                 tau = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23159             :             } else {
+   23160           0 :                 tau = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23161             :             }
+   23162           0 :             eta = tau / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + tau));
+   23163             :         } else {
+   23164             : 
+   23165           0 :             orgati = 0;
+   23166           0 :             sg2lb = -delsq2;
+   23167             :             sg2ub = 0.;
+   23168           0 :             a = c__ * delsq - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1];
+   23169           0 :             b = z__[ip1] * z__[ip1] * delsq;
+   23170           0 :             if (a < 0.) {
+   23171           0 :                 tau = b * 2. / (a -  std::sqrt(std::abs(a * a + b * 4. * c__)));
+   23172             :             } else {
+   23173           0 :                 tau = -(a +  std::sqrt(std::abs(a * a + b * 4. * c__))) /       (c__ * 2.);
+   23174             :             }
+   23175           0 :             eta = tau / (d__[ip1] +  std::sqrt(std::abs(d__[ip1] * d__[ip1] + tau)));
+   23176             :         }
+   23177             : 
+   23178           0 :         if (orgati) {
+   23179           0 :             ii = *i__;
+   23180           0 :             *sigma = d__[*i__] + eta;
+   23181           0 :             i__1 = *n;
+   23182           0 :             for (j = 1; j <= i__1; ++j) {
+   23183           0 :                 work[j] = d__[j] + d__[*i__] + eta;
+   23184           0 :                 delta[j] = d__[j] - d__[*i__] - eta;
+   23185             :             }
+   23186             :         } else {
+   23187           0 :             ii = *i__ + 1;
+   23188           0 :             *sigma = d__[ip1] + eta;
+   23189           0 :             i__1 = *n;
+   23190           0 :             for (j = 1; j <= i__1; ++j) {
+   23191           0 :                 work[j] = d__[j] + d__[ip1] + eta;
+   23192           0 :                 delta[j] = d__[j] - d__[ip1] - eta;
+   23193             :             }
+   23194             :         }
+   23195           0 :         iim1 = ii - 1;
+   23196           0 :         iip1 = ii + 1;
+   23197             : 
+   23198             :         dpsi = 0.;
+   23199             :         psi = 0.;
+   23200             :         erretm = 0.;
+   23201             :         i__1 = iim1;
+   23202           0 :         for (j = 1; j <= i__1; ++j) {
+   23203           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23204           0 :             psi += z__[j] * temp;
+   23205           0 :             dpsi += temp * temp;
+   23206           0 :             erretm += psi;
+   23207             :         }
+   23208             :         erretm = std::abs(erretm);
+   23209             : 
+   23210             :         dphi = 0.;
+   23211             :         phi = 0.;
+   23212             :         i__1 = iip1;
+   23213           0 :         for (j = *n; j >= i__1; --j) {
+   23214           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23215           0 :             phi += z__[j] * temp;
+   23216           0 :             dphi += temp * temp;
+   23217           0 :             erretm += phi;
+   23218             :         }
+   23219             : 
+   23220           0 :         w = rhoinv + phi + psi;
+   23221             : 
+   23222             :         swtch3 = 0;
+   23223           0 :         if (orgati) {
+   23224           0 :             if (w < 0.) {
+   23225             :                 swtch3 = 1;
+   23226             :             }
+   23227             :         } else {
+   23228           0 :             if (w > 0.) {
+   23229             :                 swtch3 = 1;
+   23230             :             }
+   23231             :         }
+   23232           0 :         if (ii == 1 || ii == *n) {
+   23233             :             swtch3 = 0;
+   23234             :         }
+   23235             : 
+   23236           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23237           0 :         dw = dpsi + dphi + temp * temp;
+   23238           0 :         temp = z__[ii] * temp;
+   23239           0 :         w += temp;
+   23240           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23241           0 :                 std::abs(tau) * dw;
+   23242             : 
+   23243           0 :         if (std::abs(w) <= eps * erretm) {
+   23244           0 :             goto L240;
+   23245             :         }
+   23246             : 
+   23247           0 :         if (w <= 0.) {
+   23248           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23249             :         } else {
+   23250           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23251             :         }
+   23252             : 
+   23253           0 :         ++niter;
+   23254           0 :         if (! swtch3) {
+   23255           0 :             dtipsq = work[ip1] * delta[ip1];
+   23256           0 :             dtisq = work[*i__] * delta[*i__];
+   23257           0 :             if (orgati) {
+   23258           0 :                 d__1 = z__[*i__] / dtisq;
+   23259           0 :                 c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23260             :             } else {
+   23261           0 :                 d__1 = z__[ip1] / dtipsq;
+   23262           0 :                 c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23263             :             }
+   23264           0 :             a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23265           0 :             b = dtipsq * dtisq * w;
+   23266           0 :             if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23267           0 :                 if ( std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23268           0 :                     if (orgati) {
+   23269           0 :                         a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * (dpsi + 
+   23270             :                                 dphi);
+   23271             :                     } else {
+   23272           0 :                         a = z__[ip1] * z__[ip1] + dtisq * dtisq * (dpsi + 
+   23273             :                                 dphi);
+   23274             :                     }
+   23275             :                 }
+   23276           0 :                 eta = b / a;
+   23277           0 :             } else if (a <= 0.) {
+   23278           0 :                 eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23279             :             } else {
+   23280           0 :                 eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23281             :             }
+   23282             :         } else {
+   23283             : 
+   23284           0 :             dtiim = work[iim1] * delta[iim1];
+   23285           0 :             dtiip = work[iip1] * delta[iip1];
+   23286           0 :             temp = rhoinv + psi + phi;
+   23287           0 :             if (orgati) {
+   23288           0 :                 temp1 = z__[iim1] / dtiim;
+   23289           0 :                 temp1 *= temp1;
+   23290           0 :                 c__ = temp - dtiip * (dpsi + dphi) - (d__[iim1] - d__[iip1]) *
+   23291           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23292           0 :                 zz[0] = z__[iim1] * z__[iim1];
+   23293           0 :                 if (dpsi < temp1) {
+   23294           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23295             :                 } else {
+   23296           0 :                     zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23297             :                 }
+   23298             :             } else {
+   23299           0 :                 temp1 = z__[iip1] / dtiip;
+   23300           0 :                 temp1 *= temp1;
+   23301           0 :                 c__ = temp - dtiim * (dpsi + dphi) - (d__[iip1] - d__[iim1]) *
+   23302           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23303           0 :                 if (dphi < temp1) {
+   23304           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23305             :                 } else {
+   23306           0 :                     zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23307             :                 }
+   23308           0 :                 zz[2] = z__[iip1] * z__[iip1];
+   23309             :             }
+   23310           0 :             zz[1] = z__[ii] * z__[ii];
+   23311           0 :             dd[0] = dtiim;
+   23312           0 :             dd[1] = delta[ii] * work[ii];
+   23313           0 :             dd[2] = dtiip;
+   23314           0 :             PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23315           0 :             if (*info != 0) {
+   23316           0 :                 goto L240;
+   23317             :             }
+   23318             :         }
+   23319             : 
+   23320           0 :         if (w * eta >= 0.) {
+   23321           0 :             eta = -w / dw;
+   23322             :         }
+   23323           0 :         if (orgati) {
+   23324           0 :             temp1 = work[*i__] * delta[*i__];
+   23325           0 :             temp = eta - temp1;
+   23326             :         } else {
+   23327           0 :             temp1 = work[ip1] * delta[ip1];
+   23328           0 :             temp = eta - temp1;
+   23329             :         }
+   23330           0 :         if (temp > sg2ub || temp < sg2lb) {
+   23331           0 :             if (w < 0.) {
+   23332           0 :                 eta = (sg2ub - tau) / 2.;
+   23333             :             } else {
+   23334           0 :                 eta = (sg2lb - tau) / 2.;
+   23335             :             }
+   23336             :         }
+   23337             : 
+   23338           0 :         tau += eta;
+   23339           0 :         eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23340             : 
+   23341             :         prew = w;
+   23342             : 
+   23343           0 :         *sigma += eta;
+   23344           0 :         i__1 = *n;
+   23345           0 :         for (j = 1; j <= i__1; ++j) {
+   23346           0 :             work[j] += eta;
+   23347           0 :             delta[j] -= eta;
+   23348             :         }
+   23349             : 
+   23350             :         dpsi = 0.;
+   23351             :         psi = 0.;
+   23352             :         erretm = 0.;
+   23353             :         i__1 = iim1;
+   23354           0 :         for (j = 1; j <= i__1; ++j) {
+   23355           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23356           0 :             psi += z__[j] * temp;
+   23357           0 :             dpsi += temp * temp;
+   23358           0 :             erretm += psi;
+   23359             :         }
+   23360             :         erretm = std::abs(erretm);
+   23361             : 
+   23362             :         dphi = 0.;
+   23363             :         phi = 0.;
+   23364             :         i__1 = iip1;
+   23365           0 :         for (j = *n; j >= i__1; --j) {
+   23366           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23367           0 :             phi += z__[j] * temp;
+   23368           0 :             dphi += temp * temp;
+   23369           0 :             erretm += phi;
+   23370             :         }
+   23371             : 
+   23372           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23373           0 :         dw = dpsi + dphi + temp * temp;
+   23374           0 :         temp = z__[ii] * temp;
+   23375           0 :         w = rhoinv + phi + psi + temp;
+   23376           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23377           0 :                 std::abs(tau) * dw;
+   23378             : 
+   23379           0 :         if (w <= 0.) {
+   23380           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23381             :         } else {
+   23382           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23383             :         }
+   23384             : 
+   23385             :         swtch = 0;
+   23386           0 :         if (orgati) {
+   23387           0 :             if (-w > std::abs(prew) / 10.) {
+   23388             :                 swtch = 1;
+   23389             :             }
+   23390             :         } else {
+   23391           0 :             if (w > std::abs(prew) / 10.) {
+   23392             :                 swtch = 1;
+   23393             :             }
+   23394             :         }
+   23395             : 
+   23396           0 :         iter = niter + 1;
+   23397             : 
+   23398           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23399             : 
+   23400           0 :             if (std::abs(w) <= eps * erretm) {
+   23401           0 :                 goto L240;
+   23402             :             }
+   23403             : 
+   23404           0 :             if (! swtch3) {
+   23405           0 :                 dtipsq = work[ip1] * delta[ip1];
+   23406           0 :                 dtisq = work[*i__] * delta[*i__];
+   23407           0 :                 if (! swtch) {
+   23408           0 :                     if (orgati) {
+   23409           0 :                         d__1 = z__[*i__] / dtisq;
+   23410           0 :                         c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23411             :                     } else {
+   23412           0 :                         d__1 = z__[ip1] / dtipsq;
+   23413           0 :                         c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23414             :                     }
+   23415             :                 } else {
+   23416           0 :                     temp = z__[ii] / (work[ii] * delta[ii]);
+   23417           0 :                     if (orgati) {
+   23418           0 :                         dpsi += temp * temp;
+   23419             :                     } else {
+   23420           0 :                         dphi += temp * temp;
+   23421             :                     }
+   23422           0 :                     c__ = w - dtisq * dpsi - dtipsq * dphi;
+   23423             :                 }
+   23424           0 :                 a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23425           0 :                 b = dtipsq * dtisq * w;
+   23426           0 :                 if (std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23427           0 :                     if (std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23428           0 :                         if (! swtch) {
+   23429           0 :                             if (orgati) {
+   23430           0 :                                 a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * 
+   23431           0 :                                         (dpsi + dphi);
+   23432             :                             } else {
+   23433           0 :                                 a = z__[ip1] * z__[ip1] + dtisq * dtisq * (
+   23434           0 :                                         dpsi + dphi);
+   23435             :                             }
+   23436             :                         } else {
+   23437           0 :                             a = dtisq * dtisq * dpsi + dtipsq * dtipsq * dphi;
+   23438             :                         }
+   23439             :                     }
+   23440           0 :                     eta = b / a;
+   23441           0 :                 } else if (a <= 0.) {
+   23442           0 :                   eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23443             :                 } else {
+   23444           0 :                   eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23445             :                 }
+   23446             :             } else {
+   23447             : 
+   23448           0 :                 dtiim = work[iim1] * delta[iim1];
+   23449           0 :                 dtiip = work[iip1] * delta[iip1];
+   23450           0 :                 temp = rhoinv + psi + phi;
+   23451           0 :                 if (swtch) {
+   23452           0 :                     c__ = temp - dtiim * dpsi - dtiip * dphi;
+   23453           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23454           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23455             :                 } else {
+   23456           0 :                     if (orgati) {
+   23457           0 :                         temp1 = z__[iim1] / dtiim;
+   23458           0 :                         temp1 *= temp1;
+   23459           0 :                         temp2 = (d__[iim1] - d__[iip1]) * (d__[iim1] + d__[
+   23460             :                                 iip1]) * temp1;
+   23461           0 :                         c__ = temp - dtiip * (dpsi + dphi) - temp2;
+   23462           0 :                         zz[0] = z__[iim1] * z__[iim1];
+   23463           0 :                         if (dpsi < temp1) {
+   23464           0 :                             zz[2] = dtiip * dtiip * dphi;
+   23465             :                         } else {
+   23466           0 :                             zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23467             :                         }
+   23468             :                     } else {
+   23469           0 :                         temp1 = z__[iip1] / dtiip;
+   23470           0 :                         temp1 *= temp1;
+   23471           0 :                         temp2 = (d__[iip1] - d__[iim1]) * (d__[iim1] + d__[
+   23472             :                                 iip1]) * temp1;
+   23473           0 :                         c__ = temp - dtiim * (dpsi + dphi) - temp2;
+   23474           0 :                         if (dphi < temp1) {
+   23475           0 :                             zz[0] = dtiim * dtiim * dpsi;
+   23476             :                         } else {
+   23477           0 :                             zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23478             :                         }
+   23479           0 :                         zz[2] = z__[iip1] * z__[iip1];
+   23480             :                     }
+   23481             :                 }
+   23482           0 :                 dd[0] = dtiim;
+   23483           0 :                 dd[1] = delta[ii] * work[ii];
+   23484           0 :                 dd[2] = dtiip;
+   23485           0 :                 PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23486           0 :                 if (*info != 0) {
+   23487           0 :                     goto L240;
+   23488             :                 }
+   23489             :             }
+   23490             : 
+   23491           0 :             if (w * eta >= 0.) {
+   23492           0 :                 eta = -w / dw;
+   23493             :             }
+   23494           0 :             if (orgati) {
+   23495           0 :                 temp1 = work[*i__] * delta[*i__];
+   23496           0 :                 temp = eta - temp1;
+   23497             :             } else {
+   23498           0 :                 temp1 = work[ip1] * delta[ip1];
+   23499           0 :                 temp = eta - temp1;
+   23500             :             }
+   23501           0 :             if (temp > sg2ub || temp < sg2lb) {
+   23502           0 :                 if (w < 0.) {
+   23503           0 :                     eta = (sg2ub - tau) / 2.;
+   23504             :                 } else {
+   23505           0 :                     eta = (sg2lb - tau) / 2.;
+   23506             :                 }
+   23507             :             }
+   23508             : 
+   23509           0 :             tau += eta;
+   23510           0 :             eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23511             : 
+   23512           0 :             *sigma += eta;
+   23513           0 :             i__1 = *n;
+   23514           0 :             for (j = 1; j <= i__1; ++j) {
+   23515           0 :                 work[j] += eta;
+   23516           0 :                 delta[j] -= eta;
+   23517             :             }
+   23518             : 
+   23519             :             prew = w;
+   23520             : 
+   23521             :             dpsi = 0.;
+   23522             :             psi = 0.;
+   23523             :             erretm = 0.;
+   23524             :             i__1 = iim1;
+   23525           0 :             for (j = 1; j <= i__1; ++j) {
+   23526           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23527           0 :                 psi += z__[j] * temp;
+   23528           0 :                 dpsi += temp * temp;
+   23529           0 :                 erretm += psi;
+   23530             :             }
+   23531             :             erretm = std::abs(erretm);
+   23532             : 
+   23533             :             dphi = 0.;
+   23534             :             phi = 0.;
+   23535             :             i__1 = iip1;
+   23536           0 :             for (j = *n; j >= i__1; --j) {
+   23537           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23538           0 :                 phi += z__[j] * temp;
+   23539           0 :                 dphi += temp * temp;
+   23540           0 :                 erretm += phi;
+   23541             :             }
+   23542             : 
+   23543           0 :             temp = z__[ii] / (work[ii] * delta[ii]);
+   23544           0 :             dw = dpsi + dphi + temp * temp;
+   23545           0 :             temp = z__[ii] * temp;
+   23546           0 :             w = rhoinv + phi + psi + temp;
+   23547           0 :             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. 
+   23548           0 :                     + std::abs(tau) * dw;
+   23549           0 :             if (w * prew > 0. && std::abs(w) > std::abs(prew) / 10.) {
+   23550           0 :                 swtch = ! swtch;
+   23551             :             }
+   23552             : 
+   23553           0 :             if (w <= 0.) {
+   23554           0 :                 sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23555             :             } else {
+   23556           0 :                 sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23557             :             }
+   23558             :         }
+   23559             : 
+   23560           0 :         *info = 1;
+   23561             : 
+   23562             :     }
+   23563             : 
+   23564           0 : L240:
+   23565             :     return;
+   23566             : 
+   23567             : } 
+   23568             : }
+   23569             : }
+   23570             : #include <cmath>
+   23571             : #include "lapack.h"
+   23572             : 
+   23573             : #include "blas/blas.h"
+   23574             : namespace PLMD{
+   23575             : namespace lapack{
+   23576             : using namespace blas;
+   23577             : void 
+   23578           0 : PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(int *i__, 
+   23579             :         float *d__, 
+   23580             :         float *z__, 
+   23581             :         float *delta, 
+   23582             :         float *rho, 
+   23583             :         float *dsigma, 
+   23584             :         float *work)
+   23585             : {
+   23586             :     float b, c__, w, del, tau, delsq;
+   23587             : 
+   23588             :     --work;
+   23589             :     --delta;
+   23590             :     --z__;
+   23591             :     --d__;
+   23592             : 
+   23593           0 :     del = d__[2] - d__[1];
+   23594           0 :     delsq = del * (d__[2] + d__[1]);
+   23595           0 :     if (*i__ == 1) {
+   23596           0 :         w = *rho * 4. * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.) - z__[1] * 
+   23597           0 :                 z__[1] / (d__[1] * 3. + d__[2])) / del + 1.;
+   23598           0 :         if (w > 0.) {
+   23599           0 :             b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23600           0 :             c__ = *rho * z__[1] * z__[1] * delsq;
+   23601             : 
+   23602           0 :             tau = c__ * 2. / (b +  std::sqrt(std::abs(b * b - c__ * 4.)));
+   23603             : 
+   23604           0 :             tau /= d__[1] +  std::sqrt(d__[1] * d__[1] + tau);
+   23605           0 :             *dsigma = d__[1] + tau;
+   23606           0 :             delta[1] = -tau;
+   23607           0 :             delta[2] = del - tau;
+   23608           0 :             work[1] = d__[1] * 2. + tau;
+   23609           0 :             work[2] = d__[1] + tau + d__[2];
+   23610             :         } else {
+   23611           0 :             b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23612           0 :             c__ = *rho * z__[2] * z__[2] * delsq;
+   23613             : 
+   23614           0 :             if (b > 0.) {
+   23615           0 :                 tau = c__ * -2. / (b +  std::sqrt(b * b + c__ * 4.));
+   23616             :             } else {
+   23617           0 :                 tau = (b -  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23618             :             }
+   23619             : 
+   23620           0 :             tau /= d__[2] +  std::sqrt(std::abs(d__[2] * d__[2] + tau));
+   23621           0 :             *dsigma = d__[2] + tau;
+   23622           0 :             delta[1] = -(del + tau);
+   23623           0 :             delta[2] = -tau;
+   23624           0 :             work[1] = d__[1] + tau + d__[2];
+   23625           0 :             work[2] = d__[2] * 2. + tau;
+   23626             :         }
+   23627             :     } else {
+   23628             : 
+   23629           0 :         b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23630           0 :         c__ = *rho * z__[2] * z__[2] * delsq;
+   23631             : 
+   23632           0 :         if (b > 0.) {
+   23633           0 :             tau = (b +  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23634             :         } else {
+   23635           0 :             tau = c__ * 2. / (-b +  std::sqrt(b * b + c__ * 4.));
+   23636             :         }
+   23637           0 :         tau /= d__[2] +  std::sqrt(d__[2] * d__[2] + tau);
+   23638           0 :         *dsigma = d__[2] + tau;
+   23639           0 :         delta[1] = -(del + tau);
+   23640           0 :         delta[2] = -tau;
+   23641           0 :         work[1] = d__[1] + tau + d__[2];
+   23642           0 :         work[2] = d__[2] * 2. + tau;
+   23643             :     }
+   23644           0 :     return;
+   23645             : 
+   23646             : } 
+   23647             : }
+   23648             : }
+   23649             : #include <cmath>
+   23650             : #include "blas/blas.h"
+   23651             : #include "lapack.h"
+   23652             : 
+   23653             : #include "blas/blas.h"
+   23654             : namespace PLMD{
+   23655             : namespace lapack{
+   23656             : using namespace blas;
+   23657             : void 
+   23658           0 : PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(int *icompq, 
+   23659             :         int *nl, 
+   23660             :         int *nr, 
+   23661             :         int *sqre, 
+   23662             :         float *d__, 
+   23663             :         float *vf, 
+   23664             :         float *vl, 
+   23665             :         float *alpha, 
+   23666             :         float *beta, 
+   23667             :         int *idxq, 
+   23668             :         int *perm, 
+   23669             :         int *givptr, 
+   23670             :         int *givcol, 
+   23671             :         int *ldgcol, 
+   23672             :         float *givnum,
+   23673             :         int *ldgnum, 
+   23674             :         float *poles, 
+   23675             :         float *difl, 
+   23676             :         float *difr, 
+   23677             :         float *z__, 
+   23678             :         int *k, 
+   23679             :         float *c__, 
+   23680             :         float *s, 
+   23681             :         float *work, 
+   23682             :         int *iwork, 
+   23683             :         int *info)
+   23684             : {
+   23685             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, 
+   23686             :             poles_dim1, poles_offset, i__1;
+   23687             :     float d__1, d__2;
+   23688             : 
+   23689             :     int i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw;
+   23690             :     int isigma;
+   23691             :     float orgnrm;
+   23692           0 :     int c__0 = 0;
+   23693           0 :     float one = 1.0;
+   23694           0 :     int c__1 = 1;
+   23695           0 :     int c_n1 = -1;
+   23696             : 
+   23697           0 :     --d__;
+   23698             :     --vf;
+   23699             :     --vl;
+   23700             :     --idxq;
+   23701             :     --perm;
+   23702             :     givcol_dim1 = *ldgcol;
+   23703             :     givcol_offset = 1 + givcol_dim1;
+   23704             :     givcol -= givcol_offset;
+   23705           0 :     poles_dim1 = *ldgnum;
+   23706           0 :     poles_offset = 1 + poles_dim1;
+   23707           0 :     poles -= poles_offset;
+   23708             :     givnum_dim1 = *ldgnum;
+   23709             :     givnum_offset = 1 + givnum_dim1;
+   23710             :     givnum -= givnum_offset;
+   23711             :     --difl;
+   23712             :     --difr;
+   23713             :     --z__;
+   23714           0 :     --work;
+   23715             :     --iwork;
+   23716             : 
+   23717           0 :     *info = 0;
+   23718           0 :     n = *nl + *nr + 1;
+   23719           0 :     m = n + *sqre;
+   23720             : 
+   23721             :     isigma = 1;
+   23722           0 :     iw = isigma + n;
+   23723           0 :     ivfw = iw + m;
+   23724           0 :     ivlw = ivfw + m;
+   23725             : 
+   23726             :     idx = 1;
+   23727             :     idxc = idx + n;
+   23728           0 :     idxp = idxc + n;
+   23729             : 
+   23730           0 :     d__1 = std::abs(*alpha); 
+   23731           0 :     d__2 = std::abs(*beta);
+   23732           0 :     orgnrm = (d__1 > d__2) ? d__1 : d__2;
+   23733           0 :     d__[*nl + 1] = 0.;
+   23734             :     i__1 = n;
+   23735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   23736           0 :       d__1 = std::abs(d__[i__]);
+   23737           0 :         if (d__1 > orgnrm)
+   23738           0 :             orgnrm = d__1;
+   23739             :     }
+   23740           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   23741           0 :     *alpha /= orgnrm;
+   23742           0 :     *beta /= orgnrm;
+   23743             : 
+   23744           0 :     PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], &
+   23745           0 :             work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], &
+   23746           0 :             iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[
+   23747             :             givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s, 
+   23748             :             info);
+   23749             : 
+   23750           0 :     PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1], 
+   23751             :             ldgnum, &work[isigma], &work[iw], info);
+   23752             : 
+   23753           0 :     if (*icompq == 1) {
+   23754           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1);
+   23755           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1);
+   23756             :     }
+   23757             : 
+   23758           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   23759             : 
+   23760           0 :     n1 = *k;
+   23761           0 :     n2 = n - *k;
+   23762           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   23763             : 
+   23764           0 :     return;
+   23765             : 
+   23766             : }
+   23767             : 
+   23768             : 
+   23769             : }
+   23770             : }
+   23771             : #include <cmath>
+   23772             : #include "real.h"
+   23773             : 
+   23774             : #include "blas/blas.h"
+   23775             : #include "lapack.h"
+   23776             : #include "lapack_limits.h"
+   23777             : 
+   23778             : #include "blas/blas.h"
+   23779             : namespace PLMD{
+   23780             : namespace lapack{
+   23781             : using namespace blas;
+   23782             : void 
+   23783           0 : PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(int *icompq, 
+   23784             :         int *nl, 
+   23785             :         int *nr, 
+   23786             :         int *sqre, 
+   23787             :         int *k, 
+   23788             :         float *d__, 
+   23789             :         float *z__, 
+   23790             :         float *zw, 
+   23791             :         float *vf, 
+   23792             :         float *vfw,
+   23793             :         float *vl, 
+   23794             :         float *vlw,
+   23795             :         float *alpha, 
+   23796             :         float *beta,
+   23797             :         float *dsigma, 
+   23798             :         int *idx, 
+   23799             :         int *idxp,
+   23800             :         int *idxq, 
+   23801             :         int *perm, 
+   23802             :         int *givptr,
+   23803             :         int *givcol, 
+   23804             :         int *ldgcol, 
+   23805             :         float *givnum,
+   23806             :         int *ldgnum, 
+   23807             :         float *c__, 
+   23808             :         float *s, 
+   23809             :         int *info)
+   23810             : {
+   23811             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, i__1;
+   23812             :     float d__1, d__2;
+   23813             : 
+   23814             :     int i__, j, m, n, k2;
+   23815             :     float z1;
+   23816             :     int jp;
+   23817             :     float eps, tau, tol;
+   23818             :     int nlp1, nlp2, idxi, idxj;
+   23819             :     int idxjp;
+   23820             :     int jprev = 0;
+   23821             :     float hlftol;
+   23822           0 :     int c__1 = 1;
+   23823             : 
+   23824           0 :     --d__;
+   23825           0 :     --z__;
+   23826           0 :     --zw;
+   23827           0 :     --vf;
+   23828           0 :     --vfw;
+   23829           0 :     --vl;
+   23830           0 :     --vlw;
+   23831           0 :     --dsigma;
+   23832           0 :     --idx;
+   23833           0 :     --idxp;
+   23834           0 :     --idxq;
+   23835           0 :     --perm;
+   23836           0 :     givcol_dim1 = *ldgcol;
+   23837           0 :     givcol_offset = 1 + givcol_dim1;
+   23838           0 :     givcol -= givcol_offset;
+   23839           0 :     givnum_dim1 = *ldgnum;
+   23840           0 :     givnum_offset = 1 + givnum_dim1;
+   23841           0 :     givnum -= givnum_offset;
+   23842             : 
+   23843           0 :     *info = 0;
+   23844           0 :     n = *nl + *nr + 1;
+   23845           0 :     m = n + *sqre;
+   23846             : 
+   23847           0 :     nlp1 = *nl + 1;
+   23848           0 :     nlp2 = *nl + 2;
+   23849           0 :     if (*icompq == 1) {
+   23850           0 :         *givptr = 0;
+   23851             :     }
+   23852             : 
+   23853           0 :     z1 = *alpha * vl[nlp1];
+   23854           0 :     vl[nlp1] = 0.;
+   23855           0 :     tau = vf[nlp1];
+   23856           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   23857           0 :         z__[i__ + 1] = *alpha * vl[i__];
+   23858           0 :         vl[i__] = 0.;
+   23859           0 :         vf[i__ + 1] = vf[i__];
+   23860           0 :         d__[i__ + 1] = d__[i__];
+   23861           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   23862             :     }
+   23863           0 :     vf[1] = tau;
+   23864             : 
+   23865             :     i__1 = m;
+   23866           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23867           0 :         z__[i__] = *beta * vf[i__];
+   23868           0 :         vf[i__] = 0.;
+   23869             :     }
+   23870           0 :     i__1 = n;
+   23871           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23872           0 :         idxq[i__] += nlp1;
+   23873             :     }
+   23874             : 
+   23875             :     i__1 = n;
+   23876           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23877           0 :         dsigma[i__] = d__[idxq[i__]];
+   23878           0 :         zw[i__] = z__[idxq[i__]];
+   23879           0 :         vfw[i__] = vf[idxq[i__]];
+   23880           0 :         vlw[i__] = vl[idxq[i__]];
+   23881             :     }
+   23882             : 
+   23883           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   23884             : 
+   23885           0 :     i__1 = n;
+   23886           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23887           0 :         idxi = idx[i__] + 1;
+   23888           0 :         d__[i__] = dsigma[idxi];
+   23889           0 :         z__[i__] = zw[idxi];
+   23890           0 :         vf[i__] = vfw[idxi];
+   23891           0 :         vl[i__] = vlw[idxi];
+   23892             :     }
+   23893             : 
+   23894             :     eps = PLUMED_GMX_FLOAT_EPS;
+   23895             : 
+   23896           0 :     d__1 = std::abs(*alpha);
+   23897           0 :     d__2 = std::abs(*beta);
+   23898           0 :     tol = (d__1>d__2) ? d__1 : d__2;
+   23899           0 :     d__2 = std::abs(d__[n]);
+   23900           0 :     tol = eps * 64. * ((d__2>tol) ? d__2 : tol);
+   23901             : 
+   23902           0 :     *k = 1;
+   23903           0 :     k2 = n + 1;
+   23904             :     i__1 = n;
+   23905           0 :     for (j = 2; j <= i__1; ++j) {
+   23906           0 :         if (std::abs(z__[j]) <= tol) {
+   23907             : 
+   23908           0 :             --k2;
+   23909           0 :             idxp[k2] = j;
+   23910           0 :             if (j == n) {
+   23911           0 :                 goto L100;
+   23912             :             }
+   23913             :         } else {
+   23914             :             jprev = j;
+   23915           0 :             goto L70;
+   23916             :         }
+   23917             :     }
+   23918           0 : L70:
+   23919             :     j = jprev;
+   23920           0 : L80:
+   23921           0 :     ++j;
+   23922           0 :     if (j > n) {
+   23923           0 :         goto L90;
+   23924             :     }
+   23925           0 :     if (std::abs(z__[j]) <= tol) {
+   23926             : 
+   23927           0 :         --k2;
+   23928           0 :         idxp[k2] = j;
+   23929             :     } else {
+   23930             : 
+   23931           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   23932             : 
+   23933           0 :             *s = z__[jprev];
+   23934           0 :             *c__ = z__[j];
+   23935             : 
+   23936           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(c__, s);
+   23937           0 :             z__[j] = tau;
+   23938           0 :             z__[jprev] = 0.;
+   23939           0 :             *c__ /= tau;
+   23940           0 :             *s = -(*s) / tau;
+   23941             : 
+   23942             : 
+   23943           0 :             if (*icompq == 1) {
+   23944           0 :                 ++(*givptr);
+   23945           0 :                 idxjp = idxq[idx[jprev] + 1];
+   23946           0 :                 idxj = idxq[idx[j] + 1];
+   23947           0 :                 if (idxjp <= nlp1) {
+   23948           0 :                     --idxjp;
+   23949             :                 }
+   23950           0 :                 if (idxj <= nlp1) {
+   23951           0 :                     --idxj;
+   23952             :                 }
+   23953           0 :                 givcol[*givptr + (givcol_dim1 << 1)] = idxjp;
+   23954           0 :                 givcol[*givptr + givcol_dim1] = idxj;
+   23955           0 :                 givnum[*givptr + (givnum_dim1 << 1)] = *c__;
+   23956           0 :                 givnum[*givptr + givnum_dim1] = *s;
+   23957             :             }
+   23958           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[jprev], &c__1, &vf[j], &c__1, c__, s);
+   23959           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[jprev], &c__1, &vl[j], &c__1, c__, s);
+   23960           0 :             --k2;
+   23961           0 :             idxp[k2] = jprev;
+   23962             :             jprev = j;
+   23963             :         } else {
+   23964           0 :             ++(*k);
+   23965           0 :             zw[*k] = z__[jprev];
+   23966           0 :             dsigma[*k] = d__[jprev];
+   23967           0 :             idxp[*k] = jprev;
+   23968             :             jprev = j;
+   23969             :         }
+   23970             :     }
+   23971           0 :     goto L80;
+   23972             : L90:
+   23973             : 
+   23974           0 :     ++(*k);
+   23975           0 :     zw[*k] = z__[jprev];
+   23976           0 :     dsigma[*k] = d__[jprev];
+   23977           0 :     idxp[*k] = jprev;
+   23978             : 
+   23979           0 : L100:
+   23980             : 
+   23981           0 :     i__1 = n;
+   23982           0 :     for (j = 2; j <= i__1; ++j) {
+   23983           0 :         jp = idxp[j];
+   23984           0 :         dsigma[j] = d__[jp];
+   23985           0 :         vfw[j] = vf[jp];
+   23986           0 :         vlw[j] = vl[jp];
+   23987             :     }
+   23988           0 :     if (*icompq == 1) {
+   23989             :         i__1 = n;
+   23990           0 :         for (j = 2; j <= i__1; ++j) {
+   23991           0 :             jp = idxp[j];
+   23992           0 :             perm[j] = idxq[idx[jp] + 1];
+   23993           0 :             if (perm[j] <= nlp1) {
+   23994           0 :                 --perm[j];
+   23995             :             }
+   23996             :         }
+   23997             :     }
+   23998           0 :     i__1 = n - *k;
+   23999           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   24000             : 
+   24001           0 :     dsigma[1] = 0.;
+   24002           0 :     hlftol = tol / 2.;
+   24003           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   24004           0 :         dsigma[2] = hlftol;
+   24005             :     }
+   24006           0 :     if (m > n) {
+   24007           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   24008           0 :         if (z__[1] <= tol) {
+   24009           0 :             *c__ = 1.;
+   24010           0 :             *s = 0.;
+   24011           0 :             z__[1] = tol;
+   24012             :         } else {
+   24013           0 :             *c__ = z1 / z__[1];
+   24014           0 :             *s = -z__[m] / z__[1];
+   24015             :         }
+   24016           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[m], &c__1, &vf[1], &c__1, c__, s);
+   24017           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[m], &c__1, &vl[1], &c__1, c__, s);
+   24018             :     } else {
+   24019           0 :         if (std::abs(z1) <= tol) {
+   24020           0 :             z__[1] = tol;
+   24021             :         } else {
+   24022           0 :             z__[1] = z1;
+   24023             :         }
+   24024             :     }
+   24025             : 
+   24026           0 :     i__1 = *k - 1;
+   24027           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &zw[2], &c__1, &z__[2], &c__1);
+   24028           0 :     i__1 = n - 1;
+   24029           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vfw[2], &c__1, &vf[2], &c__1);
+   24030           0 :     i__1 = n - 1;
+   24031           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vlw[2], &c__1, &vl[2], &c__1);
+   24032             : 
+   24033           0 :     return;
+   24034             : 
+   24035             : }
+   24036             : 
+   24037             : 
+   24038             : }
+   24039             : }
+   24040             : #include <cmath>
+   24041             : #include "blas/blas.h"
+   24042             : #include "lapack.h"
+   24043             : 
+   24044             : #include "blas/blas.h"
+   24045             : namespace PLMD{
+   24046             : namespace lapack{
+   24047             : using namespace blas;
+   24048             : void 
+   24049           0 : PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(int *icompq, 
+   24050             :         int *k, 
+   24051             :         float *d__, 
+   24052             :         float *z__, 
+   24053             :         float *vf, 
+   24054             :         float *vl, 
+   24055             :         float *difl, 
+   24056             :         float *difr, 
+   24057             :         int *lddifr, 
+   24058             :         float *dsigma, 
+   24059             :         float *work, 
+   24060             :         int *info)
+   24061             : {
+   24062             :     int difr_dim1, difr_offset, i__1, i__2;
+   24063             :     float d__2;
+   24064             : 
+   24065             :     int i__, j;
+   24066             :     float dj, rho;
+   24067             :     int iwk1, iwk2, iwk3;
+   24068             :     float temp;
+   24069             :     int iwk2i, iwk3i;
+   24070             :     float diflj, difrj, dsigj;
+   24071             :     float dsigjp;
+   24072           0 :     int c__1 = 1;
+   24073           0 :     int c__0 = 0;
+   24074           0 :     float one = 1.;
+   24075             : 
+   24076             :     /* avoid warnings on high gcc optimization levels */
+   24077             :     difrj = dsigjp = 0;
+   24078             : 
+   24079           0 :      --d__;
+   24080           0 :     --z__;
+   24081             :     --vf;
+   24082             :     --vl;
+   24083           0 :     --difl;
+   24084           0 :     difr_dim1 = *lddifr;
+   24085           0 :     difr_offset = 1 + difr_dim1;
+   24086           0 :     difr -= difr_offset;
+   24087           0 :     --dsigma;
+   24088           0 :     --work;
+   24089             : 
+   24090           0 :     *info = 0;
+   24091             : 
+   24092           0 :     if (*k == 1) {
+   24093           0 :         d__[1] = std::abs(z__[1]);
+   24094           0 :         difl[1] = d__[1];
+   24095           0 :         if (*icompq == 1) {
+   24096           0 :             difl[2] = 1.;
+   24097           0 :             difr[(difr_dim1 << 1) + 1] = 1.;
+   24098             :         }
+   24099           0 :         return;
+   24100             :     }
+   24101             : 
+   24102             :     iwk1 = 1;
+   24103           0 :     iwk2 = iwk1 + *k;
+   24104           0 :     iwk3 = iwk2 + *k;
+   24105             :     iwk2i = iwk2 - 1;
+   24106           0 :     iwk3i = iwk3 - 1;
+   24107             : 
+   24108           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   24109           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   24110           0 :     rho *= rho;
+   24111             : 
+   24112           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", k, &c__1, &one, &one, &work[iwk3], k);
+   24113             : 
+   24114           0 :     i__1 = *k;
+   24115           0 :     for (j = 1; j <= i__1; ++j) {
+   24116           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &work[iwk1], &rho, &d__[j], &work[
+   24117           0 :                 iwk2], info);
+   24118             : 
+   24119           0 :         if (*info != 0) {
+   24120             :             return;
+   24121             :         }
+   24122           0 :         work[iwk3i + j] = work[iwk3i + j] * work[j] * work[iwk2i + j];
+   24123           0 :         difl[j] = -work[j];
+   24124           0 :         difr[j + difr_dim1] = -work[j + 1];
+   24125             :         i__2 = j - 1;
+   24126           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24127           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24128           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24129             :                     j]);
+   24130             :         }
+   24131           0 :         i__2 = *k;
+   24132           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24133           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24134           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24135             :                     j]);
+   24136             :         }
+   24137             :     }
+   24138             : 
+   24139           0 :     i__1 = *k;
+   24140           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24141           0 :         d__2 =  std::sqrt(std::abs(work[iwk3i + i__]));
+   24142           0 :         z__[i__] = (z__[i__] > 0) ? d__2 : -d__2;
+   24143             :     }
+   24144             : 
+   24145           0 :     i__1 = *k;
+   24146           0 :     for (j = 1; j <= i__1; ++j) {
+   24147           0 :         diflj = difl[j];
+   24148           0 :         dj = d__[j];
+   24149           0 :         dsigj = -dsigma[j];
+   24150           0 :         if (j < *k) {
+   24151           0 :             difrj = -difr[j + difr_dim1];
+   24152           0 :             dsigjp = -dsigma[j + 1];
+   24153             :         }
+   24154           0 :         work[j] = -z__[j] / diflj / (dsigma[j] + dj);
+   24155             :         i__2 = j - 1;
+   24156           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24157           0 :           work[i__] = z__[i__] / (dsigma[i__] + dsigj - diflj) / ( dsigma[i__] + dj);
+   24158             :         }
+   24159           0 :         i__2 = *k;
+   24160           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24161           0 :             work[i__] = z__[i__] / (dsigma[i__] + dsigjp - difrj) / (dsigma[i__] + dj);
+   24162             :         }
+   24163           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &work[1], &c__1);
+   24164           0 :         work[iwk2i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vf[1], &c__1) / temp;
+   24165           0 :         work[iwk3i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vl[1], &c__1) / temp;
+   24166           0 :         if (*icompq == 1) {
+   24167           0 :             difr[j + (difr_dim1 << 1)] = temp;
+   24168             :         }
+   24169             :     }
+   24170             : 
+   24171           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk2], &c__1, &vf[1], &c__1);
+   24172           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk3], &c__1, &vl[1], &c__1);
+   24173             : 
+   24174             :     return;
+   24175             : 
+   24176             : } 
+   24177             : }
+   24178             : }
+   24179             : #include "blas/blas.h"
+   24180             : #include "lapack.h"
+   24181             : 
+   24182             : #include "blas/blas.h"
+   24183             : namespace PLMD{
+   24184             : namespace lapack{
+   24185             : using namespace blas;
+   24186             : void 
+   24187           0 : PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(int *icompq, 
+   24188             :         int *smlsiz, 
+   24189             :         int *n, 
+   24190             :         int *sqre, 
+   24191             :         float *d__, 
+   24192             :         float *e, 
+   24193             :         float *u, 
+   24194             :         int *ldu, 
+   24195             :         float *vt, 
+   24196             :         int *k, 
+   24197             :         float *difl, 
+   24198             :         float *difr, 
+   24199             :         float *z__, 
+   24200             :         float *poles, 
+   24201             :         int *givptr, 
+   24202             :         int *givcol, 
+   24203             :         int *ldgcol, 
+   24204             :         int *perm, 
+   24205             :         float *givnum, 
+   24206             :         float *c__, 
+   24207             :         float *s, 
+   24208             :         float *work, 
+   24209             :         int *iwork, 
+   24210             :         int *info)
+   24211             : {
+   24212             :     int givcol_dim1, givcol_offset, perm_dim1, perm_offset, difl_dim1, 
+   24213             :             difl_offset, difr_dim1, difr_offset, givnum_dim1, givnum_offset, 
+   24214             :             poles_dim1, poles_offset, u_dim1, u_offset, vt_dim1, vt_offset, 
+   24215             :             z_dim1, z_offset, i__1, i__2;
+   24216             : 
+   24217             :     int i__, j, m, i1, ic, lf, nd, ll, nl, vf, nr, vl, im1, ncc, 
+   24218             :             nlf, nrf, vfi, iwk, vli, lvl, nru, ndb1, nlp1, lvl2, nrp1;
+   24219             :     float beta;
+   24220             :     int idxq, nlvl;
+   24221             :     float alpha;
+   24222             :     int inode, ndiml, ndimr, idxqi, itemp;
+   24223             :     int sqrei;
+   24224             :     int nwork1, nwork2;
+   24225             :     int smlszp;
+   24226           0 :     int c__0 = 0;
+   24227           0 :     float zero = 0.0;
+   24228           0 :     float one = 1.;
+   24229           0 :     int c__1 = 1;
+   24230           0 :     --d__;
+   24231           0 :     --e;
+   24232           0 :     givnum_dim1 = *ldu;
+   24233           0 :     givnum_offset = 1 + givnum_dim1;
+   24234           0 :     givnum -= givnum_offset;
+   24235             :     poles_dim1 = *ldu;
+   24236             :     poles_offset = 1 + poles_dim1;
+   24237             :     poles -= poles_offset;
+   24238             :     z_dim1 = *ldu;
+   24239             :     z_offset = 1 + z_dim1;
+   24240             :     z__ -= z_offset;
+   24241             :     difr_dim1 = *ldu;
+   24242             :     difr_offset = 1 + difr_dim1;
+   24243             :     difr -= difr_offset;
+   24244             :     difl_dim1 = *ldu;
+   24245             :     difl_offset = 1 + difl_dim1;
+   24246             :     difl -= difl_offset;
+   24247             :     vt_dim1 = *ldu;
+   24248             :     vt_offset = 1 + vt_dim1;
+   24249           0 :     vt -= vt_offset;
+   24250             :     u_dim1 = *ldu;
+   24251             :     u_offset = 1 + u_dim1;
+   24252           0 :     u -= u_offset;
+   24253             :     --k;
+   24254             :     --givptr;
+   24255           0 :     perm_dim1 = *ldgcol;
+   24256           0 :     perm_offset = 1 + perm_dim1;
+   24257           0 :     perm -= perm_offset;
+   24258             :     givcol_dim1 = *ldgcol;
+   24259             :     givcol_offset = 1 + givcol_dim1;
+   24260             :     givcol -= givcol_offset;
+   24261             :     --c__;
+   24262             :     --s;
+   24263           0 :     --work;
+   24264           0 :     --iwork;
+   24265           0 :     *info = 0;
+   24266             : 
+   24267           0 :     m = *n + *sqre;
+   24268             : 
+   24269           0 :     if (*n <= *smlsiz) {
+   24270           0 :         if (*icompq == 0) {
+   24271           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &c__0, &c__0, &c__0, &d__[1], &e[1], &vt[
+   24272             :                     vt_offset], ldu, &u[u_offset], ldu, &u[u_offset], ldu, &
+   24273             :                     work[1], info);
+   24274             :         } else {
+   24275           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset]
+   24276             :                     , ldu, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], 
+   24277             :                     info);
+   24278             :         }
+   24279           0 :         return;
+   24280             :     }
+   24281             : 
+   24282             :     inode = 1;
+   24283           0 :     ndiml = inode + *n;
+   24284           0 :     ndimr = ndiml + *n;
+   24285           0 :     idxq = ndimr + *n;
+   24286           0 :     iwk = idxq + *n;
+   24287             : 
+   24288           0 :     ncc = 0;
+   24289           0 :     nru = 0;
+   24290             : 
+   24291           0 :     smlszp = *smlsiz + 1;
+   24292             :     vf = 1;
+   24293           0 :     vl = vf + m;
+   24294           0 :     nwork1 = vl + m;
+   24295           0 :     nwork2 = nwork1 + smlszp * smlszp;
+   24296             : 
+   24297           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   24298             :             smlsiz);
+   24299             : 
+   24300           0 :     ndb1 = (nd + 1) / 2;
+   24301             :     i__1 = nd;
+   24302           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   24303           0 :         i1 = i__ - 1;
+   24304           0 :         ic = iwork[inode + i1];
+   24305           0 :         nl = iwork[ndiml + i1];
+   24306           0 :         nlp1 = nl + 1;
+   24307           0 :         nr = iwork[ndimr + i1];
+   24308           0 :         nlf = ic - nl;
+   24309           0 :         nrf = ic + 1;
+   24310           0 :         idxqi = idxq + nlf - 2;
+   24311             :         vfi = vf + nlf - 1;
+   24312           0 :         vli = vl + nlf - 1;
+   24313           0 :         sqrei = 1;
+   24314           0 :         if (*icompq == 0) {
+   24315           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &work[nwork1], &smlszp);
+   24316           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nru, &ncc, &d__[nlf], &e[nlf], &
+   24317             :                     work[nwork1], &smlszp, &work[nwork2], &nl, &work[nwork2], 
+   24318           0 :                     &nl, &work[nwork2], info);
+   24319           0 :             itemp = nwork1 + nl * smlszp;
+   24320           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24321           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24322             :         } else {
+   24323           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nl, &nl, &zero, &one, &u[nlf + u_dim1], ldu);
+   24324           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &vt[nlf + vt_dim1], 
+   24325             :                     ldu);
+   24326           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &
+   24327             :                     vt[nlf + vt_dim1], ldu, &u[nlf + u_dim1], ldu, &u[nlf + 
+   24328           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24329           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24330           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + nlp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24331             :                     ;
+   24332             :         }
+   24333           0 :         if (*info != 0) {
+   24334             :             return;
+   24335             :         }
+   24336           0 :         i__2 = nl;
+   24337           0 :         for (j = 1; j <= i__2; ++j) {
+   24338           0 :             iwork[idxqi + j] = j;
+   24339             :         }
+   24340           0 :         if (i__ == nd && *sqre == 0) {
+   24341           0 :             sqrei = 0;
+   24342             :         } else {
+   24343           0 :             sqrei = 1;
+   24344             :         }
+   24345           0 :         idxqi += nlp1;
+   24346           0 :         vfi += nlp1;
+   24347           0 :         vli += nlp1;
+   24348           0 :         nrp1 = nr + sqrei;
+   24349           0 :         if (*icompq == 0) {
+   24350           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &work[nwork1], &smlszp);
+   24351           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nru, &ncc, &d__[nrf], &e[nrf], &
+   24352             :                     work[nwork1], &smlszp, &work[nwork2], &nr, &work[nwork2], 
+   24353           0 :                     &nr, &work[nwork2], info);
+   24354           0 :             itemp = nwork1 + (nrp1 - 1) * smlszp;
+   24355           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24356           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24357             :         } else {
+   24358           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nr, &nr, &zero, &one, &u[nrf + u_dim1], ldu);
+   24359           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &vt[nrf + vt_dim1], 
+   24360             :                     ldu);
+   24361           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &
+   24362             :                     vt[nrf + vt_dim1], ldu, &u[nrf + u_dim1], ldu, &u[nrf + 
+   24363           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24364           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24365           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + nrp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24366             :                     ;
+   24367             :         }
+   24368           0 :         if (*info != 0) {
+   24369             :             return;
+   24370             :         }
+   24371           0 :         i__2 = nr;
+   24372           0 :         for (j = 1; j <= i__2; ++j) {
+   24373           0 :             iwork[idxqi + j] = j;
+   24374             :         }
+   24375             :     }
+   24376             : 
+   24377           0 :     j = (1 << nlvl);
+   24378             : 
+   24379           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   24380           0 :         lvl2 = (lvl << 1) - 1;
+   24381             : 
+   24382           0 :         if (lvl == 1) {
+   24383             :             lf = 1;
+   24384             :             ll = 1;
+   24385             :         } else {
+   24386           0 :             lf = (1 << (lvl-1));
+   24387           0 :             ll = (lf << 1) - 1;
+   24388             :         }
+   24389             :         i__1 = ll;
+   24390           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   24391           0 :             im1 = i__ - 1;
+   24392           0 :             ic = iwork[inode + im1];
+   24393           0 :             nl = iwork[ndiml + im1];
+   24394           0 :             nr = iwork[ndimr + im1];
+   24395           0 :             nlf = ic - nl;
+   24396           0 :             if (i__ == ll) {
+   24397           0 :                 sqrei = *sqre;
+   24398             :             } else {
+   24399           0 :                 sqrei = 1;
+   24400             :             }
+   24401             :             vfi = vf + nlf - 1;
+   24402           0 :             vli = vl + nlf - 1;
+   24403           0 :             idxqi = idxq + nlf - 1;
+   24404           0 :             alpha = d__[ic];
+   24405           0 :             beta = e[ic];
+   24406           0 :             if (*icompq == 0) {
+   24407           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24408           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[
+   24409             :                         perm_offset], &givptr[1], &givcol[givcol_offset], 
+   24410             :                         ldgcol, &givnum[givnum_offset], ldu, &poles[
+   24411             :                         poles_offset], &difl[difl_offset], &difr[difr_offset],
+   24412           0 :                          &z__[z_offset], &k[1], &c__[1], &s[1], &work[nwork1],
+   24413           0 :                          &iwork[iwk], info);
+   24414             :             } else {
+   24415           0 :                 --j;
+   24416           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24417           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[nlf + 
+   24418           0 :                         lvl * perm_dim1], &givptr[j], &givcol[nlf + lvl2 * 
+   24419             :                         givcol_dim1], ldgcol, &givnum[nlf + lvl2 * 
+   24420             :                         givnum_dim1], ldu, &poles[nlf + lvl2 * poles_dim1], &
+   24421           0 :                         difl[nlf + lvl * difl_dim1], &difr[nlf + lvl2 * 
+   24422           0 :                         difr_dim1], &z__[nlf + lvl * z_dim1], &k[j], &c__[j], 
+   24423           0 :                         &s[j], &work[nwork1], &iwork[iwk], info);
+   24424             :             }
+   24425           0 :             if (*info != 0) {
+   24426             :                 return;
+   24427             :             }
+   24428             :         }
+   24429             :     }
+   24430             : 
+   24431             :     return;
+   24432             : 
+   24433             : }
+   24434             : 
+   24435             : 
+   24436             : }
+   24437             : }
+   24438             : #include <cctype>
+   24439             : 
+   24440             : #include "blas/blas.h"
+   24441             : #include "lapack.h"
+   24442             : 
+   24443             : 
+   24444             : #include "blas/blas.h"
+   24445             : namespace PLMD{
+   24446             : namespace lapack{
+   24447             : using namespace blas;
+   24448             : void 
+   24449           0 : PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)(const char *uplo,
+   24450             :                         int *sqre,
+   24451             :                         int *n,
+   24452             :                         int *ncvt,
+   24453             :                         int *nru,
+   24454             :                         int *ncc,
+   24455             :                         float *d__,
+   24456             :                         float *e, 
+   24457             :                         float *vt, 
+   24458             :                         int *ldvt, 
+   24459             :                         float *u,
+   24460             :                         int *ldu, 
+   24461             :                         float *c__,
+   24462             :                         int *ldc,
+   24463             :                         float *work, 
+   24464             :                         int *info)
+   24465             : {
+   24466           0 :     const char xuplo=std::toupper(*uplo);
+   24467             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   24468             :             i__2;
+   24469           0 :     int c__1 = 1;
+   24470             :     int itmp1,itmp2;
+   24471             :     int i__, j;
+   24472             :     float r__, cs, sn;
+   24473             :     int np1, isub;
+   24474             :     float smin;
+   24475             :     int sqre1;
+   24476             :     int iuplo;
+   24477             :     int rotate;
+   24478             : 
+   24479           0 :     --d__;
+   24480           0 :     --e;
+   24481           0 :     vt_dim1 = *ldvt;
+   24482           0 :     vt_offset = 1 + vt_dim1;
+   24483           0 :     vt -= vt_offset;
+   24484           0 :     u_dim1 = *ldu;
+   24485           0 :     u_offset = 1 + u_dim1;
+   24486           0 :     u -= u_offset;
+   24487           0 :     c_dim1 = *ldc;
+   24488           0 :     c_offset = 1 + c_dim1;
+   24489           0 :     c__ -= c_offset;
+   24490           0 :     --work;
+   24491             : 
+   24492           0 :     *info = 0;
+   24493             :     iuplo = 0;
+   24494           0 :     if (xuplo == 'U') {
+   24495             :         iuplo = 1;
+   24496             :     }
+   24497           0 :     if (xuplo == 'L') {
+   24498             :         iuplo = 2;
+   24499             :     }
+   24500             :     
+   24501           0 :     itmp1 = (*n > 1) ? *n : 1;
+   24502           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   24503           0 :     if (iuplo == 0) {
+   24504           0 :         *info = -1;
+   24505           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   24506           0 :         *info = -2;
+   24507           0 :     } else if (*n < 0) {
+   24508           0 :         *info = -3;
+   24509           0 :     } else if (*ncvt < 0) {
+   24510           0 :         *info = -4;
+   24511           0 :     } else if (*nru < 0) {
+   24512           0 :         *info = -5;
+   24513           0 :     } else if (*ncc < 0) {
+   24514           0 :         *info = -6;
+   24515           0 :     } else if ( (*ncvt == 0 && *ldvt < 1) || (*ncvt > 0 && *ldvt < itmp1)) {
+   24516           0 :         *info = -10;
+   24517           0 :     } else if (*ldu < itmp2) {
+   24518           0 :         *info = -12;
+   24519           0 :     } else if ((*ncc == 0 && *ldc < 1) || (*ncc > 0 && *ldc < itmp1)) {
+   24520           0 :         *info = -14;
+   24521             :     }
+   24522           0 :     if (*info != 0) {
+   24523             :         return;
+   24524             :     }
+   24525           0 :     if (*n == 0) {
+   24526             :         return;
+   24527             :     }
+   24528             : 
+   24529           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   24530           0 :     np1 = *n + 1;
+   24531           0 :     sqre1 = *sqre;
+   24532             : 
+   24533           0 :     if (iuplo == 1 && sqre1 == 1) {
+   24534             :         i__1 = *n - 1;
+   24535           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24536           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24537           0 :             d__[i__] = r__;
+   24538           0 :             e[i__] = sn * d__[i__ + 1];
+   24539           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24540           0 :             if (rotate) {
+   24541           0 :                 work[i__] = cs;
+   24542           0 :                 work[*n + i__] = sn;
+   24543             :             }
+   24544             :         }
+   24545           0 :         PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24546           0 :         d__[*n] = r__;
+   24547           0 :         e[*n] = 0.f;
+   24548           0 :         if (rotate) {
+   24549           0 :             work[*n] = cs;
+   24550           0 :             work[*n + *n] = sn;
+   24551             :         }
+   24552             :         iuplo = 2;
+   24553             :         sqre1 = 0;
+   24554             : 
+   24555           0 :         if (*ncvt > 0) {
+   24556           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncvt, &work[1], &work[np1], &vt[
+   24557             :                     vt_offset], ldvt);
+   24558             :         }
+   24559             :     }
+   24560           0 :     if (iuplo == 2) {
+   24561           0 :         i__1 = *n - 1;
+   24562           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24563           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24564           0 :             d__[i__] = r__;
+   24565           0 :             e[i__] = sn * d__[i__ + 1];
+   24566           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24567           0 :             if (rotate) {
+   24568           0 :                 work[i__] = cs;
+   24569           0 :                 work[*n + i__] = sn;
+   24570             :             }
+   24571             :         }
+   24572             : 
+   24573           0 :         if (sqre1 == 1) {
+   24574           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24575           0 :             d__[*n] = r__;
+   24576           0 :             if (rotate) {
+   24577           0 :                 work[*n] = cs;
+   24578           0 :                 work[*n + *n] = sn;
+   24579             :             }
+   24580             :         }
+   24581           0 :         if (*nru > 0) {
+   24582           0 :             if (sqre1 == 0) {
+   24583           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[np1], &u[
+   24584             :                         u_offset], ldu);
+   24585             :             } else {
+   24586           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &np1, &work[1], &work[np1], &u[
+   24587             :                         u_offset], ldu);
+   24588             :             }
+   24589             :         }
+   24590           0 :         if (*ncc > 0) {
+   24591           0 :             if (sqre1 == 0) {
+   24592           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[np1], &c__[
+   24593             :                         c_offset], ldc);
+   24594             :             } else {
+   24595           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncc, &work[1], &work[np1], &c__[
+   24596             :                         c_offset], ldc);
+   24597             :             }
+   24598             :         }
+   24599             :     }
+   24600             : 
+   24601           0 :     PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)("U", n, ncvt, nru, ncc, &d__[1], &e[1], &vt[vt_offset], ldvt, &u[
+   24602             :             u_offset], ldu, &c__[c_offset], ldc, &work[1], info);
+   24603             : 
+   24604           0 :     i__1 = *n;
+   24605           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24606             : 
+   24607             :         isub = i__;
+   24608           0 :         smin = d__[i__];
+   24609           0 :         i__2 = *n;
+   24610           0 :         for (j = i__ + 1; j <= i__2; ++j) {
+   24611           0 :             if (d__[j] < smin) {
+   24612             :                 isub = j;
+   24613             :                 smin = d__[j];
+   24614             :             }
+   24615             :         }
+   24616           0 :         if (isub != i__) {
+   24617           0 :             d__[isub] = d__[i__];
+   24618           0 :             d__[i__] = smin;
+   24619           0 :             if (*ncvt > 0) {
+   24620           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[i__ + vt_dim1], 
+   24621             :                         ldvt);
+   24622             :             }
+   24623           0 :             if (*nru > 0) {
+   24624           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[i__ * u_dim1 + 1]
+   24625             :                         , &c__1);
+   24626             :             }
+   24627           0 :             if (*ncc > 0) {
+   24628           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[i__ + c_dim1], ldc)
+   24629             :                         ;
+   24630             :             }
+   24631             :         }
+   24632             :     }
+   24633             : 
+   24634             :     return;
+   24635             : }
+   24636             : 
+   24637             : 
+   24638             : }
+   24639             : }
+   24640             : #include <cmath>
+   24641             : #include "lapack.h"
+   24642             : 
+   24643             : #include "blas/blas.h"
+   24644             : namespace PLMD{
+   24645             : namespace lapack{
+   24646             : using namespace blas;
+   24647             : void
+   24648           0 : PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(int *n,
+   24649             :         int *lvl,
+   24650             :         int *nd,
+   24651             :         int *inode,
+   24652             :         int *ndiml,
+   24653             :         int *ndimr,
+   24654             :         int *msub)
+   24655             : {
+   24656           0 :   int maxn = (*n > 1) ? *n : 1;
+   24657             :   float temp;
+   24658             :   int i,il,ir,llst,nlvl,ncrnt;
+   24659             : 
+   24660           0 :   temp = std::log( ((float) maxn) / ((float)(*msub+1))) / std::log(2.0);
+   24661             :   
+   24662           0 :   *lvl = 1 + (int) temp;
+   24663             : 
+   24664           0 :   i = *n / 2;
+   24665           0 :   inode[0] = i + 1;
+   24666           0 :   ndiml[0] = i;
+   24667           0 :   ndimr[0] = *n - i - 1;
+   24668             :   il = -1;
+   24669             :   ir = 0;
+   24670             :   llst = 1;
+   24671             : 
+   24672           0 :   for(nlvl=1;nlvl<*lvl;nlvl++) {
+   24673           0 :     for(i=0;i<llst;i++) {
+   24674           0 :       il += 2;
+   24675           0 :       ir += 2;
+   24676           0 :       ncrnt = llst + i - 1;
+   24677           0 :       ndiml[il] = ndiml[ncrnt] / 2;
+   24678           0 :       ndimr[il] = ndiml[ncrnt] - ndiml[il] - 1;
+   24679           0 :       inode[il] = inode[ncrnt] - ndimr[il] - 1;
+   24680           0 :       ndiml[ir] = ndimr[ncrnt] / 2;
+   24681           0 :       ndimr[ir] = ndimr[ncrnt] - ndiml[ir] - 1;
+   24682           0 :       inode[ir] = inode[ncrnt] + ndiml[ir] + 1;
+   24683             :     }
+   24684           0 :     llst *= 2;
+   24685             :   }
+   24686           0 :   *nd = llst*2 - 1;
+   24687           0 :   return;
+   24688             : }
+   24689             : }
+   24690             : }
+   24691             : #include <cctype>
+   24692             : #include "lapack.h"
+   24693             : 
+   24694             : 
+   24695             : #include "blas/blas.h"
+   24696             : namespace PLMD{
+   24697             : namespace lapack{
+   24698             : using namespace blas;
+   24699             : void
+   24700           0 : PLUMED_BLAS_F77_FUNC(slaset,SLASET)(const char *uplo,
+   24701             :         int *m,
+   24702             :         int *n,
+   24703             :         float *alpha,
+   24704             :         float *beta,
+   24705             :         float *a,
+   24706             :         int *lda)
+   24707             : {
+   24708             :   int i,j,k;
+   24709           0 :   const char ch=std::toupper(*uplo);
+   24710             : 
+   24711           0 :   if(ch=='U') {
+   24712           0 :     for(j=1;j<*n;j++) {
+   24713           0 :       k = (j < *m) ? j : *m;
+   24714           0 :       for(i=0;i<k;i++)
+   24715           0 :         a[j*(*lda)+i] = *alpha;
+   24716             :     }
+   24717           0 :   } else if(ch=='L') {
+   24718           0 :     k = (*m < *n) ? *m : *n;
+   24719           0 :     for(j=0;j<k;j++) {
+   24720           0 :       for(i=j+1;i<*m;i++)
+   24721           0 :         a[j*(*lda)+i] = *alpha;
+   24722             :     }
+   24723             :   } else {
+   24724           0 :     for(j=0;j<*n;j++) {
+   24725           0 :       for(i=0;i<*m;i++)
+   24726           0 :         a[j*(*lda)+i] = *alpha;
+   24727             :     }    
+   24728             :   }
+   24729             : 
+   24730           0 :   k = (*m < *n) ? *m : *n;
+   24731           0 :   for(i=0;i<k;i++)
+   24732           0 :     a[i*(*lda)+i] = *beta;
+   24733           0 : }
+   24734             : }
+   24735             : }
+   24736             : #include <cmath>
+   24737             : #include "blas/blas.h"
+   24738             : #include "lapack.h"
+   24739             : #include "lapack_limits.h"
+   24740             : 
+   24741             : #include "real.h"
+   24742             : 
+   24743             : #include "blas/blas.h"
+   24744             : namespace PLMD{
+   24745             : namespace lapack{
+   24746             : using namespace blas;
+   24747             : void
+   24748           0 : PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(int *n,
+   24749             :         float *d,
+   24750             :         float *e,
+   24751             :         float *work,
+   24752             :         int *info)
+   24753             : {
+   24754           0 :   float sigmx = 0.0;
+   24755             :   int i,j,k,iinfo;
+   24756             :   float minval,safemin;
+   24757             :   float dtemp,scale;
+   24758             :   float eps;
+   24759             : 
+   24760             :   eps = PLUMED_GMX_FLOAT_EPS;
+   24761             :   minval = PLUMED_GMX_FLOAT_MIN;
+   24762             :   safemin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   24763           0 :   *info = 0;
+   24764             : 
+   24765           0 :   if(*n<0) {
+   24766           0 :     *info = -2;
+   24767           0 :     return;
+   24768             :   }
+   24769             :   
+   24770           0 :   for(i=0;i<*n-1;i++) {
+   24771           0 :     d[i] = std::abs(d[i]);
+   24772           0 :     dtemp = std::abs(e[i]);
+   24773           0 :     if(dtemp>sigmx)
+   24774           0 :       sigmx=dtemp;
+   24775             :   }
+   24776           0 :   d[*n-1] = std::abs(d[*n-1]);
+   24777             :   
+   24778           0 :   if(std::abs(sigmx)<PLUMED_GMX_FLOAT_MIN) {
+   24779           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D",n,d,&iinfo);
+   24780           0 :     return;
+   24781             :   }
+   24782             : 
+   24783           0 :   for(i=0;i<*n;i++) {
+   24784           0 :     if(d[i]>sigmx)
+   24785           0 :       sigmx=d[i];
+   24786             :   }
+   24787             : 
+   24788             :   /* Copy d and e into work (z format) and scale.
+   24789             :    * Squaring input data makes scaling by a power of the
+   24790             :    * radix pointless.
+   24791             :    */
+   24792           0 :   scale =  std::sqrt(eps/safemin);
+   24793           0 :   i = 1;
+   24794           0 :   j = 2;
+   24795           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n,d,&i,work,&j);
+   24796           0 :   k = *n-1;
+   24797           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&k,e,&i,work+1,&j);
+   24798           0 :   i = 0;
+   24799           0 :   j = 2*(*n)-1;
+   24800           0 :   k = 1;
+   24801           0 :   PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&i,&i,&sigmx,&scale,&j,&k,work,&j,&iinfo);
+   24802             : 
+   24803             : 
+   24804             :   /* Compute q and e elements */
+   24805           0 :   for(i=0;i<2*(*n)-1;i++)
+   24806           0 :     work[i] = work[i]*work[i];
+   24807             : 
+   24808           0 :   work[2*(*n)-1] = 0.0;
+   24809             : 
+   24810           0 :   PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(n,work,info);
+   24811             : 
+   24812           0 :   j = 0;
+   24813           0 :   k = 1;
+   24814           0 :   if(*info==0) {
+   24815           0 :     for(i=0;i<*n;i++)
+   24816           0 :       d[i]= std::sqrt(work[i]);
+   24817           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&j,&j,&scale,&sigmx,n,&k,d,n,&iinfo);
+   24818             :   }
+   24819             :   return;
+   24820             : }
+   24821             : }
+   24822             : }
+   24823             : #include <cmath>
+   24824             : #include "lapack.h"
+   24825             : #include "lapack_limits.h"
+   24826             : 
+   24827             : #include "real.h"
+   24828             : 
+   24829             : #ifdef _MSC_VER
+   24830             : #pragma warning(disable: 4723) /*division by zero - is used on purpose here*/
+   24831             : #endif
+   24832             : 
+   24833             : #include "blas/blas.h"
+   24834             : namespace PLMD{
+   24835             : namespace lapack{
+   24836             : using namespace blas;
+   24837             : void 
+   24838           0 : PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(int *n, 
+   24839             :                         float *z__, 
+   24840             :                         int *info)
+   24841             : {
+   24842             :     int i__1, i__2, i__3;
+   24843             :     float d__1, d__2;
+   24844             : 
+   24845             :     float d__, e;
+   24846             :     int k;
+   24847             :     float s, t;
+   24848             :     int i0, i4, n0, pp;
+   24849             :     float dee, eps, tol;
+   24850             :     int ipn4;
+   24851             :     float tol2;
+   24852             :     int ieee;
+   24853             :     int nbig;
+   24854             :     float dmin__, emin, emax;
+   24855             :     int kmin, ndiv, iter;
+   24856             :     float qmin, temp, qmax, zmax;
+   24857             :     int splt, nfail;
+   24858             :     float desig, trace, sigma;
+   24859             :     int iinfo;
+   24860             :     float deemin;
+   24861             :     int iwhila, iwhilb;
+   24862             :     float oldemn, safmin, minval;
+   24863             :     float posinf,neginf,negzro,newzro;
+   24864             :     float zero = 0.0;
+   24865             :     float one = 1.0;
+   24866             : 
+   24867           0 :     --z__;
+   24868             : 
+   24869           0 :     *info = 0;
+   24870             :     eps = PLUMED_GMX_FLOAT_EPS;
+   24871             :     minval = PLUMED_GMX_FLOAT_MIN;
+   24872             :     safmin = minval*(1.0+eps);
+   24873             : 
+   24874             :     tol = eps * 100.;
+   24875             : 
+   24876             :     d__1 = tol;
+   24877             :     tol2 = d__1 * d__1;
+   24878             : 
+   24879           0 :     if (*n < 0) {
+   24880           0 :         *info = -1;
+   24881           0 :         return;
+   24882           0 :     } else if (*n == 0) {
+   24883             :         return;
+   24884           0 :     } else if (*n == 1) {
+   24885             : 
+   24886           0 :         if (z__[1] < 0.) {
+   24887           0 :             *info = -201;
+   24888             :         }
+   24889           0 :         return;
+   24890           0 :     } else if (*n == 2) {
+   24891             : 
+   24892           0 :         if (z__[2] < 0. || z__[3] < 0.) {
+   24893           0 :             *info = -2;
+   24894           0 :             return;
+   24895           0 :         } else if (z__[3] > z__[1]) {
+   24896             :             d__ = z__[3];
+   24897           0 :             z__[3] = z__[1];
+   24898           0 :             z__[1] = d__;
+   24899             :         }
+   24900           0 :         z__[5] = z__[1] + z__[2] + z__[3];
+   24901           0 :         if (z__[2] > z__[3] * tol2) {
+   24902           0 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+   24903           0 :             s = z__[3] * (z__[2] / t);
+   24904           0 :             if (s <= t) {
+   24905           0 :                 s = z__[3] * (z__[2] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   24906             :             } else {
+   24907           0 :                 s = z__[3] * (z__[2] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   24908             :             }
+   24909           0 :             t = z__[1] + (s + z__[2]);
+   24910           0 :             z__[3] *= z__[1] / t;
+   24911           0 :             z__[1] = t;
+   24912             :         }
+   24913           0 :         z__[2] = z__[3];
+   24914           0 :         z__[6] = z__[2] + z__[1];
+   24915           0 :         return;
+   24916             :     }
+   24917           0 :     z__[*n * 2] = 0.;
+   24918           0 :     emin = z__[2];
+   24919           0 :     qmax = 0.;
+   24920             :     zmax = 0.;
+   24921             :     d__ = 0.;
+   24922             :     e = 0.;
+   24923             : 
+   24924           0 :     i__1 = 2*(*n - 1);
+   24925           0 :     for (k = 1; k <= i__1; k += 2) {
+   24926           0 :         if (z__[k] < 0.) {
+   24927           0 :             *info = -(k + 200);
+   24928           0 :             return;
+   24929           0 :         } else if (z__[k + 1] < 0.) {
+   24930           0 :             *info = -(k + 201);
+   24931           0 :             return;
+   24932             :         }
+   24933           0 :         d__ += z__[k];
+   24934           0 :         e += z__[k + 1];
+   24935           0 :         d__1 = qmax, d__2 = z__[k];
+   24936           0 :         qmax = (d__1>d__2) ? d__1 : d__2;
+   24937             :         d__1 = emin, d__2 = z__[k + 1];
+   24938           0 :         emin = (d__1<d__2) ? d__1 : d__2;
+   24939           0 :         d__1 = (qmax>zmax) ? qmax : zmax;
+   24940             :         d__2 = z__[k + 1];
+   24941           0 :         zmax = (d__1>d__2) ? d__1 : d__2;
+   24942             :     }
+   24943           0 :     if (z__[(*n << 1) - 1] < 0.) {
+   24944           0 :         *info = -((*n << 1) + 199);
+   24945           0 :         return;
+   24946             :     }
+   24947           0 :     d__ += z__[(*n << 1) - 1];
+   24948           0 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+   24949           0 :     qmax = (d__1>d__2) ? d__1 : d__2;
+   24950             : 
+   24951           0 :     if (std::abs(e)<PLUMED_GMX_FLOAT_MIN) {
+   24952             :         i__1 = *n;
+   24953           0 :         for (k = 2; k <= i__1; ++k) {
+   24954           0 :             z__[k] = z__[(k << 1) - 1];
+   24955             :         }
+   24956           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   24957           0 :         z__[(*n << 1) - 1] = d__;
+   24958           0 :         return;
+   24959             :     }
+   24960             : 
+   24961           0 :     trace = d__ + e;
+   24962             : 
+   24963           0 :     if (std::abs(trace)<PLUMED_GMX_FLOAT_MIN) {
+   24964           0 :         z__[(*n << 1) - 1] = 0.;
+   24965           0 :         return;
+   24966             :     }
+   24967             : 
+   24968           0 :     ieee = 1;
+   24969           0 :     posinf = one/zero;
+   24970           0 :     if(posinf<=1.0)
+   24971           0 :       ieee = 0;
+   24972             :     neginf = -one/zero;
+   24973           0 :     if(neginf>=0.0)
+   24974           0 :       ieee = 0;
+   24975           0 :     negzro = one/(neginf+one);
+   24976           0 :     if(std::abs(negzro)>PLUMED_GMX_FLOAT_MIN)
+   24977           0 :       ieee = 0;
+   24978           0 :     neginf = one/negzro;
+   24979           0 :     if(neginf>=0)
+   24980           0 :       ieee = 0;
+   24981           0 :     newzro = negzro + zero;
+   24982           0 :     if(std::abs(newzro-zero)>PLUMED_GMX_FLOAT_MIN)
+   24983           0 :       ieee = 0;
+   24984           0 :     posinf = one /newzro;
+   24985           0 :     if(posinf<=one)
+   24986           0 :       ieee = 0;
+   24987           0 :     neginf = neginf*posinf;
+   24988           0 :     if(neginf>=zero)
+   24989           0 :       ieee = 0;
+   24990           0 :     posinf = posinf*posinf;
+   24991           0 :     if(posinf<=1.0)
+   24992           0 :       ieee = 0;
+   24993             : 
+   24994           0 :     for (k = *n << 1; k >= 2; k += -2) {
+   24995           0 :         z__[k * 2] = 0.;
+   24996           0 :         z__[(k << 1) - 1] = z__[k];
+   24997           0 :         z__[(k << 1) - 2] = 0.;
+   24998           0 :         z__[(k << 1) - 3] = z__[k - 1];
+   24999             :     }
+   25000             : 
+   25001           0 :     i0 = 1;
+   25002           0 :     n0 = *n;
+   25003             : 
+   25004           0 :     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
+   25005           0 :         ipn4 = 4*(i0 + n0);
+   25006           0 :         i__1 = 2*(i0 + n0 - 1);
+   25007           0 :         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
+   25008           0 :             temp = z__[i4 - 3];
+   25009           0 :             z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25010           0 :             z__[ipn4 - i4 - 3] = temp;
+   25011           0 :             temp = z__[i4 - 1];
+   25012           0 :             z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25013           0 :             z__[ipn4 - i4 - 5] = temp;
+   25014             :         }
+   25015             :     }
+   25016             : 
+   25017           0 :     pp = 0;
+   25018             : 
+   25019           0 :     for (k = 1; k <= 2; ++k) {
+   25020             : 
+   25021           0 :         d__ = z__[(n0 << 2) + pp - 3];
+   25022           0 :         i__1 = (i0 << 2) + pp;
+   25023           0 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+   25024           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25025           0 :                 z__[i4 - 1] = -0.;
+   25026           0 :                 d__ = z__[i4 - 3];
+   25027             :             } else {
+   25028           0 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+   25029             :             }
+   25030             :         }
+   25031             : 
+   25032           0 :         emin = z__[(i0 << 2) + pp + 1];
+   25033           0 :         d__ = z__[(i0 << 2) + pp - 3];
+   25034             :         i__1 = 4*(n0 - 1) + pp;
+   25035           0 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+   25036           0 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+   25037           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25038           0 :                 z__[i4 - 1] = -0.;
+   25039           0 :                 z__[i4 - (pp << 1) - 2] = d__;
+   25040           0 :                 z__[i4 - (pp << 1)] = 0.;
+   25041           0 :                 d__ = z__[i4 + 1];
+   25042           0 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+   25043           0 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+   25044           0 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+   25045           0 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+   25046           0 :                 d__ *= temp;
+   25047             :             } else {
+   25048           0 :                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
+   25049             :                         pp << 1) - 2]);
+   25050           0 :                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
+   25051             :             }
+   25052           0 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+   25053           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25054             :         }
+   25055           0 :         z__[(n0 << 2) - pp - 2] = d__;
+   25056             : 
+   25057             : 
+   25058           0 :         qmax = z__[(i0 << 2) - pp - 2];
+   25059           0 :         i__1 = (n0 << 2) - pp - 2;
+   25060           0 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+   25061           0 :             d__1 = qmax, d__2 = z__[i4];
+   25062           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25063             :         }
+   25064             : 
+   25065           0 :         pp = 1 - pp;
+   25066             :     }
+   25067             : 
+   25068           0 :     iter = 2;
+   25069           0 :     nfail = 0;
+   25070           0 :     ndiv = 2*(n0 - i0);
+   25071             : 
+   25072           0 :     i__1 = *n + 1;
+   25073           0 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+   25074           0 :         if (n0 < 1) {
+   25075           0 :             goto L170;
+   25076             :         }
+   25077             : 
+   25078           0 :         desig = 0.;
+   25079           0 :         if (n0 == *n) {
+   25080           0 :             sigma = 0.;
+   25081             :         } else {
+   25082           0 :             sigma = -z__[(n0 << 2) - 1];
+   25083             :         }
+   25084           0 :         if (sigma < 0.) {
+   25085           0 :             *info = 1;
+   25086           0 :             return;
+   25087             :         }
+   25088             : 
+   25089             :         emax = 0.;
+   25090           0 :         if (n0 > i0) {
+   25091           0 :             emin = std::abs(z__[(n0 << 2) - 5]);
+   25092             :         } else {
+   25093             :             emin = 0.;
+   25094             :         }
+   25095           0 :         qmin = z__[(n0 << 2) - 3];
+   25096           0 :         qmax = qmin;
+   25097           0 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+   25098           0 :             if (z__[i4 - 5] <= 0.) {
+   25099           0 :                 goto L100;
+   25100             :             }
+   25101           0 :             if (qmin >= emax * 4.) {
+   25102           0 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+   25103           0 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+   25104             :                 d__1 = emax, d__2 = z__[i4 - 5];
+   25105           0 :                 emax = (d__1>d__2) ? d__1 : d__2;
+   25106             :             }
+   25107           0 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+   25108           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25109             :             d__1 = emin, d__2 = z__[i4 - 5];
+   25110           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25111             :         }
+   25112             :         i4 = 4;
+   25113             : 
+   25114           0 : L100:
+   25115           0 :         i0 = i4 / 4;
+   25116           0 :         pp = 0;
+   25117             : 
+   25118           0 :         if (n0 - i0 > 1) {
+   25119           0 :             dee = z__[(i0 << 2) - 3];
+   25120             :             deemin = dee;
+   25121             :             kmin = i0;
+   25122           0 :             i__2 = (n0 << 2) - 3;
+   25123           0 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+   25124           0 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+   25125           0 :                 if (dee <= deemin) {
+   25126             :                     deemin = dee;
+   25127           0 :                     kmin = (i4 + 3) / 4;
+   25128             :                 }
+   25129             :             }
+   25130           0 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+   25131             :                     .5) {
+   25132           0 :                 ipn4 = 4*(i0 + n0);
+   25133           0 :                 pp = 2;
+   25134           0 :                 i__2 = 2*(i0 + n0 - 1);
+   25135           0 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+   25136           0 :                     temp = z__[i4 - 3];
+   25137           0 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25138           0 :                     z__[ipn4 - i4 - 3] = temp;
+   25139           0 :                     temp = z__[i4 - 2];
+   25140           0 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+   25141           0 :                     z__[ipn4 - i4 - 2] = temp;
+   25142           0 :                     temp = z__[i4 - 1];
+   25143           0 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25144           0 :                     z__[ipn4 - i4 - 5] = temp;
+   25145           0 :                     temp = z__[i4];
+   25146           0 :                     z__[i4] = z__[ipn4 - i4 - 4];
+   25147           0 :                     z__[ipn4 - i4 - 4] = temp;
+   25148             :                 }
+   25149             :             }
+   25150             :         }
+   25151             : 
+   25152             : 
+   25153           0 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+   25154           0 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+   25155             : 
+   25156           0 :         nbig = (n0 - i0 + 1) * 30;
+   25157             :         i__2 = nbig;
+   25158           0 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+   25159           0 :             if (i0 > n0) {
+   25160           0 :                 goto L150;
+   25161             :             }
+   25162             : 
+   25163           0 :             PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+   25164             :                     nfail, &iter, &ndiv, &ieee);
+   25165             : 
+   25166           0 :             pp = 1 - pp;
+   25167             : 
+   25168           0 :             if (pp == 0 && n0 - i0 >= 3) {
+   25169           0 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+   25170             :                          sigma) {
+   25171           0 :                     splt = i0 - 1;
+   25172           0 :                     qmax = z__[(i0 << 2) - 3];
+   25173           0 :                     emin = z__[(i0 << 2) - 1];
+   25174           0 :                     oldemn = z__[i0 * 4];
+   25175           0 :                     i__3 = 4*(n0 - 3);
+   25176           0 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+   25177           0 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+   25178           0 :                                 tol2 * sigma) {
+   25179           0 :                             z__[i4 - 1] = -sigma;
+   25180           0 :                             splt = i4 / 4;
+   25181           0 :                             qmax = 0.;
+   25182           0 :                             emin = z__[i4 + 3];
+   25183           0 :                             oldemn = z__[i4 + 4];
+   25184             :                         } else {
+   25185           0 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+   25186           0 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+   25187             :                             d__1 = emin, d__2 = z__[i4 - 1];
+   25188           0 :                             emin = (d__1<d__2) ? d__1 : d__2;
+   25189             :                             d__1 = oldemn, d__2 = z__[i4];
+   25190           0 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+   25191             :                         }
+   25192             :                     }
+   25193           0 :                     z__[(n0 << 2) - 1] = emin;
+   25194           0 :                     z__[n0 * 4] = oldemn;
+   25195           0 :                     i0 = splt + 1;
+   25196             :                 }
+   25197             :             }
+   25198             :         }
+   25199             : 
+   25200           0 :         *info = 2;
+   25201           0 :         return;
+   25202             : 
+   25203             : L150:
+   25204             :         ;
+   25205             :     }
+   25206             : 
+   25207           0 :     *info = 3;
+   25208           0 :     return;
+   25209             : 
+   25210             : 
+   25211             : L170:
+   25212             : 
+   25213           0 :     i__1 = *n;
+   25214           0 :     for (k = 2; k <= i__1; ++k) {
+   25215           0 :         z__[k] = z__[(k << 2) - 3];
+   25216             :     }
+   25217             : 
+   25218           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   25219             : 
+   25220             :     e = 0.;
+   25221           0 :     for (k = *n; k >= 1; --k) {
+   25222           0 :         e += z__[k];
+   25223             :     }
+   25224             : 
+   25225             : 
+   25226           0 :     z__[(*n << 1) + 1] = trace;
+   25227           0 :     z__[(*n << 1) + 2] = e;
+   25228           0 :     z__[(*n << 1) + 3] = (float) iter;
+   25229           0 :     i__1 = *n;
+   25230           0 :     z__[(*n << 1) + 4] = (float) ndiv / (float) (i__1 * i__1);
+   25231           0 :     z__[(*n << 1) + 5] = nfail * 100. / (float) iter;
+   25232             : 
+   25233           0 :     return;
+   25234             : 
+   25235             : }
+   25236             : 
+   25237             : 
+   25238             : 
+   25239             : }
+   25240             : }
+   25241             : #include <cmath>
+   25242             : #include "real.h"
+   25243             : 
+   25244             : #include "lapack.h"
+   25245             : #include "lapack_limits.h"
+   25246             : 
+   25247             : #include "blas/blas.h"
+   25248             : namespace PLMD{
+   25249             : namespace lapack{
+   25250             : using namespace blas;
+   25251             : void
+   25252           0 : PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(int *i0, 
+   25253             :                         int *n0, 
+   25254             :                         float *z__, 
+   25255             :                         int *pp, 
+   25256             :                         float *dmin__, 
+   25257             :                         float *sigma,
+   25258             :                         float *desig,
+   25259             :                         float *qmax, 
+   25260             :                         int *nfail, 
+   25261             :                         int *iter, 
+   25262             :                         int *ndiv, 
+   25263             :         int *ieee)
+   25264             : {
+   25265             : 
+   25266           0 :     int ttype = 0;
+   25267           0 :     float dmin1 = 0.;
+   25268           0 :     float dmin2 = 0.;
+   25269           0 :     float dn = 0.;
+   25270           0 :     float dn1 = 0.;
+   25271           0 :     float dn2 = 0.;
+   25272           0 :     float tau = 0.;
+   25273             : 
+   25274             :     int i__1;
+   25275             :     float d__1, d__2;
+   25276             :     float s, t;
+   25277             :     int j4, nn;
+   25278             :     float eps, tol;
+   25279             :     int n0in, ipn4;
+   25280             :     float tol2, temp;
+   25281           0 :     --z__;
+   25282             : 
+   25283           0 :     n0in = *n0;
+   25284             :     eps = PLUMED_GMX_FLOAT_EPS;
+   25285             :     tol = eps * 100.;
+   25286             :     d__1 = tol;
+   25287             :     tol2 = d__1 * d__1;
+   25288             : 
+   25289             : 
+   25290           0 : L10:
+   25291             : 
+   25292           0 :     if (*n0 < *i0) {
+   25293             :         return;
+   25294             :     }
+   25295           0 :     if (*n0 == *i0) {
+   25296           0 :         goto L20;
+   25297             :     }
+   25298           0 :     nn = (*n0 << 2) + *pp;
+   25299           0 :     if (*n0 == *i0 + 1) {
+   25300           0 :         goto L40;
+   25301             :     }
+   25302             : 
+   25303           0 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+   25304           0 :             4] > tol2 * z__[nn - 7]) {
+   25305           0 :         goto L30;
+   25306             :     }
+   25307             : 
+   25308           0 : L20:
+   25309             : 
+   25310           0 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+   25311           0 :     --(*n0);
+   25312           0 :     goto L10;
+   25313             : 
+   25314             : L30:
+   25315             : 
+   25316           0 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+   25317           0 :             nn - 11]) {
+   25318           0 :         goto L50;
+   25319             :     }
+   25320             : 
+   25321           0 : L40:
+   25322             : 
+   25323           0 :     if (z__[nn - 3] > z__[nn - 7]) {
+   25324             :         s = z__[nn - 3];
+   25325           0 :         z__[nn - 3] = z__[nn - 7];
+   25326           0 :         z__[nn - 7] = s;
+   25327             :     }
+   25328           0 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+   25329           0 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+   25330           0 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+   25331           0 :         if (s <= t) {
+   25332           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   25333             :         } else {
+   25334           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   25335             :         }
+   25336           0 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+   25337           0 :         z__[nn - 3] *= z__[nn - 7] / t;
+   25338           0 :         z__[nn - 7] = t;
+   25339             :     }
+   25340           0 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+   25341           0 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+   25342           0 :     *n0 += -2;
+   25343           0 :     goto L10;
+   25344             : 
+   25345             : L50:
+   25346           0 :     if (*pp == 2) {
+   25347           0 :         *pp = 0;
+   25348             :     }
+   25349             : 
+   25350           0 :     if (*dmin__ <= 0. || *n0 < n0in) {
+   25351           0 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+   25352           0 :             ipn4 = 4*(*i0 + *n0);
+   25353           0 :             i__1 = 2*(*i0 + *n0 - 1);
+   25354           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25355           0 :                 temp = z__[j4 - 3];
+   25356           0 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+   25357           0 :                 z__[ipn4 - j4 - 3] = temp;
+   25358           0 :                 temp = z__[j4 - 2];
+   25359           0 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+   25360           0 :                 z__[ipn4 - j4 - 2] = temp;
+   25361           0 :                 temp = z__[j4 - 1];
+   25362           0 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+   25363           0 :                 z__[ipn4 - j4 - 5] = temp;
+   25364           0 :                 temp = z__[j4];
+   25365           0 :                 z__[j4] = z__[ipn4 - j4 - 4];
+   25366           0 :                 z__[ipn4 - j4 - 4] = temp;
+   25367             :             }
+   25368           0 :             if (*n0 - *i0 <= 4) {
+   25369           0 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+   25370           0 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+   25371             :             }
+   25372           0 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+   25373           0 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+   25374           0 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+   25375           0 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+   25376           0 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+   25377           0 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+   25378           0 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+   25379           0 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+   25380           0 :             d__1 = *qmax;
+   25381           0 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+   25382           0 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+   25383           0 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+   25384           0 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+   25385           0 :             *dmin__ = -0.;
+   25386             :         }
+   25387             :     }
+   25388             : 
+   25389             : 
+   25390           0 :     PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25391             :             dn2, &tau, &ttype);
+   25392             : 
+   25393           0 : L70:
+   25394             : 
+   25395           0 :     PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25396             :             dn2, ieee);
+   25397             : 
+   25398           0 :     *ndiv += *n0 - *i0 + 2;
+   25399           0 :     ++(*iter);
+   25400             : 
+   25401           0 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+   25402             : 
+   25403           0 :         goto L90;
+   25404             : 
+   25405           0 :     } else if (*dmin__ < 0. && dmin1 > 0. && z__[4*(*n0 - 1) - *pp] < tol *
+   25406           0 :              (*sigma + dn1) && std::abs(dn) < tol * *sigma) {
+   25407             : 
+   25408           0 :         z__[4*(*n0 - 1) - *pp + 2] = 0.;
+   25409           0 :         *dmin__ = 0.;
+   25410           0 :         goto L90;
+   25411           0 :     } else if (*dmin__ < 0.) {
+   25412             : 
+   25413           0 :         ++(*nfail);
+   25414           0 :         if (ttype < -22) {
+   25415             : 
+   25416           0 :             tau = 0.;
+   25417           0 :         } else if (dmin1 > 0.) {
+   25418             : 
+   25419           0 :             tau = (tau + *dmin__) * (1. - eps * 2.);
+   25420           0 :             ttype += -11;
+   25421             :         } else {
+   25422             : 
+   25423           0 :             tau *= .25;
+   25424           0 :             ttype += -12;
+   25425             :         }
+   25426           0 :         goto L70;
+   25427             :     }
+   25428             :     else {
+   25429             :         
+   25430           0 :         goto L80;
+   25431             :     }
+   25432             : 
+   25433             : L80:
+   25434           0 :     PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(i0, n0, &z__[1], pp, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2);
+   25435           0 :     *ndiv += *n0 - *i0 + 2;
+   25436           0 :     ++(*iter);
+   25437           0 :     tau = 0.;
+   25438             : 
+   25439           0 : L90:
+   25440           0 :     if (tau < *sigma) {
+   25441           0 :         *desig += tau;
+   25442           0 :         t = *sigma + *desig;
+   25443           0 :         *desig -= t - *sigma;
+   25444             :     } else {
+   25445           0 :         t = *sigma + tau;
+   25446           0 :         *desig = *sigma - (t - tau) + *desig;
+   25447             :     }
+   25448           0 :     *sigma = t;
+   25449             : 
+   25450           0 :     return;
+   25451             : }
+   25452             : }
+   25453             : }
+   25454             : #include <cmath>
+   25455             : #include "real.h"
+   25456             : 
+   25457             : #include "lapack.h"
+   25458             : 
+   25459             : #include "blas/blas.h"
+   25460             : namespace PLMD{
+   25461             : namespace lapack{
+   25462             : using namespace blas;
+   25463             : void 
+   25464           0 : PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(int *i0, 
+   25465             :         int *n0, 
+   25466             :         float *z__, 
+   25467             :         int *pp, 
+   25468             :         int *n0in, 
+   25469             :         float *dmin__, 
+   25470             :         float *dmin1, 
+   25471             :         float *dmin2, 
+   25472             :         float *dn, 
+   25473             :         float *dn1, 
+   25474             :         float *dn2, 
+   25475             :         float *tau, 
+   25476             :         int *ttype)
+   25477             : {
+   25478             :     float g = 0.;
+   25479             :     int i__1;
+   25480             :     float d__1, d__2;
+   25481             : 
+   25482             :     float s, a2, b1, b2;
+   25483             :     int i4, nn, np;
+   25484             :     float gam, gap1, gap2;
+   25485             : 
+   25486             : 
+   25487           0 :     if (*dmin__ <= 0.) {
+   25488           0 :         *tau = -(*dmin__);
+   25489           0 :         *ttype = -1;
+   25490           0 :         return;
+   25491             :     }
+   25492             : 
+   25493             :     s = 0.0;
+   25494             : 
+   25495           0 :     nn = (*n0 << 2) + *pp;
+   25496           0 :     if (*n0in == *n0) {
+   25497             : 
+   25498           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) ||
+   25499           0 :          std::abs(*dmin__ - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn1)) {
+   25500             : 
+   25501           0 :             b1 =  std::sqrt(z__[nn - 3]) * std::sqrt(z__[nn - 5]);
+   25502           0 :             b2 =  std::sqrt(z__[nn - 7]) * std::sqrt(z__[nn - 9]);
+   25503           0 :             a2 = z__[nn - 7] + z__[nn - 5];
+   25504             : 
+   25505           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) &&
+   25506           0 :              std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25507             : 
+   25508           0 :             gap2 = *dmin2 - a2 - *dmin2 * .25;
+   25509           0 :                 if (gap2 > 0. && gap2 > b2) {
+   25510           0 :                     gap1 = a2 - *dn - b2 / gap2 * b2;
+   25511             :                 } else {
+   25512           0 :                     gap1 = a2 - *dn - (b1 + b2);
+   25513             :                 }
+   25514           0 :                 if (gap1 > 0. && gap1 > b1) {
+   25515           0 :                     d__1 = *dn - b1 / gap1 * b1, d__2 = *dmin__ * .5;
+   25516           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25517           0 :                     *ttype = -2;
+   25518             :                 } else {
+   25519             :                     s = 0.;
+   25520           0 :                     if (*dn > b1) {
+   25521           0 :                         s = *dn - b1;
+   25522             :                     }
+   25523           0 :                     if (a2 > b1 + b2) {
+   25524           0 :                         d__1 = s, d__2 = a2 - (b1 + b2);
+   25525           0 :                         s = (d__1<d__2) ? d__1 : d__2;
+   25526             :                     }
+   25527           0 :                     d__1 = s, d__2 = *dmin__ * .333;
+   25528           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25529           0 :                     *ttype = -3;
+   25530             :                 }
+   25531             :             } else {
+   25532             : 
+   25533             : 
+   25534           0 :                 *ttype = -4;
+   25535           0 :                 s = *dmin__ * .25;
+   25536           0 :                 if (std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn)) {
+   25537             :                     gam = *dn;
+   25538             :                     a2 = 0.;
+   25539           0 :                     if (z__[nn - 5] > z__[nn - 7]) {
+   25540             :                         return;
+   25541             :                     }
+   25542           0 :                     b2 = z__[nn - 5] / z__[nn - 7];
+   25543           0 :                     np = nn - 9;
+   25544             :                 } else {
+   25545           0 :                     np = nn - (*pp << 1);
+   25546           0 :                     gam = *dn1;
+   25547           0 :                     if (z__[np - 4] > z__[np - 2]) {
+   25548             :                         return;
+   25549             :                     }
+   25550           0 :                     a2 = z__[np - 4] / z__[np - 2];
+   25551           0 :                     if (z__[nn - 9] > z__[nn - 11]) {
+   25552             :                         return;
+   25553             :                     }
+   25554           0 :                     b2 = z__[nn - 9] / z__[nn - 11];
+   25555           0 :                     np = nn - 13;
+   25556             :                 }
+   25557             : 
+   25558             : 
+   25559           0 :                 a2 += b2;
+   25560           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25561           0 :                 for (i4 = np; i4 >= i__1; i4 += -4) {
+   25562           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25563           0 :                         goto L20;
+   25564             :                     }
+   25565             :                     b1 = b2;
+   25566           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25567             :                         return;
+   25568             :                     }
+   25569           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25570           0 :                     a2 += b2;
+   25571           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25572           0 :                         goto L20;
+   25573             :                     }
+   25574             :                 }
+   25575           0 : L20:
+   25576           0 :                 a2 *= 1.05;
+   25577             : 
+   25578             : 
+   25579           0 :                 if (a2 < .563) {
+   25580           0 :                     s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25581             :                 }
+   25582             :             }
+   25583           0 :         } else if (std::abs(*dmin__ - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn2)) {
+   25584             : 
+   25585           0 :             *ttype = -5;
+   25586           0 :             s = *dmin__ * .25;
+   25587             : 
+   25588           0 :             np = nn - (*pp << 1);
+   25589           0 :             b1 = z__[np - 2];
+   25590           0 :             b2 = z__[np - 6];
+   25591           0 :             gam = *dn2;
+   25592           0 :             if (z__[np - 8] > b2 || z__[np - 4] > b1) {
+   25593             :                 return;
+   25594             :             }
+   25595           0 :             a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.);
+   25596             : 
+   25597             : 
+   25598           0 :             if (*n0 - *i0 > 2) {
+   25599           0 :                 b2 = z__[nn - 13] / z__[nn - 15];
+   25600           0 :                 a2 += b2;
+   25601           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25602           0 :                 for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
+   25603           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25604           0 :                         goto L40;
+   25605             :                     }
+   25606             :                     b1 = b2;
+   25607           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25608             :                         return;
+   25609             :                     }
+   25610           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25611           0 :                     a2 += b2;
+   25612           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25613           0 :                         goto L40;
+   25614             :                     }
+   25615             :                 }
+   25616           0 : L40:
+   25617           0 :                 a2 *= 1.05;
+   25618             :             }
+   25619             : 
+   25620           0 :             if (a2 < .563) {
+   25621           0 :                 s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25622             :             }
+   25623             :         } else {
+   25624             : 
+   25625           0 :             if (*ttype == -6) {
+   25626             :                 g += (1. - g) * .333;
+   25627           0 :             } else if (*ttype == -18) {
+   25628             :                 g = .083250000000000005;
+   25629             :             } else {
+   25630             :                 g = .25;
+   25631             :             }
+   25632           0 :             s = g * *dmin__;
+   25633           0 :             *ttype = -6;
+   25634             :         }
+   25635             : 
+   25636           0 :     } else if (*n0in == *n0 + 1) {
+   25637             : 
+   25638           0 :         if ( std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1) &&
+   25639           0 :              std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2)) {
+   25640             : 
+   25641           0 :             *ttype = -7;
+   25642           0 :             s = *dmin1 * .333;
+   25643           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25644             :                 return;
+   25645             :             }
+   25646           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25647             :             b2 = b1;
+   25648           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25649           0 :                 goto L60;
+   25650             :             }
+   25651           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25652           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25653             :                 a2 = b1;
+   25654           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25655             :                     return;
+   25656             :                 }
+   25657           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25658           0 :                 b2 += b1;
+   25659           0 :                 if (((a2>b1) ? a2 : b1) * 100. < b2) {
+   25660           0 :                     goto L60;
+   25661             :                 }
+   25662             :             }
+   25663           0 : L60:
+   25664           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25665             :             d__1 = b2;
+   25666           0 :             a2 = *dmin1 / (d__1 * d__1 + 1.);
+   25667           0 :             gap2 = *dmin2 * .5 - a2;
+   25668           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25669           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25670           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25671             :             } else {
+   25672           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25673           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25674           0 :                 *ttype = -8;
+   25675             :             }
+   25676             :         } else {
+   25677             : 
+   25678           0 :             s = *dmin1 * .25;
+   25679           0 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25680           0 :                 s = *dmin1 * .5;
+   25681             :             }
+   25682           0 :             *ttype = -9;
+   25683             :         }
+   25684             : 
+   25685           0 :     } else if (*n0in == *n0 + 2) {
+   25686             : 
+   25687           0 :         if (std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2) &&
+   25688           0 :         z__[nn - 5] * 2. < z__[nn - 7]) {
+   25689           0 :             *ttype = -10;
+   25690           0 :             s = *dmin2 * .333;
+   25691           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25692             :                 return;
+   25693             :             }
+   25694           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25695             :             b2 = b1;
+   25696           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25697           0 :                 goto L80;
+   25698             :             }
+   25699           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25700           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25701           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25702             :                     return;
+   25703             :                 }
+   25704           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25705           0 :                 b2 += b1;
+   25706           0 :                 if (b1 * 100. < b2) {
+   25707           0 :                     goto L80;
+   25708             :                 }
+   25709             :             }
+   25710           0 : L80:
+   25711           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25712             :             d__1 = b2;
+   25713           0 :             a2 = *dmin2 / (d__1 * d__1 + 1.);
+   25714           0 :             gap2 = z__[nn - 7] + z__[nn - 9] -  std::sqrt(z__[nn - 11]) * std::sqrt(z__[
+   25715             :                     nn - 9]) - a2;
+   25716           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25717           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25718           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25719             :             } else {
+   25720           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25721           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25722             :             }
+   25723             :         } else {
+   25724           0 :             s = *dmin2 * .25;
+   25725           0 :             *ttype = -11;
+   25726             :         }
+   25727           0 :     } else if (*n0in > *n0 + 2) {
+   25728             : 
+   25729             :         s = 0.;
+   25730           0 :         *ttype = -12;
+   25731             :     }
+   25732             : 
+   25733           0 :     *tau = s;
+   25734           0 :     return;
+   25735             : 
+   25736             : }
+   25737             : 
+   25738             : 
+   25739             : }
+   25740             : }
+   25741             : #include <cmath>
+   25742             : #include "lapack.h"
+   25743             : 
+   25744             : #include "blas/blas.h"
+   25745             : namespace PLMD{
+   25746             : namespace lapack{
+   25747             : using namespace blas;
+   25748             : void
+   25749           0 : PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(int *i0, 
+   25750             :         int *n0,
+   25751             :         float *z__, 
+   25752             :         int *pp, 
+   25753             :         float *tau,
+   25754             :         float *dmin__, 
+   25755             :         float *dmin1, 
+   25756             :         float *dmin2, 
+   25757             :         float *dn,
+   25758             :         float *dnm1, 
+   25759             :         float *dnm2,
+   25760             :         int *ieee)
+   25761             : {
+   25762             :     int i__1;
+   25763             :     float d__1, d__2;
+   25764             : 
+   25765             :     float d__;
+   25766             :     int j4, j4p2;
+   25767             :     float emin, temp;
+   25768             : 
+   25769           0 :     --z__;
+   25770             : 
+   25771           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25772             :         return;
+   25773             :     }
+   25774             : 
+   25775           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25776           0 :     emin = z__[j4 + 4];
+   25777           0 :     d__ = z__[j4] - *tau;
+   25778           0 :     *dmin__ = d__;
+   25779           0 :     *dmin1 = -z__[j4];
+   25780             : 
+   25781           0 :     if (*ieee) {
+   25782             : 
+   25783           0 :         if (*pp == 0) {
+   25784           0 :             i__1 = 4*(*n0 - 3);
+   25785           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25786           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25787           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25788           0 :                 d__ = d__ * temp - *tau;
+   25789           0 :                 if(d__<*dmin__)
+   25790           0 :                   *dmin__ = d__;
+   25791           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25792             :                 d__1 = z__[j4];
+   25793           0 :                 if(d__1<emin)
+   25794             :                   emin = d__1;
+   25795             :             }
+   25796             :         } else {
+   25797           0 :             i__1 = 4*(*n0 - 3);
+   25798           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25799           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25800           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25801           0 :                 d__ = d__ * temp - *tau;
+   25802           0 :                 if(d__<*dmin__)
+   25803           0 :                   *dmin__ = d__;
+   25804           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25805             :                 d__1 = z__[j4 - 1];
+   25806           0 :                 if(d__1<emin)
+   25807             :                   emin = d__1;
+   25808             :             }
+   25809             :         }
+   25810             : 
+   25811           0 :         *dnm2 = d__;
+   25812           0 :         *dmin2 = *dmin__;
+   25813           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25814           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25815           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25816           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25817           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25818           0 :         if(*dnm1<*dmin__)
+   25819           0 :           *dmin__ = *dnm1;
+   25820             : 
+   25821           0 :         *dmin1 = *dmin__;
+   25822           0 :         j4 += 4;
+   25823           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25824           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25825           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25826           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25827           0 :         if(*dn<*dmin__)
+   25828           0 :           *dmin__ = *dn;
+   25829             : 
+   25830             :     } else {
+   25831             : 
+   25832           0 :         if (*pp == 0) {
+   25833           0 :             i__1 = 4*(*n0 - 3);
+   25834           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25835           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25836           0 :                 if (d__ < 0.) {
+   25837             :                     return;
+   25838             :                 } else {
+   25839           0 :                     z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25840           0 :                     d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]) - *tau;
+   25841             :                 }
+   25842           0 :                 if(d__<*dmin__)
+   25843           0 :                   *dmin__ = d__;
+   25844           0 :                 d__1 = emin, d__2 = z__[j4];
+   25845           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25846             :             }
+   25847             :         } else {
+   25848           0 :             i__1 = 4*(*n0 - 3);
+   25849           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25850           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25851           0 :                 if (d__ < 0.) {
+   25852             :                     return;
+   25853             :                 } else {
+   25854           0 :                     z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25855           0 :                     d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]) - *tau;
+   25856             :                 }
+   25857           0 :                 if(d__<*dmin__)
+   25858           0 :                   *dmin__ = d__;
+   25859           0 :                 d__1 = emin, d__2 = z__[j4 - 1];
+   25860           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25861             :             }
+   25862             :         }
+   25863             : 
+   25864           0 :         *dnm2 = d__;
+   25865           0 :         *dmin2 = *dmin__;
+   25866           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25867           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25868           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25869           0 :         if (*dnm2 < 0.) {
+   25870             :             return;
+   25871             :         } else {
+   25872           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25873           0 :             *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25874             :         }
+   25875           0 :         if(*dnm1<*dmin__)
+   25876           0 :           *dmin__ = *dnm1;
+   25877             : 
+   25878           0 :         *dmin1 = *dmin__;
+   25879           0 :         j4 += 4;
+   25880           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25881           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25882           0 :         if (*dnm1 < 0.) {
+   25883             :             return;
+   25884             :         } else {
+   25885           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25886           0 :             *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25887             :         }
+   25888           0 :         if(*dn<*dmin__)
+   25889           0 :           *dmin__ = *dn;
+   25890             : 
+   25891             :     }
+   25892             : 
+   25893           0 :     z__[j4 + 2] = *dn;
+   25894           0 :     z__[(*n0 << 2) - *pp] = emin;
+   25895           0 :     return;
+   25896             : 
+   25897             : }
+   25898             : 
+   25899             : }
+   25900             : }
+   25901             : #include <cmath>
+   25902             : #include "lapack.h"
+   25903             : #include "lapack_limits.h"
+   25904             : 
+   25905             : #include "real.h"
+   25906             : 
+   25907             : #include "blas/blas.h"
+   25908             : namespace PLMD{
+   25909             : namespace lapack{
+   25910             : using namespace blas;
+   25911             : void 
+   25912           0 : PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(int *i0, 
+   25913             :         int *n0, 
+   25914             :         float *z__, 
+   25915             :         int *pp, 
+   25916             :         float *dmin__, 
+   25917             :         float *dmin1, 
+   25918             :         float *dmin2,
+   25919             :         float *dn, 
+   25920             :         float *dnm1, 
+   25921             :         float *dnm2)
+   25922             : {
+   25923             :     int i__1;
+   25924             :     float d__1, d__2;
+   25925             : 
+   25926             :     /* Local variables */
+   25927             :     float d__;
+   25928             :     int j4, j4p2;
+   25929             :     float emin, temp;
+   25930             :     const float safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   25931             : 
+   25932           0 :     --z__;
+   25933             : 
+   25934           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25935             :         return;
+   25936             :     }
+   25937             : 
+   25938           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25939           0 :     emin = z__[j4 + 4];
+   25940           0 :     d__ = z__[j4];
+   25941           0 :     *dmin__ = d__;
+   25942             : 
+   25943           0 :     if (*pp == 0) {
+   25944           0 :         i__1 = 4*(*n0 - 3);
+   25945           0 :         for (j4 = *i0*4; j4 <= i__1; j4 += 4) {
+   25946           0 :             z__[j4 - 2] = d__ + z__[j4 - 1];
+   25947           0 :             if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25948           0 :                 z__[j4] = 0.;
+   25949           0 :                 d__ = z__[j4 + 1];
+   25950           0 :                 *dmin__ = d__;
+   25951             :                 emin = 0.;
+   25952           0 :             } else if (safemin * z__[j4 + 1] < z__[j4 - 2] && safemin * z__[j4 
+   25953             :                     - 2] < z__[j4 + 1]) {
+   25954           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25955           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25956           0 :                 d__ *= temp;
+   25957             :             } else {
+   25958           0 :                 z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25959           0 :                 d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]);
+   25960             :             }
+   25961           0 :             if(d__<*dmin__)
+   25962           0 :               *dmin__ = d__;
+   25963             : 
+   25964           0 :             d__1 = emin, d__2 = z__[j4];
+   25965           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25966             :         }
+   25967             :     } else {
+   25968           0 :         i__1 = 4*(*n0 - 3);
+   25969           0 :         for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25970           0 :             z__[j4 - 3] = d__ + z__[j4];
+   25971           0 :             if (std::abs(z__[j4 - 3])<PLUMED_GMX_FLOAT_MIN) {
+   25972           0 :                 z__[j4 - 1] = 0.;
+   25973           0 :                 d__ = z__[j4 + 2];
+   25974           0 :                 *dmin__ = d__;
+   25975             :                 emin = 0.;
+   25976           0 :             } else if (safemin * z__[j4 + 2] < z__[j4 - 3] && safemin * z__[j4 
+   25977             :                     - 3] < z__[j4 + 2]) {
+   25978           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25979           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25980           0 :                 d__ *= temp;
+   25981             :             } else {
+   25982           0 :                 z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25983           0 :                 d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]);
+   25984             :             }
+   25985           0 :             if(d__<*dmin__)
+   25986           0 :               *dmin__ = d__;
+   25987           0 :             d__1 = emin, d__2 = z__[j4 - 1];
+   25988           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25989             :         }
+   25990             :     }
+   25991             : 
+   25992           0 :     *dnm2 = d__;
+   25993           0 :     *dmin2 = *dmin__;
+   25994           0 :     j4 = 4*(*n0 - 2) - *pp;
+   25995           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   25996           0 :     z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25997           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25998           0 :         z__[j4] = 0.;
+   25999           0 :         *dnm1 = z__[j4p2 + 2];
+   26000           0 :         *dmin__ = *dnm1;
+   26001             :         emin = 0.;
+   26002           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26003             :             z__[j4p2 + 2]) {
+   26004           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26005           0 :         z__[j4] = z__[j4p2] * temp;
+   26006           0 :         *dnm1 = *dnm2 * temp;
+   26007             :     } else {
+   26008           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26009           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]);
+   26010             :     }
+   26011           0 :     if(*dnm1<*dmin__)
+   26012           0 :       *dmin__ = *dnm1;
+   26013             : 
+   26014           0 :     *dmin1 = *dmin__;
+   26015           0 :     j4 += 4;
+   26016           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   26017           0 :     z__[j4 - 2] = *dnm1 + z__[j4p2];
+   26018           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   26019           0 :         z__[j4] = 0.;
+   26020           0 :         *dn = z__[j4p2 + 2];
+   26021           0 :         *dmin__ = *dn;
+   26022             :         emin = 0.;
+   26023           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26024             :             z__[j4p2 + 2]) {
+   26025           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26026           0 :         z__[j4] = z__[j4p2] * temp;
+   26027           0 :         *dn = *dnm1 * temp;
+   26028             :     } else {
+   26029           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26030           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]);
+   26031             :     }
+   26032           0 :     if(*dn<*dmin__)
+   26033           0 :       *dmin__ = *dn;
+   26034             : 
+   26035           0 :     z__[j4 + 2] = *dn;
+   26036           0 :     z__[(*n0 << 2) - *pp] = emin;
+   26037           0 :     return;
+   26038             : 
+   26039             : 
+   26040             : } 
+   26041             : }
+   26042             : }
+   26043             : #include <cmath>
+   26044             : 
+   26045             : #include "real.h"
+   26046             : #include "lapack.h"
+   26047             : 
+   26048             : #include "blas/blas.h"
+   26049             : namespace PLMD{
+   26050             : namespace lapack{
+   26051             : using namespace blas;
+   26052             : void 
+   26053           0 : PLUMED_BLAS_F77_FUNC(slasr,SLASR)(const char *side, 
+   26054             :        const char *pivot, 
+   26055             :        const char *direct, 
+   26056             :        int *m,
+   26057             :        int *n, 
+   26058             :        float *c__, 
+   26059             :        float *s, 
+   26060             :        float *a, 
+   26061             :        int *lda)
+   26062             : {
+   26063             :     /* System generated locals */
+   26064             :     int a_dim1, a_offset, i__1, i__2;
+   26065             : 
+   26066             :     /* Local variables */
+   26067             :     int i__, j;
+   26068             :     float temp;
+   26069             :     float ctemp, stemp;
+   26070             : 
+   26071           0 :     --c__;
+   26072           0 :     --s;
+   26073           0 :     a_dim1 = *lda;
+   26074           0 :     a_offset = 1 + a_dim1;
+   26075           0 :     a -= a_offset;
+   26076             : 
+   26077             :     /* Function Body */
+   26078             : 
+   26079           0 :     if (*m == 0 || *n == 0) {
+   26080             :         return;
+   26081             :     }
+   26082           0 :     if (*side=='L' || *side=='l') {
+   26083             : 
+   26084           0 :         if (*pivot=='V' || *pivot=='v') {
+   26085           0 :             if (*direct=='F' || *direct=='f') {
+   26086             :                 i__1 = *m - 1;
+   26087           0 :                 for (j = 1; j <= i__1; ++j) {
+   26088           0 :                     ctemp = c__[j];
+   26089           0 :                     stemp = s[j];
+   26090           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26091           0 :                         i__2 = *n;
+   26092           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26093           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26094           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26095           0 :                                     a[j + i__ * a_dim1];
+   26096           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26097           0 :                                     + i__ * a_dim1];
+   26098             :                         }
+   26099             :                     }
+   26100             :                 }
+   26101           0 :             } else if (*direct=='B' || *direct=='b') {
+   26102           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26103           0 :                     ctemp = c__[j];
+   26104           0 :                     stemp = s[j];
+   26105           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26106           0 :                         i__1 = *n;
+   26107           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26108           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26109           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26110           0 :                                     a[j + i__ * a_dim1];
+   26111           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26112           0 :                                     + i__ * a_dim1];
+   26113             :                         }
+   26114             :                     }
+   26115             :                 }
+   26116             :             }
+   26117           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26118           0 :             if (*direct=='F' || *direct=='f') {
+   26119             :                 i__1 = *m;
+   26120           0 :                 for (j = 2; j <= i__1; ++j) {
+   26121           0 :                     ctemp = c__[j - 1];
+   26122           0 :                     stemp = s[j - 1];
+   26123           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26124           0 :                         i__2 = *n;
+   26125           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26126           0 :                             temp = a[j + i__ * a_dim1];
+   26127           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26128           0 :                                     i__ * a_dim1 + 1];
+   26129           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26130           0 :                                     i__ * a_dim1 + 1];
+   26131             :                         }
+   26132             :                     }
+   26133             :                 }
+   26134           0 :             } else if (*direct=='B' || *direct=='b') {
+   26135           0 :                 for (j = *m; j >= 2; --j) {
+   26136           0 :                     ctemp = c__[j - 1];
+   26137           0 :                     stemp = s[j - 1];
+   26138           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26139           0 :                         i__1 = *n;
+   26140           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26141           0 :                             temp = a[j + i__ * a_dim1];
+   26142           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26143           0 :                                     i__ * a_dim1 + 1];
+   26144           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26145           0 :                                     i__ * a_dim1 + 1];
+   26146             :                         }
+   26147             :                     }
+   26148             :                 }
+   26149             :             }
+   26150           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26151           0 :             if (*direct=='F' || *direct=='f') {
+   26152             :                 i__1 = *m - 1;
+   26153           0 :                 for (j = 1; j <= i__1; ++j) {
+   26154           0 :                     ctemp = c__[j];
+   26155           0 :                     stemp = s[j];
+   26156           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26157           0 :                         i__2 = *n;
+   26158           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26159           0 :                             temp = a[j + i__ * a_dim1];
+   26160           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26161           0 :                                      + ctemp * temp;
+   26162           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26163           0 :                                     a_dim1] - stemp * temp;
+   26164             :                         }
+   26165             :                     }
+   26166             :                 }
+   26167           0 :             } else if (*direct=='B' || *direct=='b') {
+   26168           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26169           0 :                     ctemp = c__[j];
+   26170           0 :                     stemp = s[j];
+   26171           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26172           0 :                         i__1 = *n;
+   26173           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26174           0 :                             temp = a[j + i__ * a_dim1];
+   26175           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26176           0 :                                      + ctemp * temp;
+   26177           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26178           0 :                                     a_dim1] - stemp * temp;
+   26179             :                         }
+   26180             :                     }
+   26181             :                 }
+   26182             :             }
+   26183             :         }
+   26184           0 :     } else if (*side=='R' || *side=='r') {
+   26185             : 
+   26186           0 :         if (*pivot=='V' || *pivot=='v') {
+   26187           0 :             if (*direct=='F' || *direct=='f') {
+   26188             :                 i__1 = *n - 1;
+   26189           0 :                 for (j = 1; j <= i__1; ++j) {
+   26190           0 :                     ctemp = c__[j];
+   26191           0 :                     stemp = s[j];
+   26192           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26193           0 :                         i__2 = *m;
+   26194           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26195           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26196           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26197           0 :                                      a[i__ + j * a_dim1];
+   26198           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26199           0 :                                     i__ + j * a_dim1];
+   26200             :                         }
+   26201             :                     }
+   26202             :                 }
+   26203           0 :             } else if (*direct=='B' || *direct=='b') {
+   26204           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26205           0 :                     ctemp = c__[j];
+   26206           0 :                     stemp = s[j];
+   26207           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26208           0 :                         i__1 = *m;
+   26209           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26210           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26211           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26212           0 :                                      a[i__ + j * a_dim1];
+   26213           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26214           0 :                                     i__ + j * a_dim1];
+   26215             :                         }
+   26216             :                     }
+   26217             :                 }
+   26218             :             }
+   26219           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26220           0 :             if (*direct=='F' || *direct=='f') {
+   26221             :                 i__1 = *n;
+   26222           0 :                 for (j = 2; j <= i__1; ++j) {
+   26223           0 :                     ctemp = c__[j - 1];
+   26224           0 :                     stemp = s[j - 1];
+   26225           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26226           0 :                         i__2 = *m;
+   26227           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26228           0 :                             temp = a[i__ + j * a_dim1];
+   26229           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26230           0 :                                     i__ + a_dim1];
+   26231           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26232           0 :                                     a_dim1];
+   26233             :                         }
+   26234             :                     }
+   26235             :                 }
+   26236           0 :             } else if (*direct=='B' || *direct=='b') {
+   26237           0 :                 for (j = *n; j >= 2; --j) {
+   26238           0 :                     ctemp = c__[j - 1];
+   26239           0 :                     stemp = s[j - 1];
+   26240           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26241           0 :                         i__1 = *m;
+   26242           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26243           0 :                             temp = a[i__ + j * a_dim1];
+   26244           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26245           0 :                                     i__ + a_dim1];
+   26246           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26247           0 :                                     a_dim1];
+   26248             :                         }
+   26249             :                     }
+   26250             :                 }
+   26251             :             }
+   26252           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26253           0 :             if (*direct=='F' || *direct=='f') {
+   26254             :                 i__1 = *n - 1;
+   26255           0 :                 for (j = 1; j <= i__1; ++j) {
+   26256           0 :                     ctemp = c__[j];
+   26257           0 :                     stemp = s[j];
+   26258           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26259           0 :                         i__2 = *m;
+   26260           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26261           0 :                             temp = a[i__ + j * a_dim1];
+   26262           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26263           0 :                                      + ctemp * temp;
+   26264           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26265           0 :                                     a_dim1] - stemp * temp;
+   26266             :                         }
+   26267             :                     }
+   26268             :                 }
+   26269           0 :             } else if (*direct=='B' || *direct=='b') {
+   26270           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26271           0 :                     ctemp = c__[j];
+   26272           0 :                     stemp = s[j];
+   26273           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26274           0 :                         i__1 = *m;
+   26275           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26276           0 :                             temp = a[i__ + j * a_dim1];
+   26277           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26278           0 :                                      + ctemp * temp;
+   26279           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26280           0 :                                     a_dim1] - stemp * temp;
+   26281             :                         }
+   26282             :                     }
+   26283             :                 }
+   26284             :             }
+   26285             :         }
+   26286             :     }
+   26287             : 
+   26288             :     return;
+   26289             : 
+   26290             : }
+   26291             : 
+   26292             : 
+   26293             : }
+   26294             : }
+   26295             : #include "lapack.h"
+   26296             : 
+   26297             : #include "blas/blas.h"
+   26298             : namespace PLMD{
+   26299             : namespace lapack{
+   26300             : using namespace blas;
+   26301             : void 
+   26302           0 : PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)(const char *id, 
+   26303             :         int *n, 
+   26304             :         float *d__, 
+   26305             :         int *info)
+   26306             : {
+   26307             :     int i__1, i__2;
+   26308             : 
+   26309             :     int i__, j;
+   26310             :     float d1, d2, d3;
+   26311             :     int dir;
+   26312             :     float tmp;
+   26313             :     int endd;
+   26314             :     int stack[64];
+   26315             :     float dmnmx;
+   26316             :     int start;
+   26317             :     int stkpnt;
+   26318             : 
+   26319           0 :     --d__;
+   26320             : 
+   26321           0 :     *info = 0;
+   26322             :     dir = -1;
+   26323           0 :     if (*id=='D' || *id=='d') 
+   26324             :         dir = 0;
+   26325           0 :     else if (*id=='I' || *id=='i') 
+   26326             :         dir = 1;
+   26327             :    
+   26328             :     if (dir == -1) {
+   26329           0 :         *info = -1;
+   26330           0 :     } else if (*n < 0) {
+   26331           0 :         *info = -2;
+   26332             :     }
+   26333           0 :     if (*info != 0) {
+   26334             :         return;
+   26335             :     }
+   26336           0 :     if (*n <= 1) {
+   26337             :         return;
+   26338             :     }
+   26339             : 
+   26340             :     stkpnt = 1;
+   26341           0 :     stack[0] = 1;
+   26342           0 :     stack[1] = *n;
+   26343           0 : L10:
+   26344           0 :     start = stack[(stkpnt << 1) - 2];
+   26345           0 :     endd = stack[(stkpnt << 1) - 1];
+   26346           0 :     --stkpnt;
+   26347           0 :     if (endd - start <= 20 && endd - start > 0) {
+   26348             : 
+   26349             : 
+   26350           0 :         if (dir == 0) {
+   26351             : 
+   26352             :             i__1 = endd;
+   26353           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26354             :                 i__2 = start + 1;
+   26355           0 :                 for (j = i__; j >= i__2; --j) {
+   26356           0 :                     if (d__[j] > d__[j - 1]) {
+   26357             :                         dmnmx = d__[j];
+   26358           0 :                         d__[j] = d__[j - 1];
+   26359           0 :                         d__[j - 1] = dmnmx;
+   26360             :                     } else {
+   26361           0 :                         goto L30;
+   26362             :                     }
+   26363             :                 }
+   26364           0 : L30:
+   26365             :                 ;
+   26366             :             }
+   26367             : 
+   26368             :         } else {
+   26369             : 
+   26370             :             i__1 = endd;
+   26371           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26372             :                 i__2 = start + 1;
+   26373           0 :                 for (j = i__; j >= i__2; --j) {
+   26374           0 :                     if (d__[j] < d__[j - 1]) {
+   26375             :                         dmnmx = d__[j];
+   26376           0 :                         d__[j] = d__[j - 1];
+   26377           0 :                         d__[j - 1] = dmnmx;
+   26378             :                     } else {
+   26379           0 :                         goto L50;
+   26380             :                     }
+   26381             :                 }
+   26382           0 : L50:
+   26383             :                 ;
+   26384             :             }
+   26385             : 
+   26386             :         }
+   26387             : 
+   26388           0 :     } else if (endd - start > 20) {
+   26389             : 
+   26390           0 :         d1 = d__[start];
+   26391           0 :         d2 = d__[endd];
+   26392           0 :         i__ = (start + endd) / 2;
+   26393           0 :         d3 = d__[i__];
+   26394           0 :         if (d1 < d2) {
+   26395           0 :             if (d3 < d1) {
+   26396             :                 dmnmx = d1;
+   26397           0 :             } else if (d3 < d2) {
+   26398             :                 dmnmx = d3;
+   26399             :             } else {
+   26400             :                 dmnmx = d2;
+   26401             :             }
+   26402             :         } else {
+   26403           0 :             if (d3 < d2) {
+   26404             :                 dmnmx = d2;
+   26405           0 :             } else if (d3 < d1) {
+   26406             :                 dmnmx = d3;
+   26407             :             } else {
+   26408             :                 dmnmx = d1;
+   26409             :             }
+   26410             :         }
+   26411             : 
+   26412           0 :         if (dir == 0) {
+   26413             : 
+   26414           0 :             i__ = start - 1;
+   26415           0 :             j = endd + 1;
+   26416           0 : L60:
+   26417           0 : L70:
+   26418           0 :             --j;
+   26419           0 :             if (d__[j] < dmnmx) {
+   26420           0 :                 goto L70;
+   26421             :             }
+   26422           0 : L80:
+   26423           0 :             ++i__;
+   26424           0 :             if (d__[i__] > dmnmx) {
+   26425           0 :                 goto L80;
+   26426             :             }
+   26427           0 :             if (i__ < j) {
+   26428             :                 tmp = d__[i__];
+   26429           0 :                 d__[i__] = d__[j];
+   26430           0 :                 d__[j] = tmp;
+   26431           0 :                 goto L60;
+   26432             :             }
+   26433           0 :             if (j - start > endd - j - 1) {
+   26434             :                 ++stkpnt;
+   26435             :                 stack[(stkpnt << 1) - 2] = start;
+   26436           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26437           0 :                 ++stkpnt;
+   26438           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26439           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26440             :             } else {
+   26441             :                 ++stkpnt;
+   26442           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26443           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26444           0 :                 ++stkpnt;
+   26445           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26446           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26447             :             }
+   26448             :         } else {
+   26449             : 
+   26450           0 :             i__ = start - 1;
+   26451           0 :             j = endd + 1;
+   26452           0 : L90:
+   26453           0 : L100:
+   26454           0 :             --j;
+   26455           0 :             if (d__[j] > dmnmx) {
+   26456           0 :                 goto L100;
+   26457             :             }
+   26458           0 : L110:
+   26459           0 :             ++i__;
+   26460           0 :             if (d__[i__] < dmnmx) {
+   26461           0 :                 goto L110;
+   26462             :             }
+   26463           0 :             if (i__ < j) {
+   26464             :                 tmp = d__[i__];
+   26465           0 :                 d__[i__] = d__[j];
+   26466           0 :                 d__[j] = tmp;
+   26467           0 :                 goto L90;
+   26468             :             }
+   26469           0 :             if (j - start > endd - j - 1) {
+   26470             :                 ++stkpnt;
+   26471             :                 stack[(stkpnt << 1) - 2] = start;
+   26472           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26473           0 :                 ++stkpnt;
+   26474           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26475           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26476             :             } else {
+   26477             :                 ++stkpnt;
+   26478           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26479           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26480           0 :                 ++stkpnt;
+   26481           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26482           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26483             :             }
+   26484             :         }
+   26485             :     }
+   26486           0 :     if (stkpnt > 0) {
+   26487           0 :         goto L10;
+   26488             :     }
+   26489             :     return;
+   26490             : 
+   26491             : }
+   26492             : }
+   26493             : }
+   26494             : #include "lapack.h"
+   26495             : #include "blas/blas.h"
+   26496             : namespace PLMD{
+   26497             : namespace lapack{
+   26498             : using namespace blas;
+   26499             : 
+   26500           0 : void PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)(const char *id, 
+   26501             :               int *n, 
+   26502             :               float *d__, 
+   26503             :               int * key, 
+   26504             :               int *info)
+   26505             : {
+   26506             :     int i__1, i__2;
+   26507             : 
+   26508             :     int i__, j;
+   26509             :     float d1, d2, d3;
+   26510             :     int dir;
+   26511             :     float tmp;
+   26512             :     int endd;
+   26513             :     int stack[64];
+   26514             :     float dmnmx;
+   26515             :     int start;
+   26516             :     int tmpkey, stkpnt;
+   26517             : 
+   26518           0 :     --key;
+   26519           0 :     --d__;
+   26520             : 
+   26521           0 :     *info = 0;
+   26522             :     dir = -1;
+   26523           0 :     if (*id=='D' || *id=='d')
+   26524             :         dir = 0;
+   26525           0 :     else if (*id=='I' || *id=='i')
+   26526             :         dir = 1;
+   26527             :     
+   26528             :     if (dir == -1) {
+   26529           0 :         *info = -1;
+   26530           0 :     } else if (*n < 0) {
+   26531           0 :         *info = -2;
+   26532             :     }
+   26533           0 :     if (*info != 0) {
+   26534             :         return;
+   26535             :     }
+   26536             : 
+   26537           0 :     if (*n <= 1) {
+   26538             :         return;
+   26539             :     }
+   26540             : 
+   26541             :     stkpnt = 1;
+   26542           0 :     stack[0] = 1;
+   26543           0 :     stack[1] = *n;
+   26544           0 : L10:
+   26545           0 :     start = stack[(stkpnt << 1) - 2];
+   26546           0 :     endd = stack[(stkpnt << 1) - 1];
+   26547           0 :     --stkpnt;
+   26548           0 :     if (endd - start > 0) {
+   26549             : 
+   26550           0 :         if (dir == 0) {
+   26551             : 
+   26552             :             i__1 = endd;
+   26553           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26554             :                 i__2 = start + 1;
+   26555           0 :                 for (j = i__; j >= i__2; --j) {
+   26556           0 :                     if (d__[j] > d__[j - 1]) {
+   26557             :                         dmnmx = d__[j];
+   26558           0 :                         d__[j] = d__[j - 1];
+   26559           0 :                         d__[j - 1] = dmnmx;
+   26560           0 :                         tmpkey = key[j];
+   26561           0 :                         key[j] = key[j - 1];
+   26562           0 :                         key[j - 1] = tmpkey;
+   26563             :                     } else {
+   26564             :                         break;
+   26565             :                     }
+   26566             :                 }
+   26567             :             }
+   26568             : 
+   26569             :         } else {
+   26570             : 
+   26571             :             i__1 = endd;
+   26572           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26573             :                 i__2 = start + 1;
+   26574           0 :                 for (j = i__; j >= i__2; --j) {
+   26575           0 :                     if (d__[j] < d__[j - 1]) {
+   26576             :                         dmnmx = d__[j];
+   26577           0 :                         d__[j] = d__[j - 1];
+   26578           0 :                         d__[j - 1] = dmnmx;
+   26579           0 :                         tmpkey = key[j];
+   26580           0 :                         key[j] = key[j - 1];
+   26581           0 :                         key[j - 1] = tmpkey;
+   26582             :                     } else {
+   26583             :                         break;
+   26584             :                     }
+   26585             :                 }
+   26586             :             }
+   26587             : 
+   26588             :         }
+   26589             : 
+   26590           0 :     } else if (endd - start > 20) {
+   26591             : 
+   26592           0 :         d1 = d__[start];
+   26593           0 :         d2 = d__[endd];
+   26594           0 :         i__ = (start + endd) / 2;
+   26595           0 :         d3 = d__[i__];
+   26596           0 :         if (d1 < d2) {
+   26597           0 :             if (d3 < d1) {
+   26598             :                 dmnmx = d1;
+   26599           0 :             } else if (d3 < d2) {
+   26600             :                 dmnmx = d3;
+   26601             :             } else {
+   26602             :                 dmnmx = d2;
+   26603             :             }
+   26604             :         } else {
+   26605           0 :             if (d3 < d2) {
+   26606             :                 dmnmx = d2;
+   26607           0 :             } else if (d3 < d1) {
+   26608             :                 dmnmx = d3;
+   26609             :             } else {
+   26610             :                 dmnmx = d1;
+   26611             :             }
+   26612             :         }
+   26613             : 
+   26614           0 :         if (dir == 0) {
+   26615             : 
+   26616           0 :             i__ = start - 1;
+   26617           0 :             j = endd + 1;
+   26618           0 : L60:
+   26619           0 : L70:
+   26620           0 :             --j;
+   26621           0 :             if (d__[j] < dmnmx) {
+   26622           0 :                 goto L70;
+   26623             :             }
+   26624           0 : L80:
+   26625           0 :             ++i__;
+   26626           0 :             if (d__[i__] > dmnmx) {
+   26627           0 :                 goto L80;
+   26628             :             }
+   26629           0 :             if (i__ < j) {
+   26630             :                 tmp = d__[i__];
+   26631           0 :                 d__[i__] = d__[j];
+   26632           0 :                 d__[j] = tmp;
+   26633           0 :                 tmpkey = key[j];
+   26634           0 :                 key[j] = key[i__];
+   26635           0 :                 key[i__] = tmpkey;
+   26636           0 :                 goto L60;
+   26637             :             }
+   26638           0 :             if (j - start > endd - j - 1) {
+   26639             :                 ++stkpnt;
+   26640             :                 stack[(stkpnt << 1) - 2] = start;
+   26641           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26642           0 :                 ++stkpnt;
+   26643           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26644           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26645             :             } else {
+   26646             :                 ++stkpnt;
+   26647           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26648           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26649           0 :                 ++stkpnt;
+   26650           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26651           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26652             :             }
+   26653             :         } else {
+   26654             : 
+   26655           0 :             i__ = start - 1;
+   26656           0 :             j = endd + 1;
+   26657           0 : L90:
+   26658           0 : L100:
+   26659           0 :             --j;
+   26660           0 :             if (d__[j] > dmnmx) {
+   26661           0 :                 goto L100;
+   26662             :             }
+   26663           0 : L110:
+   26664           0 :             ++i__;
+   26665           0 :             if (d__[i__] < dmnmx) {
+   26666           0 :                 goto L110;
+   26667             :             }
+   26668           0 :             if (i__ < j) {
+   26669             :                 tmp = d__[i__];
+   26670           0 :                 d__[i__] = d__[j];
+   26671           0 :                 d__[j] = tmp;
+   26672           0 :                 tmpkey = key[j];
+   26673           0 :                 key[j] = key[i__];
+   26674           0 :                 key[i__] = tmpkey;
+   26675           0 :                 goto L90;
+   26676             :             }
+   26677           0 :             if (j - start > endd - j - 1) {
+   26678             :                 ++stkpnt;
+   26679             :                 stack[(stkpnt << 1) - 2] = start;
+   26680           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26681           0 :                 ++stkpnt;
+   26682           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26683           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26684             :             } else {
+   26685             :                 ++stkpnt;
+   26686           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26687           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26688           0 :                 ++stkpnt;
+   26689           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26690           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26691             :             }
+   26692             :         }
+   26693             :     }
+   26694           0 :     if (stkpnt > 0) {
+   26695           0 :         goto L10;
+   26696             :     }
+   26697             : 
+   26698             :     return;
+   26699             : }
+   26700             : }
+   26701             : }
+   26702             : #include <cmath>
+   26703             : #include "real.h"
+   26704             : #include "lapack.h"
+   26705             : 
+   26706             : #include "blas/blas.h"
+   26707             : namespace PLMD{
+   26708             : namespace lapack{
+   26709             : using namespace blas;
+   26710             : void
+   26711           0 : PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(int *n,
+   26712             :                         float *x,
+   26713             :                         int *incx,
+   26714             :                         float *scale,
+   26715             :                         float *sumsq)
+   26716             : {
+   26717             :   int ix;
+   26718             :   float absxi,t;
+   26719             : 
+   26720           0 :   if(*n>0) {
+   26721           0 :     for(ix=0;ix<=(*n-1)*(*incx);ix+=*incx) {
+   26722           0 :       if(std::abs(x[ix])>PLUMED_GMX_FLOAT_MIN) {
+   26723             :         absxi = std::abs(x[ix]);
+   26724           0 :         if(*scale<absxi) {
+   26725           0 :           t = *scale/absxi;
+   26726           0 :           t = t*t;
+   26727           0 :           *sumsq = 1.0 + (*sumsq)*t;
+   26728           0 :           *scale = absxi;
+   26729             :         } else {
+   26730           0 :           t = absxi/(*scale);
+   26731           0 :           *sumsq += t*t;
+   26732             :         }
+   26733             :       }
+   26734             :     }
+   26735             :   }
+   26736           0 :   return;
+   26737             : }
+   26738             : }
+   26739             : }
+   26740             : #include <cmath>
+   26741             : #include "lapack.h"
+   26742             : #include "lapack_limits.h"
+   26743             : 
+   26744             : #include "real.h"
+   26745             : 
+   26746             : #include "blas/blas.h"
+   26747             : namespace PLMD{
+   26748             : namespace lapack{
+   26749             : using namespace blas;
+   26750             : void 
+   26751           0 : PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(float *f, 
+   26752             :                         float *g, 
+   26753             :                         float *h__, 
+   26754             :                         float *ssmin, 
+   26755             :                         float *ssmax, 
+   26756             :                         float *snr, 
+   26757             :                         float *csr, 
+   26758             :                         float *snl, 
+   26759             :                         float *csl)
+   26760             : {
+   26761             :     float d__1;
+   26762             : 
+   26763             :     float a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt,
+   26764             :              clt, crt, slt, srt;
+   26765             :     int pmax;
+   26766             :     float temp;
+   26767             :     int swap;
+   26768             :     float tsign=1.0;
+   26769             :     int gasmal;
+   26770             : 
+   26771           0 :     ft = *f;
+   26772             :     fa = std::abs(ft);
+   26773           0 :     ht = *h__;
+   26774             :     ha = std::abs(*h__);
+   26775             : 
+   26776             :     pmax = 1;
+   26777             :     swap = ha > fa;
+   26778           0 :     if (swap) {
+   26779             :         pmax = 3;
+   26780             :         temp = ft;
+   26781             :         ft = ht;
+   26782             :         ht = temp;
+   26783             :         temp = fa;
+   26784             :         fa = ha;
+   26785             :         ha = temp;
+   26786             : 
+   26787             :     }
+   26788           0 :     gt = *g;
+   26789             :     ga = std::abs(gt);
+   26790           0 :     if (std::abs(ga)<PLUMED_GMX_FLOAT_MIN) {
+   26791             : 
+   26792           0 :         *ssmin = ha;
+   26793           0 :         *ssmax = fa;
+   26794             :         clt = 1.;
+   26795             :         crt = 1.;
+   26796             :         slt = 0.;
+   26797             :         srt = 0.;
+   26798             :     } else {
+   26799             :         gasmal = 1;
+   26800           0 :         if (ga > fa) {
+   26801             :             pmax = 2;
+   26802           0 :             if (fa / ga < PLUMED_GMX_FLOAT_EPS) {
+   26803             : 
+   26804             :                 gasmal = 0;
+   26805           0 :                 *ssmax = ga;
+   26806           0 :                 if (ha > 1.) {
+   26807           0 :                     *ssmin = fa / (ga / ha);
+   26808             :                 } else {
+   26809           0 :                     *ssmin = fa / ga * ha;
+   26810             :                 }
+   26811             :                 clt = 1.;
+   26812           0 :                 slt = ht / gt;
+   26813             :                 srt = 1.;
+   26814           0 :                 crt = ft / gt;
+   26815             :             }
+   26816             :         }
+   26817           0 :         if (gasmal) {
+   26818             : 
+   26819           0 :             d__ = fa - ha;
+   26820           0 :             if ( std::abs( fa - d__ )<PLUMED_GMX_FLOAT_EPS*std::abs( fa + d__ )) {
+   26821             :                 l = 1.;
+   26822             :             } else {
+   26823           0 :                 l = d__ / fa;
+   26824             :             }
+   26825             : 
+   26826           0 :             m = gt / ft;
+   26827           0 :             t = 2. - l;
+   26828             : 
+   26829           0 :             mm = m * m;
+   26830           0 :             tt = t * t;
+   26831           0 :             s =  std::sqrt(tt + mm);
+   26832             : 
+   26833           0 :             if ( std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26834             :                 r__ = std::abs(m);
+   26835             :             } else {
+   26836           0 :                 r__ =  std::sqrt(l * l + mm);
+   26837             :             }
+   26838           0 :             a = (s + r__) * .5;
+   26839             : 
+   26840           0 :             *ssmin = ha / a;
+   26841           0 :             *ssmax = fa * a;
+   26842           0 :             if ( std::abs(mm)<PLUMED_GMX_FLOAT_MIN) {
+   26843             : 
+   26844           0 :                 if (std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26845           0 :                     t = ( (ft>0) ? 2.0 : -2.0) * ( (gt>0) ? 1.0 : -1.0);
+   26846             :                 } else {
+   26847           0 :                     t = gt / ( (ft>0) ? d__ : -d__) + m / t;
+   26848             :                 }
+   26849             :             } else {
+   26850           0 :                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
+   26851             :             }
+   26852           0 :             l =  std::sqrt(t * t + 4.);
+   26853           0 :             crt = 2. / l;
+   26854           0 :             srt = t / l;
+   26855           0 :             clt = (crt + srt * m) / a;
+   26856           0 :             slt = ht / ft * srt / a;
+   26857             :         }
+   26858             :     }
+   26859           0 :     if (swap) {
+   26860           0 :         *csl = srt;
+   26861           0 :         *snl = crt;
+   26862           0 :         *csr = slt;
+   26863           0 :         *snr = clt;
+   26864             :     } else {
+   26865           0 :         *csl = clt;
+   26866           0 :         *snl = slt;
+   26867           0 :         *csr = crt;
+   26868           0 :         *snr = srt;
+   26869             :     }
+   26870             : 
+   26871           0 :     if (pmax == 1) {
+   26872           0 :         tsign = ( (*csr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*f>0) ? 1.0 : -1.0);
+   26873             :     }
+   26874           0 :     if (pmax == 2) {
+   26875           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*g>0) ? 1.0 : -1.0);
+   26876             :     }
+   26877           0 :     if (pmax == 3) {
+   26878           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*snl>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26879             :     }
+   26880           0 :     if(tsign<0)
+   26881           0 :       *ssmax *= -1.0;
+   26882           0 :     d__1 = tsign * ( (*f>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26883           0 :     if(d__1<0)
+   26884           0 :       *ssmin *= -1.0;
+   26885           0 :     return;
+   26886             : 
+   26887             : }
+   26888             : }
+   26889             : }
+   26890             : #include "lapack.h"
+   26891             : 
+   26892             : /* LAPACK */
+   26893             : #include "blas/blas.h"
+   26894             : namespace PLMD{
+   26895             : namespace lapack{
+   26896             : using namespace blas;
+   26897             : void
+   26898           0 : PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(int *n,
+   26899             :         float *a,
+   26900             :         int *lda,
+   26901             :         int *k1,
+   26902             :         int *k2,
+   26903             :         int *ipiv,
+   26904             :         int *incx)
+   26905             : {
+   26906             :   int ix0,i1,i2,inc,n32;
+   26907             :   int ix,i,j,ip,k;
+   26908             :   float temp;
+   26909             : 
+   26910           0 :   if(*incx>0) {
+   26911           0 :     ix0 = *k1 - 1;
+   26912             :     i1 = *k1 - 1;
+   26913           0 :     i2 = *k2;
+   26914             :     inc = 1;
+   26915           0 :   } else if(*incx<0) {
+   26916           0 :     ix0 = *incx * (1- *k2);
+   26917           0 :     i1 = *k2 - 1;
+   26918           0 :     i2 = *k1;
+   26919             :     inc = -1;
+   26920             :   } else
+   26921             :     return;
+   26922             : 
+   26923           0 :   n32 = *n / 32;
+   26924             :   
+   26925           0 :   n32 *= 32;
+   26926             : 
+   26927             : 
+   26928           0 :   if(n32!=0) {
+   26929           0 :     for(j=0;j<n32;j+=32) {
+   26930             :       ix = ix0;
+   26931           0 :       for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26932           0 :         ip = ipiv[ix] - 1;
+   26933           0 :         if(ip != i) {
+   26934           0 :           for(k=j;k<j+32;k++) {
+   26935           0 :             temp = a[(k)*(*lda)+i];
+   26936           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26937           0 :             a[(k)*(*lda)+ip] = temp;
+   26938             :           }
+   26939             :         }
+   26940             :       }
+   26941             :     }
+   26942             :   }
+   26943           0 :   if(n32!=*n) {
+   26944             :     ix = ix0;
+   26945           0 :     for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26946           0 :       ip = ipiv[ix] - 1;
+   26947           0 :       if(ip != i) {
+   26948           0 :         for(k=n32;k<*n;k++) {
+   26949           0 :             temp = a[(k)*(*lda)+i];
+   26950           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26951           0 :             a[(k)*(*lda)+ip] = temp;
+   26952             :         }
+   26953             :       }
+   26954             :     }
+   26955             :   }
+   26956             :   return;
+   26957             : }
+   26958             : }
+   26959             : }
+   26960             : #include <cctype>
+   26961             : #include "blas/blas.h"
+   26962             : #include "lapack.h"
+   26963             : #include "lapack_limits.h"
+   26964             : 
+   26965             : 
+   26966             : #include "blas/blas.h"
+   26967             : namespace PLMD{
+   26968             : namespace lapack{
+   26969             : using namespace blas;
+   26970             : void
+   26971           0 : PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(const char *  uplo,
+   26972             :        int  *   n,
+   26973             :        int  *   nb,
+   26974             :        float * a,
+   26975             :        int *    lda,
+   26976             :        float * e,
+   26977             :        float * tau,
+   26978             :        float * w,
+   26979             :        int *    ldw)
+   26980             : {
+   26981             :   int i,iw;
+   26982             :   int ti1,ti2,ti3;
+   26983             :   float one,zero,minusone,alpha;
+   26984           0 :   const char ch=std::toupper(*uplo);
+   26985             : 
+   26986           0 :   one=1.0;
+   26987           0 :   minusone=-1.0;
+   26988           0 :   zero=0.0;
+   26989             : 
+   26990           0 :   if(*n<=0)
+   26991             :     return;
+   26992             : 
+   26993           0 :   if(ch=='U') {
+   26994           0 :     for(i=*n;i>=(*n-*nb+1);i--) {
+   26995           0 :       iw = i -*n + *nb;
+   26996             :       
+   26997           0 :       if(i<*n) {
+   26998           0 :         ti1 = *n-i;
+   26999           0 :         ti2 = 1;
+   27000             :         /* BLAS */
+   27001           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(a[ i*(*lda) + 0]),lda,&(w[iw*(*ldw)+(i-1)]),
+   27002           0 :                ldw,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27003             :         /* BLAS */
+   27004           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(w[ iw*(*ldw) + 0]),ldw,&(a[i*(*lda)+(i-1)]),
+   27005           0 :                lda,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27006             :       }
+   27007             : 
+   27008           0 :       if(i>1) {
+   27009             :         /*  Generate elementary reflector H(i) to annihilate
+   27010             :          *              A(1:i-2,i) 
+   27011             :          */
+   27012           0 :         ti1 = i-1;
+   27013           0 :         ti2 = 1;
+   27014             : 
+   27015             :         /* LAPACK */
+   27016           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i-2)]),&(a[(i-1)*(*lda)+0]),&ti2,&(tau[i-2]));
+   27017             :       
+   27018           0 :         e[i-2] = a[(i-1)*(*lda)+(i-2)];
+   27019           0 :         a[(i-1)*(*lda)+(i-2)] = 1.0;
+   27020             : 
+   27021             :         /* Compute W(1:i-1,i) */
+   27022           0 :         ti1 = i-1;
+   27023           0 :         ti2 = 1;
+   27024             : 
+   27025             :         /* BLAS */
+   27026           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&ti1,&one,a,lda,&(a[(i-1)*(*lda)+0]),&ti2,&zero,
+   27027           0 :                &(w[(iw-1)*(*ldw)+0]),&ti2);
+   27028           0 :         if(i<*n) {
+   27029           0 :           ti1 = i-1;
+   27030           0 :           ti2 = *n-i;
+   27031           0 :           ti3 = 1;
+   27032             :           /* BLAS */
+   27033           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[iw*(*ldw)+0]),ldw,&(a[(i-1)*(*lda)+0]),&ti3,
+   27034           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27035             :         
+   27036             :           /* BLAS */
+   27037           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[i*(*lda)+0]),lda,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27038           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27039             :         
+   27040             :           /* BLAS */
+   27041           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[i*(*lda)+0]),lda,&(a[(i-1)*(*lda)+0]),&ti3,
+   27042           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27043             :         
+   27044             :           /* BLAS */
+   27045           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[iw*(*ldw)+0]),ldw,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27046           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27047             :         }
+   27048             :       
+   27049           0 :         ti1 = i-1;
+   27050           0 :         ti2 = 1;
+   27051             :         /* BLAS */
+   27052           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-2]),&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27053             :       
+   27054           0 :         alpha = -0.5*tau[i-2]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(iw-1)*(*ldw)+0]),&ti2,
+   27055           0 :                                     &(a[(i-1)*(*lda)+0]),&ti2);
+   27056             :       
+   27057             :         /* BLAS */
+   27058           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+0]),&ti2,&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27059             : 
+   27060             :       }
+   27061             :     }
+   27062             :   } else {
+   27063             :     /* lower */
+   27064           0 :     for(i=1;i<=*nb;i++) {
+   27065             : 
+   27066           0 :       ti1 = *n-i+1;
+   27067           0 :       ti2 = i-1;
+   27068           0 :       ti3 = 1;
+   27069             :       /* BLAS */
+   27070           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(a[ i-1 ]),lda,&(w[ i-1 ]),
+   27071           0 :                ldw,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27072             :       /* BLAS */
+   27073           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(w[ i-1 ]),ldw,&(a[ i-1 ]),
+   27074           0 :                lda,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27075             : 
+   27076           0 :       if(i<*n) {
+   27077           0 :         ti1 = *n - i;
+   27078           0 :         ti2 = (*n < i+2 ) ? *n : (i+2);
+   27079           0 :         ti3 = 1;
+   27080             :         /* LAPACK */
+   27081           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+(ti2-1)]),&ti3,&(tau[i-1]));
+   27082           0 :         e[i-1] = a[(i-1)*(*lda)+(i)];
+   27083           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   27084             :         
+   27085           0 :         ti1 = *n - i;
+   27086           0 :         ti2 = 1;
+   27087           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("L",&ti1,&one,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),&ti2,
+   27088           0 :                &zero,&(w[(i-1)*(*ldw)+i]),&ti2);
+   27089           0 :         ti1 = *n - i;
+   27090           0 :         ti2 = i-1;
+   27091           0 :         ti3 = 1;
+   27092             :         /* BLAS */
+   27093           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[ i ]),ldw,&(a[(i-1)*(*lda)+i]),&ti3,
+   27094           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27095             :         
+   27096             :         /* BLAS */
+   27097           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[ i ]),lda,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27098           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27099             :         
+   27100             :         /* BLAS */
+   27101           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[ i ]),lda,&(a[(i-1)*(*lda)+i]),&ti3,
+   27102           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27103             :         
+   27104             :         /* BLAS */
+   27105           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[ i ]),ldw,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27106           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27107             : 
+   27108           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-1]),&(w[(i-1)*(*ldw)+i]),&ti3);
+   27109           0 :         alpha = -0.5*tau[i-1]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(i-1)*(*ldw)+i]),&ti3,
+   27110           0 :                                    &(a[(i-1)*(*lda)+i]),&ti3);
+   27111             :         
+   27112           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti3,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27113             :       }
+   27114             :     }
+   27115             :   }
+   27116             :   return;
+   27117             : }
+   27118             :         
+   27119             : 
+   27120             : 
+   27121             :   
+   27122             : }
+   27123             : }
+   27124             : #include <cmath>
+   27125             : 
+   27126             : #include "blas/blas.h"
+   27127             : #include "lapack.h"
+   27128             : 
+   27129             : #include "blas/blas.h"
+   27130             : namespace PLMD{
+   27131             : namespace lapack{
+   27132             : using namespace blas;
+   27133             : void 
+   27134           0 : PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(int *m, 
+   27135             :                         int *n,
+   27136             :                         int *k, 
+   27137             :                         float *a, 
+   27138             :                         int *lda,
+   27139             :                         float *tau,
+   27140             :                         float *work,
+   27141             :                         int *info)
+   27142             : {
+   27143             :     int a_dim1, a_offset, i__1, i__2;
+   27144             :     float r__1;
+   27145           0 :     int c__1 = 1;
+   27146             : 
+   27147             :     int i__, j, l;
+   27148             : 
+   27149           0 :     a_dim1 = *lda;
+   27150           0 :     a_offset = 1 + a_dim1;
+   27151           0 :     a -= a_offset;
+   27152           0 :     --tau;
+   27153             :     --work;
+   27154             : 
+   27155           0 :     *info = 0;
+   27156             : 
+   27157           0 :     if (*n <= 0) {
+   27158             :         return;
+   27159             :     }
+   27160             : 
+   27161           0 :     i__1 = *n;
+   27162           0 :     for (j = *k + 1; j <= i__1; ++j) {
+   27163           0 :         i__2 = *m;
+   27164           0 :         for (l = 1; l <= i__2; ++l) {
+   27165           0 :             a[l + j * a_dim1] = 0.0;
+   27166             :         }
+   27167           0 :         a[j + j * a_dim1] = 1.0;
+   27168             :     }
+   27169           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27170           0 :         if (i__ < *n) {
+   27171           0 :             a[i__ + i__ * a_dim1] = 1.0;
+   27172           0 :             i__1 = *m - i__ + 1;
+   27173           0 :             i__2 = *n - i__;
+   27174           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L", &i__1, &i__2, &a[i__ + i__ * a_dim1], &c__1, 
+   27175           0 :                               &tau[i__], &a[i__ + (i__ + 1) * a_dim1], lda, &work[1]);
+   27176             :         }
+   27177           0 :         if (i__ < *m) {
+   27178           0 :             i__1 = *m - i__;
+   27179           0 :             r__1 = -tau[i__];
+   27180           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + 1 + i__ * a_dim1], &c__1);
+   27181             :         }
+   27182           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27183           0 :         i__1 = i__ - 1;
+   27184           0 :         for (l = 1; l <= i__1; ++l) {
+   27185           0 :             a[l + i__ * a_dim1] = 0.0;
+   27186             :         }
+   27187             :     }
+   27188             :     return;
+   27189             : 
+   27190             : }
+   27191             : 
+   27192             : 
+   27193             : }
+   27194             : }
+   27195             : #include "lapack.h"
+   27196             : #include "lapack_limits.h"
+   27197             : 
+   27198             : #include "blas/blas.h"
+   27199             : namespace PLMD{
+   27200             : namespace lapack{
+   27201             : using namespace blas;
+   27202             : void
+   27203           0 : PLUMED_BLAS_F77_FUNC(sorgbr,SORGBR)(const char *vect,
+   27204             :         int *m,
+   27205             :         int *n,
+   27206             :         int *k,
+   27207             :         float *a,
+   27208             :         int *lda,
+   27209             :         float *tau,
+   27210             :         float *work,
+   27211             :         int *lwork,
+   27212             :         int *info)
+   27213             : {
+   27214             :   int wantq,iinfo,j,i,i1,wrksz;
+   27215           0 :   int mn = (*m < *n) ? *m : *n;
+   27216             : 
+   27217           0 :   wantq = (*vect=='Q' || *vect=='q');
+   27218             : 
+   27219           0 :   *info = 0;
+   27220           0 :   wrksz = mn*DORGBR_BLOCKSIZE;
+   27221           0 :   if(*lwork==-1) {
+   27222           0 :     work[0] = wrksz;
+   27223           0 :     return;
+   27224             :   }
+   27225             :   
+   27226           0 :   if(*m==0 || *n==0)
+   27227             :     return;
+   27228             : 
+   27229           0 :   if(wantq) {
+   27230           0 :     if(*m>=*k)
+   27231           0 :       PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27232             :     else {
+   27233           0 :       for(j=*m;j>=2;j--) {
+   27234           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27235           0 :         for(i=j+1;i<=*m;i++)
+   27236           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-2)*(*lda)+(i-1)]; 
+   27237             :       }
+   27238           0 :       a[0] = 1.0;
+   27239           0 :       for(i=2;i<=*m;i++)
+   27240           0 :         a[i-1] = 0.0;
+   27241           0 :       if(*m>1) {
+   27242           0 :         i1 = *m-1;
+   27243           0 :         PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27244             :       }
+   27245             :     }
+   27246             :   } else {
+   27247           0 :     if(*k<*n)
+   27248           0 :       PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27249             :     else {
+   27250           0 :       a[0] = 1.0;
+   27251           0 :       for(i=2;i<=*m;i++)
+   27252           0 :         a[i-1] = 0.0;
+   27253           0 :       for(j=2;j<=*n;j++) {
+   27254           0 :         for(i=j-1;i>=2;i--)
+   27255           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-1)*(*lda)+(i-2)]; 
+   27256           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27257             :       }
+   27258           0 :       if(*n>1) {
+   27259           0 :         i1 = *n-1;
+   27260           0 :         PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27261             :       }
+   27262             :     }
+   27263             :   }
+   27264           0 :   work[0] = wrksz;
+   27265           0 :   return;
+   27266             : }
+   27267             :  
+   27268             : }
+   27269             : }
+   27270             : #include "blas/blas.h"
+   27271             : #include "lapack.h"
+   27272             : 
+   27273             : #include "blas/blas.h"
+   27274             : namespace PLMD{
+   27275             : namespace lapack{
+   27276             : using namespace blas;
+   27277             : void
+   27278           0 : PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(int *m,
+   27279             :                         int *n, 
+   27280             :                         int *k, 
+   27281             :                         float *a, 
+   27282             :                         int *lda, 
+   27283             :                         float *tau, 
+   27284             :                         float *work, 
+   27285             :                         int *info)
+   27286             : {
+   27287             :     int a_dim1, a_offset, i__1, i__2;
+   27288             :     float r__1;
+   27289             : 
+   27290             :     int i__, j, l;
+   27291             : 
+   27292           0 :     a_dim1 = *lda;
+   27293           0 :     a_offset = 1 + a_dim1;
+   27294           0 :     a -= a_offset;
+   27295           0 :     --tau;
+   27296             :     --work;
+   27297             : 
+   27298           0 :     i__ = (*m > 1) ? *m : 1;
+   27299             :     
+   27300           0 :     *info = 0;
+   27301           0 :     if (*m < 0) {
+   27302           0 :         *info = -1;
+   27303           0 :     } else if (*n < *m) {
+   27304           0 :         *info = -2;
+   27305           0 :     } else if (*k < 0 || *k > *m) {
+   27306           0 :         *info = -3;
+   27307           0 :     } else if (*lda < i__) {
+   27308           0 :         *info = -5;
+   27309             :     }
+   27310           0 :     if (*info != 0) {
+   27311             :         return;
+   27312             :     }
+   27313           0 :     if (*m <= 0) {
+   27314             :         return;
+   27315             :     }
+   27316             : 
+   27317           0 :     if (*k < *m) {
+   27318           0 :         i__1 = *n;
+   27319           0 :         for (j = 1; j <= i__1; ++j) {
+   27320           0 :             i__2 = *m;
+   27321           0 :             for (l = *k + 1; l <= i__2; ++l) {
+   27322           0 :                 a[l + j * a_dim1] = 0.0;
+   27323             :             }
+   27324           0 :             if (j > *k && j <= *m) {
+   27325           0 :                 a[j + j * a_dim1] = 1.0;
+   27326             :             }
+   27327             :         }
+   27328             :     }
+   27329             : 
+   27330           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27331           0 :         if (i__ < *n) {
+   27332           0 :             if (i__ < *m) {
+   27333           0 :                 a[i__ + i__ * a_dim1] = 1.0;
+   27334           0 :                 i__1 = *m - i__;
+   27335           0 :                 i__2 = *n - i__ + 1;
+   27336           0 :                 PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__1, &i__2, &a[i__ + i__ * a_dim1], lda, 
+   27337           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   27338             :             }
+   27339           0 :             i__1 = *n - i__;
+   27340           0 :             r__1 = -tau[i__];
+   27341           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + (i__ + 1) * a_dim1], lda);
+   27342             :         }
+   27343           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27344           0 :         i__1 = i__ - 1;
+   27345           0 :         for (l = 1; l <= i__1; ++l) {
+   27346           0 :             a[i__ + l * a_dim1] = 0.0;
+   27347             :         }
+   27348             :     }
+   27349             :     return;
+   27350             : 
+   27351             : }
+   27352             : 
+   27353             : 
+   27354             : 
+   27355             : }
+   27356             : }
+   27357             : #include "lapack.h"
+   27358             : 
+   27359             : #define SORGLQ_BLOCKSIZE    32
+   27360             : #define SORGLQ_MINBLOCKSIZE 2
+   27361             : #define SORGLQ_CROSSOVER    128
+   27362             : 
+   27363             : 
+   27364             : #include "blas/blas.h"
+   27365             : namespace PLMD{
+   27366             : namespace lapack{
+   27367             : using namespace blas;
+   27368             : void 
+   27369           0 : PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(int *m, 
+   27370             :         int *n, 
+   27371             :         int *k, 
+   27372             :         float *a, 
+   27373             :         int *lda, 
+   27374             :         float *tau, 
+   27375             :         float *work, 
+   27376             :         int *lwork, 
+   27377             :         int *info)
+   27378             : {
+   27379             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27380             : 
+   27381             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27382             : 
+   27383             :     int ldwork, lwkopt;
+   27384             :     int lquery;
+   27385             :     
+   27386           0 :     a_dim1 = *lda;
+   27387           0 :     a_offset = 1 + a_dim1;
+   27388           0 :     a -= a_offset;
+   27389           0 :     --tau;
+   27390             :     --work;
+   27391             : 
+   27392           0 :     *info = 0;
+   27393             :     ki = 0;
+   27394             :     nb = SORGLQ_BLOCKSIZE;
+   27395           0 :     lwkopt = (*m) * nb;
+   27396           0 :     work[1] = (float) lwkopt;
+   27397           0 :     lquery = *lwork == -1;
+   27398           0 :     if (*m < 0) {
+   27399           0 :         *info = -1;
+   27400           0 :     } else if (*n < *m) {
+   27401           0 :         *info = -2;
+   27402           0 :     } else if (*k < 0 || *k > *m) {
+   27403           0 :         *info = -3;
+   27404           0 :     } else if (*lda < (*m)) {
+   27405           0 :         *info = -5;
+   27406           0 :     } else if (*lwork < (*m) && ! lquery) {
+   27407           0 :         *info = -8;
+   27408             :     }
+   27409           0 :     if (*info != 0) {
+   27410             :         i__1 = -(*info);
+   27411             :         return;
+   27412           0 :     } else if (lquery) {
+   27413             :         return;
+   27414             :     }
+   27415             : 
+   27416           0 :     if (*m <= 0) {
+   27417           0 :         work[1] = 1.;
+   27418           0 :         return;
+   27419             :     }
+   27420             : 
+   27421             :     nbmin = 2;
+   27422             :     nx = 0;
+   27423             :     iws = *m;
+   27424           0 :     if (nb > 1 && nb < *k) {
+   27425             : 
+   27426             :         nx = SORGLQ_CROSSOVER;
+   27427           0 :         if (nx < *k) {
+   27428             : 
+   27429           0 :             ldwork = *m;
+   27430           0 :             iws = ldwork * nb;
+   27431           0 :             if (*lwork < iws) {
+   27432             : 
+   27433           0 :                 nb = *lwork / ldwork;
+   27434             :                 nbmin = SORGLQ_MINBLOCKSIZE;
+   27435             :             }
+   27436             :         }
+   27437             :     }
+   27438             : 
+   27439           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27440             : 
+   27441           0 :         ki = (*k - nx - 1) / nb * nb;
+   27442           0 :         i__1 = *k, i__2 = ki + nb;
+   27443             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27444             : 
+   27445           0 :         i__1 = kk;
+   27446           0 :         for (j = 1; j <= i__1; ++j) {
+   27447           0 :             i__2 = *m;
+   27448           0 :             for (i__ = kk + 1; i__ <= i__2; ++i__) {
+   27449           0 :                 a[i__ + j * a_dim1] = 0.;
+   27450             :             }
+   27451             :         }
+   27452             :     } else {
+   27453             :         kk = 0;
+   27454             :     }
+   27455           0 :     if (kk < *m) {
+   27456           0 :         i__1 = *m - kk;
+   27457           0 :         i__2 = *n - kk;
+   27458           0 :         i__3 = *k - kk;
+   27459           0 :         PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27460           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27461             :     }
+   27462             : 
+   27463           0 :     if (kk > 0) {
+   27464             : 
+   27465           0 :         i__1 = -nb;
+   27466           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27467           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27468           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27469           0 :             if (i__ + ib <= *m) {
+   27470             : 
+   27471           0 :                 i__2 = *n - i__ + 1;
+   27472           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__2, &ib, &a[i__ + i__ * 
+   27473           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27474             : 
+   27475           0 :                 i__2 = *m - i__ - ib + 1;
+   27476           0 :                 i__3 = *n - i__ + 1;
+   27477           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "Transpose", "Forward", "Rowwise", &i__2, &
+   27478             :                         i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   27479           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   27480           0 :                         1], &ldwork);
+   27481             :             }
+   27482             : 
+   27483           0 :             i__2 = *n - i__ + 1;
+   27484           0 :             PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&ib, &i__2, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27485             :                     work[1], &iinfo);
+   27486             : 
+   27487           0 :             i__2 = i__ - 1;
+   27488           0 :             for (j = 1; j <= i__2; ++j) {
+   27489           0 :                 i__3 = i__ + ib - 1;
+   27490           0 :                 for (l = i__; l <= i__3; ++l) {
+   27491           0 :                     a[l + j * a_dim1] = 0.;
+   27492             :                 }
+   27493             :             }
+   27494             :         }
+   27495             :     }
+   27496             : 
+   27497           0 :     work[1] = (float) iws;
+   27498           0 :     return;
+   27499             : 
+   27500             : }
+   27501             : 
+   27502             : 
+   27503             : }
+   27504             : }
+   27505             : #include "lapack.h"
+   27506             : #include "lapack_limits.h"
+   27507             : 
+   27508             : 
+   27509             : #include "blas/blas.h"
+   27510             : namespace PLMD{
+   27511             : namespace lapack{
+   27512             : using namespace blas;
+   27513             : void 
+   27514           0 : PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(int *m, 
+   27515             :         int *n, 
+   27516             :         int *k, 
+   27517             :         float *a, 
+   27518             :         int *lda, 
+   27519             :         float *tau, 
+   27520             :         float *work, 
+   27521             :         int *lwork, 
+   27522             :         int *info)
+   27523             : {
+   27524             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27525             : 
+   27526             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27527             :     int ldwork, lwkopt;
+   27528             :     int lquery;
+   27529             :  
+   27530           0 :     a_dim1 = *lda;
+   27531           0 :     a_offset = 1 + a_dim1;
+   27532           0 :     a -= a_offset;
+   27533           0 :     --tau;
+   27534             :     --work;
+   27535             : 
+   27536             :     ki = 0;
+   27537           0 :     *info = 0;
+   27538             :     nb = DORGQR_BLOCKSIZE;
+   27539           0 :     lwkopt = (*n) * nb;
+   27540           0 :     work[1] = (float) lwkopt;
+   27541           0 :     lquery = *lwork == -1;
+   27542           0 :     if (*m < 0) {
+   27543           0 :         *info = -1;
+   27544           0 :     } else if (*n < 0 || *n > *m) {
+   27545           0 :         *info = -2;
+   27546           0 :     } else if (*k < 0 || *k > *n) {
+   27547           0 :         *info = -3;
+   27548           0 :     } else if (*lda < (*m)) {
+   27549           0 :         *info = -5;
+   27550           0 :     } else if (*lwork < (*n) && ! lquery) {
+   27551           0 :         *info = -8;
+   27552             :     }
+   27553           0 :     if (*info != 0) {
+   27554             :         i__1 = -(*info);
+   27555             :         return;
+   27556           0 :     } else if (lquery) {
+   27557             :         return;
+   27558             :     }
+   27559             : 
+   27560           0 :     if (*n <= 0) {
+   27561           0 :         work[1] = 1.;
+   27562           0 :         return;
+   27563             :     }
+   27564             : 
+   27565             :     nbmin = 2;
+   27566             :     nx = 0;
+   27567             :     iws = *n;
+   27568           0 :     if (nb > 1 && nb < *k) {
+   27569             : 
+   27570             :         nx = DORGQR_CROSSOVER;
+   27571           0 :         if (nx < *k) {
+   27572             : 
+   27573           0 :             ldwork = *n;
+   27574           0 :             iws = ldwork * nb;
+   27575           0 :             if (*lwork < iws) {
+   27576             : 
+   27577           0 :                 nb = *lwork / ldwork;
+   27578             :                 nbmin = DORGQR_MINBLOCKSIZE;
+   27579             :             }
+   27580             :         }
+   27581             :     }
+   27582             : 
+   27583           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27584             : 
+   27585           0 :         ki = (*k - nx - 1) / nb * nb;
+   27586           0 :         i__1 = *k, i__2 = ki + nb;
+   27587             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27588             : 
+   27589           0 :         i__1 = *n;
+   27590           0 :         for (j = kk + 1; j <= i__1; ++j) {
+   27591           0 :             i__2 = kk;
+   27592           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   27593           0 :                 a[i__ + j * a_dim1] = 0.;
+   27594             :             }
+   27595             :         }
+   27596             :     } else {
+   27597             :         kk = 0;
+   27598             :     }
+   27599             : 
+   27600           0 :     if (kk < *n) {
+   27601           0 :         i__1 = *m - kk;
+   27602           0 :         i__2 = *n - kk;
+   27603           0 :         i__3 = *k - kk;
+   27604           0 :         PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27605           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27606             :     }
+   27607             : 
+   27608           0 :     if (kk > 0) {
+   27609             : 
+   27610           0 :         i__1 = -nb;
+   27611           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27612           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27613           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27614           0 :             if (i__ + ib <= *n) {
+   27615             : 
+   27616           0 :                 i__2 = *m - i__ + 1;
+   27617           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__2, &ib, &a[i__ + i__ * 
+   27618           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27619             : 
+   27620           0 :                 i__2 = *m - i__ + 1;
+   27621           0 :                 i__3 = *n - i__ - ib + 1;
+   27622           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "No transpose", "Forward", "Columnwise", &
+   27623             :                         i__2, &i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[
+   27624           0 :                         1], &ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &
+   27625           0 :                         work[ib + 1], &ldwork);
+   27626             :             }
+   27627             : 
+   27628           0 :             i__2 = *m - i__ + 1;
+   27629           0 :             PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__2, &ib, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27630             :                     work[1], &iinfo);
+   27631             : 
+   27632           0 :             i__2 = i__ + ib - 1;
+   27633           0 :             for (j = i__; j <= i__2; ++j) {
+   27634           0 :                 i__3 = i__ - 1;
+   27635           0 :                 for (l = 1; l <= i__3; ++l) {
+   27636           0 :                     a[l + j * a_dim1] = 0.;
+   27637             :                 }
+   27638             :             }
+   27639             :         }
+   27640             :     }
+   27641             : 
+   27642           0 :     work[1] = (float) iws;
+   27643           0 :     return;
+   27644             : 
+   27645             : } 
+   27646             : }
+   27647             : }
+   27648             : #include "lapack.h"
+   27649             : 
+   27650             : #include "blas/blas.h"
+   27651             : namespace PLMD{
+   27652             : namespace lapack{
+   27653             : using namespace blas;
+   27654             : void
+   27655           0 : PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(const char *side, 
+   27656             :         const char *trans, 
+   27657             :         int *m, 
+   27658             :         int *n, 
+   27659             :         int *k, 
+   27660             :         float *a,
+   27661             :         int *lda, 
+   27662             :         float *tau,
+   27663             :         float *c__,
+   27664             :         int *ldc, 
+   27665             :         float *work, 
+   27666             :         int *info)
+   27667             : {
+   27668             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27669           0 :     int c__1 = 1;
+   27670             : 
+   27671             :     int i__, i1, i2, i3, mi, ni, nq;
+   27672             :     float aii;
+   27673             :     int left;
+   27674             :     int notran;
+   27675             : 
+   27676           0 :     a_dim1 = *lda;
+   27677           0 :     a_offset = 1 + a_dim1;
+   27678           0 :     a -= a_offset;
+   27679             :     --tau;
+   27680             :     c_dim1 = *ldc;
+   27681             :     c_offset = 1 + c_dim1;
+   27682             :     c__ -= c_offset;
+   27683             :     --work;
+   27684             : 
+   27685             :     /* Function Body */
+   27686           0 :     *info = 0;
+   27687           0 :     left = (*side=='L' || *side=='l');
+   27688           0 :     notran = (*trans=='N' || *trans=='n');
+   27689             : 
+   27690           0 :     if (left) {
+   27691           0 :         nq = *m;
+   27692             :     } else {
+   27693           0 :         nq = *n;
+   27694             :     }
+   27695             :     if (*info != 0) {
+   27696             :         return;
+   27697             :     }
+   27698             : 
+   27699           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   27700             :         return;
+   27701             :     }
+   27702             : 
+   27703           0 :     if ((left && notran) || (! left && ! notran)) {
+   27704             :         i1 = 1;
+   27705             :         i2 = *k;
+   27706             :         i3 = 1;
+   27707             :     } else {
+   27708             :         i1 = *k;
+   27709             :         i2 = 1;
+   27710             :         i3 = -1;
+   27711             :     }
+   27712             : 
+   27713           0 :     if (left) {
+   27714           0 :         ni = *n;
+   27715             :     } else {
+   27716           0 :         mi = *m;
+   27717             :     }
+   27718             : 
+   27719             :     i__1 = i2;
+   27720             :     i__2 = i3;
+   27721           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27722           0 :         if (left) {
+   27723             : 
+   27724           0 :             mi = *m - *k + i__;
+   27725             :         } else {
+   27726             : 
+   27727           0 :             ni = *n - *k + i__;
+   27728             :         }
+   27729             : 
+   27730           0 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   27731           0 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   27732           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ * a_dim1 + 1], &c__1, &tau[i__], &c__[
+   27733             :                 c_offset], ldc, &work[1]);
+   27734           0 :         a[nq - *k + i__ + i__ * a_dim1] = aii;
+   27735             :     }
+   27736             :     return;
+   27737             : }
+   27738             : }
+   27739             : }
+   27740             : #include "lapack.h"
+   27741             : 
+   27742             : #include "blas/blas.h"
+   27743             : namespace PLMD{
+   27744             : namespace lapack{
+   27745             : using namespace blas;
+   27746             : void 
+   27747           0 : PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(const char *side, 
+   27748             :         const char *trans, 
+   27749             :         int *m, 
+   27750             :         int *n, 
+   27751             :         int *k, 
+   27752             :         float *a, 
+   27753             :         int *lda, 
+   27754             :         float *tau, 
+   27755             :         float *c__, 
+   27756             :         int *ldc, 
+   27757             :         float *work, 
+   27758             :         int *info)
+   27759             : {
+   27760             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27761             : 
+   27762             :     int i__, i1, i2, i3, ic, jc, mi, ni;
+   27763             :     float aii;
+   27764             :     int left;
+   27765             :     int notran;
+   27766           0 :     int c__1 = 1;
+   27767             : 
+   27768           0 :     a_dim1 = *lda;
+   27769           0 :     a_offset = 1 + a_dim1;
+   27770           0 :     a -= a_offset;
+   27771             :     --tau;
+   27772           0 :     c_dim1 = *ldc;
+   27773           0 :     c_offset = 1 + c_dim1;
+   27774           0 :     c__ -= c_offset;
+   27775             :     --work;
+   27776           0 :     *info = 0;
+   27777           0 :     left = (*side=='L' || *side=='l');
+   27778           0 :     notran = (*trans=='N' || *trans=='n');
+   27779             : 
+   27780             :     ic = jc = 0;
+   27781             : 
+   27782           0 :     if (*m <= 0 || *n <= 0 || *k <= 0) {
+   27783             :         return;
+   27784             :     }
+   27785             : 
+   27786           0 :     if ((left && !notran) || (!left && notran)) {
+   27787             :         i1 = 1;
+   27788             :         i2 = *k;
+   27789             :         i3 = 1;
+   27790             :     } else {
+   27791             :         i1 = *k;
+   27792             :         i2 = 1;
+   27793             :         i3 = -1;
+   27794             :     }
+   27795             : 
+   27796           0 :     if (left) {
+   27797           0 :         ni = *n;
+   27798             :         jc = 1;
+   27799             :     } else {
+   27800           0 :         mi = *m;
+   27801             :         ic = 1;
+   27802             :     }
+   27803             : 
+   27804             :     i__1 = i2;
+   27805             :     i__2 = i3;
+   27806           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27807           0 :         if (left) {
+   27808             : 
+   27809           0 :             mi = *m - i__ + 1;
+   27810             :             ic = i__;
+   27811             :         } else {
+   27812             : 
+   27813           0 :             ni = *n - i__ + 1;
+   27814             :             jc = i__;
+   27815             :         }
+   27816             : 
+   27817             : 
+   27818           0 :         aii = a[i__ + i__ * a_dim1];
+   27819           0 :         a[i__ + i__ * a_dim1] = 1.;
+   27820           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ + i__ * a_dim1], &c__1, &tau[i__], &c__[
+   27821           0 :                 ic + jc * c_dim1], ldc, &work[1]);
+   27822           0 :         a[i__ + i__ * a_dim1] = aii;
+   27823             :     }
+   27824             :     return;
+   27825             : 
+   27826             : } 
+   27827             : }
+   27828             : }
+   27829             : #include "lapack.h"
+   27830             : #include "lapack_limits.h"
+   27831             : 
+   27832             : #include "blas/blas.h"
+   27833             : namespace PLMD{
+   27834             : namespace lapack{
+   27835             : using namespace blas;
+   27836             : void 
+   27837           0 : PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)(const char *vect, 
+   27838             :         const char *side, 
+   27839             :         const char *trans, 
+   27840             :         int *m, 
+   27841             :         int *n, 
+   27842             :         int *k, 
+   27843             :         float *a, 
+   27844             :         int *lda, 
+   27845             :         float *tau, 
+   27846             :         float *c__, 
+   27847             :         int *ldc, 
+   27848             :         float *work, 
+   27849             :         int *lwork, 
+   27850             :         int *info)
+   27851             : {
+   27852             :     int a_dim1, a_offset, c_dim1, c_offset, i__1;
+   27853             :  
+   27854             : 
+   27855             :     int i1, i2, nb, mi, ni, nq, nw;
+   27856             :     int left;
+   27857             :     int iinfo;
+   27858             :     int notran;
+   27859             :     int applyq;
+   27860             :     char transt[1];
+   27861             :     int lwkopt;
+   27862             :     int lquery;
+   27863             : 
+   27864           0 :     a_dim1 = *lda;
+   27865           0 :     a_offset = 1 + a_dim1;
+   27866           0 :     a -= a_offset;
+   27867             :     --tau;
+   27868           0 :     c_dim1 = *ldc;
+   27869           0 :     c_offset = 1 + c_dim1;
+   27870           0 :     c__ -= c_offset;
+   27871             :     --work;
+   27872           0 :     *info = 0;
+   27873           0 :     applyq = (*vect=='Q' || *vect=='q');
+   27874           0 :     left = (*side=='L' || *side=='l');
+   27875           0 :     notran = (*trans=='N' || *trans=='n');
+   27876           0 :     lquery = *lwork == -1;
+   27877             : 
+   27878           0 :     if (left) {
+   27879           0 :         nq = *m;
+   27880           0 :         nw = *n;
+   27881             :     } else {
+   27882           0 :         nq = *n;
+   27883           0 :         nw = *m;
+   27884             :     }
+   27885             : 
+   27886             :     nb = DORMQR_BLOCKSIZE;
+   27887           0 :     lwkopt = nw * nb;
+   27888           0 :     work[1] = (float) lwkopt;
+   27889             :     
+   27890           0 :     if (*info != 0) {
+   27891             :         i__1 = -(*info);
+   27892             :         return;
+   27893           0 :     } else if (lquery) {
+   27894             :         return;
+   27895             :     }
+   27896             : 
+   27897           0 :     work[1] = 1.;
+   27898           0 :     if (*m == 0 || *n == 0) {
+   27899             :         return;
+   27900             :     }
+   27901             : 
+   27902           0 :     if (applyq) {
+   27903             : 
+   27904           0 :         if (nq >= *k) {
+   27905             : 
+   27906           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27907             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27908           0 :         } else if (nq > 1) {
+   27909             : 
+   27910           0 :             if (left) {
+   27911           0 :                 mi = *m - 1;
+   27912           0 :                 ni = *n;
+   27913             :                 i1 = 2;
+   27914             :                 i2 = 1;
+   27915             :             } else {
+   27916           0 :                 mi = *m;
+   27917           0 :                 ni = *n - 1;
+   27918             :                 i1 = 1;
+   27919             :                 i2 = 2;
+   27920             :             }
+   27921           0 :             i__1 = nq - 1;
+   27922           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__1, &a[a_dim1 + 2], lda, &tau[1]
+   27923           0 :                     , &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   27924             :         }
+   27925             :     } else {
+   27926             : 
+   27927           0 :         if (notran) {
+   27928           0 :             *(unsigned char *)transt = 'T';
+   27929             :         } else {
+   27930           0 :             *(unsigned char *)transt = 'N';
+   27931             :         }
+   27932           0 :         if (nq > *k) {
+   27933             : 
+   27934           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27935             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27936           0 :         } else if (nq > 1) {
+   27937             : 
+   27938           0 :             if (left) {
+   27939           0 :                 mi = *m - 1;
+   27940           0 :                 ni = *n;
+   27941             :                 i1 = 2;
+   27942             :                 i2 = 1;
+   27943             :             } else {
+   27944           0 :                 mi = *m;
+   27945           0 :                 ni = *n - 1;
+   27946             :                 i1 = 1;
+   27947             :                 i2 = 2;
+   27948             :             }
+   27949           0 :             i__1 = nq - 1;
+   27950           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, &mi, &ni, &i__1, &a[(a_dim1 << 1) + 1], lda,
+   27951           0 :                      &tau[1], &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &
+   27952             :                     iinfo);
+   27953             :         }
+   27954             :     }
+   27955           0 :     work[1] = (float) lwkopt;
+   27956           0 :     return;
+   27957             : 
+   27958             : 
+   27959             : }
+   27960             : 
+   27961             : 
+   27962             : }
+   27963             : }
+   27964             : #include <cctype>
+   27965             : #include "real.h"
+   27966             : #include "lapack.h"
+   27967             : 
+   27968             : #include "blas/blas.h"
+   27969             : namespace PLMD{
+   27970             : namespace lapack{
+   27971             : using namespace blas;
+   27972             : void
+   27973           0 : PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(const char *side,
+   27974             :                         const char *trans,
+   27975             :                         int *m,
+   27976             :                         int *n,
+   27977             :                         int *k,
+   27978             :                         float *a,
+   27979             :                         int *lda,
+   27980             :                         float *tau,
+   27981             :                         float *c,
+   27982             :                         int *ldc,
+   27983             :                         float *work,
+   27984             :                         int *info)
+   27985             : {
+   27986           0 :   const char xside=std::toupper(*side);
+   27987           0 :   const char xtrans=std::toupper(*trans);
+   27988             :   int i,i1,i2,i3,ni,mi,ic,jc;
+   27989             :   float aii;
+   27990             : 
+   27991           0 :   if(*m<=0 || *n<=0 || *k<=0)
+   27992             :     return;
+   27993             : 
+   27994             :   ic = jc = 0;
+   27995             : 
+   27996           0 :   if((xside=='L' && xtrans=='N') || (xside!='L' && xtrans!='N')) {
+   27997             :     i1 = 0;
+   27998             :     i2 = *k;
+   27999             :     i3 = 1;
+   28000             :   } else {
+   28001           0 :     i1 = *k-1;
+   28002             :     i2 = -1;
+   28003             :     i3 = -1;
+   28004             :   }
+   28005             :   
+   28006           0 :   if(xside=='L') {
+   28007           0 :     ni = *n;
+   28008             :     jc = 0;
+   28009             :   } else {
+   28010           0 :     mi = *m;
+   28011             :     ic = 0;
+   28012             :   }
+   28013             : 
+   28014           0 :   for(i=i1;i!=i2;i+=i3) {
+   28015           0 :     if(xside=='L') {
+   28016           0 :       mi = *m - i;
+   28017             :       ic = i;
+   28018             :     } else {
+   28019           0 :       ni = *n - i;
+   28020             :       jc = i;
+   28021             :     }
+   28022           0 :     aii = a[i*(*lda)+i];
+   28023           0 :     a[i*(*lda)+i] = 1.0;
+   28024           0 :     PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side,&mi,&ni,&(a[i*(*lda)+i]),lda,tau+i,
+   28025           0 :            &(c[jc*(*ldc)+ic]),ldc,work);
+   28026           0 :     a[i*(*lda)+i] = aii;
+   28027             :   }
+   28028             :   return;
+   28029             : }
+   28030             :              
+   28031             : }
+   28032             : }
+   28033             : #include "lapack.h"
+   28034             : #include "lapack_limits.h"
+   28035             : 
+   28036             : 
+   28037             : #include "blas/blas.h"
+   28038             : namespace PLMD{
+   28039             : namespace lapack{
+   28040             : using namespace blas;
+   28041             : void 
+   28042           0 : PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(const char *side, 
+   28043             :         const char *trans,
+   28044             :         int *m, 
+   28045             :         int *n, 
+   28046             :         int *k,
+   28047             :         float *a,
+   28048             :         int *lda, 
+   28049             :         float *tau, 
+   28050             :         float *c__, 
+   28051             :         int *ldc, 
+   28052             :         float *work, 
+   28053             :         int *lwork, 
+   28054             :         int *info)
+   28055             : {
+   28056             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, 
+   28057             :             i__5;
+   28058             :   
+   28059             : 
+   28060             :     int i__;
+   28061             :     float t[4160]       /* was [65][64] */;
+   28062             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28063             :     int left;
+   28064             :     int nbmin, iinfo;
+   28065             :     int notran;
+   28066             :     int ldwork;
+   28067             :     char transt[1];
+   28068             :     int lwkopt;
+   28069             :     int lquery;
+   28070           0 :     int ldt = 65;
+   28071             : 
+   28072           0 :     a_dim1 = *lda;
+   28073           0 :     a_offset = 1 + a_dim1;
+   28074           0 :     a -= a_offset;
+   28075             :     --tau;
+   28076           0 :     c_dim1 = *ldc;
+   28077           0 :     c_offset = 1 + c_dim1;
+   28078           0 :     c__ -= c_offset;
+   28079             :     --work;
+   28080             : 
+   28081             :     ic = jc = 0;
+   28082             : 
+   28083           0 :     *info = 0;
+   28084           0 :     left = (*side=='L' || *side=='l');
+   28085           0 :     notran = (*trans=='N' || *trans=='n');
+   28086           0 :     lquery = *lwork == -1;
+   28087             : 
+   28088           0 :     if (left) {
+   28089           0 :         nq = *m;
+   28090           0 :         nw = *n;
+   28091             :     } else {
+   28092           0 :         nq = *n;
+   28093           0 :         nw = *m;
+   28094             :     }
+   28095             : 
+   28096             :     nb = DORMLQ_BLOCKSIZE;
+   28097           0 :     lwkopt = nw * nb;
+   28098           0 :     work[1] = (float) lwkopt;
+   28099             :     
+   28100           0 :     if (*info != 0) {
+   28101             :         return;
+   28102           0 :     } else if (lquery) {
+   28103             :         return;
+   28104             :     }
+   28105             : 
+   28106           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28107           0 :         work[1] = 1.;
+   28108           0 :         return;
+   28109             :     }
+   28110             : 
+   28111             :     nbmin = 2;
+   28112           0 :     ldwork = nw;
+   28113           0 :     if (nb > 1 && nb < *k) {
+   28114             :         iws = nw * nb;
+   28115           0 :         if (*lwork < iws) {
+   28116           0 :             nb = *lwork / ldwork;
+   28117             :             nbmin = DORMLQ_MINBLOCKSIZE;
+   28118             :         }
+   28119             :     }
+   28120             : 
+   28121           0 :     if (nb < nbmin || nb >= *k) {
+   28122             : 
+   28123             : 
+   28124           0 :         PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28125             :                 c_offset], ldc, &work[1], &iinfo);
+   28126             :     } else {
+   28127             : 
+   28128           0 :         if ((left && notran) || (!left && !notran)) {
+   28129             :             i1 = 1;
+   28130             :             i2 = *k;
+   28131             :             i3 = nb;
+   28132             :         } else {
+   28133           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28134             :             i2 = 1;
+   28135           0 :             i3 = -nb;
+   28136             :         }
+   28137             : 
+   28138           0 :         if (left) {
+   28139           0 :             ni = *n;
+   28140             :             jc = 1;
+   28141             :         } else {
+   28142           0 :             mi = *m;
+   28143             :             ic = 1;
+   28144             :         }
+   28145             : 
+   28146           0 :         if (notran) {
+   28147           0 :             *(unsigned char *)transt = 'T';
+   28148             :         } else {
+   28149           0 :             *(unsigned char *)transt = 'N';
+   28150             :         }
+   28151             : 
+   28152             :         i__1 = i2;
+   28153             :         i__2 = i3;
+   28154           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28155           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28156           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28157             : 
+   28158           0 :             i__4 = nq - i__ + 1;
+   28159           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__4, &ib, &a[i__ + i__ * a_dim1], 
+   28160           0 :                     lda, &tau[i__], t, &ldt);
+   28161           0 :             if (left) {
+   28162             : 
+   28163           0 :                 mi = *m - i__ + 1;
+   28164             :                 ic = i__;
+   28165             :             } else {
+   28166             : 
+   28167           0 :                 ni = *n - i__ + 1;
+   28168             :                 jc = i__;
+   28169             :             }
+   28170             : 
+   28171           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a[i__ 
+   28172           0 :                     + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * c_dim1], 
+   28173             :                     ldc, &work[1], &ldwork);
+   28174             :         }
+   28175             :     }
+   28176           0 :     work[1] = (float) lwkopt;
+   28177           0 :     return;
+   28178             : 
+   28179             : }
+   28180             : 
+   28181             : 
+   28182             : }
+   28183             : }
+   28184             : #include "lapack.h"
+   28185             : #include "lapack_limits.h"
+   28186             : 
+   28187             : #include "blas/blas.h"
+   28188             : namespace PLMD{
+   28189             : namespace lapack{
+   28190             : using namespace blas;
+   28191             : void
+   28192           0 : PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(const char *side, const char *trans, int *m, int *n, 
+   28193             :         int *k, float *a, int *lda, float *tau, float *
+   28194             :         c__, int *ldc, float *work, int *lwork, int *info)
+   28195             : {
+   28196             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28197           0 :     int c__65 = 65;
+   28198             : 
+   28199             :     int i__;
+   28200             :     float t[4160];
+   28201             :     int i1, i2, i3, ib, nb, mi, ni, nq, nw, iws;
+   28202             :     int left;
+   28203             :     int nbmin, iinfo;
+   28204             :     int notran;
+   28205             :     int ldwork, lwkopt;
+   28206             :     int lquery;
+   28207             : 
+   28208             : 
+   28209           0 :     a_dim1 = *lda;
+   28210           0 :     a_offset = 1 + a_dim1;
+   28211           0 :     a -= a_offset;
+   28212             :     --tau;
+   28213             :     c_dim1 = *ldc;
+   28214             :     c_offset = 1 + c_dim1;
+   28215             :     c__ -= c_offset;
+   28216             :     --work;
+   28217             : 
+   28218           0 :     *info = 0;
+   28219           0 :     left = (*side=='L' || *side=='l');
+   28220           0 :     notran = (*trans=='N' || *trans=='n');
+   28221           0 :     lquery = *lwork == -1;
+   28222             : 
+   28223           0 :     if (left) {
+   28224           0 :         nq = *m;
+   28225           0 :         nw = *n;
+   28226             :     } else {
+   28227           0 :         nq = *n;
+   28228           0 :         nw = *m;
+   28229             :     }
+   28230             : 
+   28231             :     nb = DORMQL_BLOCKSIZE;
+   28232           0 :     lwkopt = nw * nb;
+   28233           0 :     work[1] = (float) lwkopt;
+   28234             :     
+   28235           0 :     if (*info != 0) {
+   28236             :         return;
+   28237           0 :     } else if (lquery) {
+   28238             :         return;
+   28239             :     }
+   28240             : 
+   28241           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28242           0 :         work[1] = 1.;
+   28243           0 :         return;
+   28244             :     }
+   28245             : 
+   28246             :     nbmin = 2;
+   28247           0 :     ldwork = nw;
+   28248           0 :     if (nb > 1 && nb < *k) {
+   28249             :         iws = nw * nb;
+   28250           0 :         if (*lwork < iws) {
+   28251           0 :             nb = *lwork / ldwork;
+   28252             :             nbmin = DORMQL_MINBLOCKSIZE;
+   28253             :         }
+   28254             :     }
+   28255             : 
+   28256           0 :     if (nb < nbmin || nb >= *k) {
+   28257             : 
+   28258           0 :         PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28259             :                 c_offset], ldc, &work[1], &iinfo);
+   28260             :     } else {
+   28261             : 
+   28262           0 :         if ((left && notran) || (! left && ! notran)) {
+   28263             :             i1 = 1;
+   28264             :             i2 = *k;
+   28265             :             i3 = nb;
+   28266             :         } else {
+   28267           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28268             :             i2 = 1;
+   28269           0 :             i3 = -nb;
+   28270             :         }
+   28271             : 
+   28272           0 :         if (left) {
+   28273           0 :             ni = *n;
+   28274             :         } else {
+   28275           0 :             mi = *m;
+   28276             :         }
+   28277             : 
+   28278             :         i__1 = i2;
+   28279             :         i__2 = i3;
+   28280           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28281           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28282           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28283             : 
+   28284           0 :             i__4 = nq - *k + i__ + ib - 1;
+   28285           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Backward", "Columnwise", &i__4, &ib, &a[i__ * a_dim1 + 1]
+   28286           0 :                     , lda, &tau[i__], t, &c__65);
+   28287           0 :             if (left) {
+   28288             : 
+   28289           0 :                 mi = *m - *k + i__ + ib - 1;
+   28290             :             } else {
+   28291             : 
+   28292           0 :                 ni = *n - *k + i__ + ib - 1;
+   28293             :             }
+   28294             : 
+   28295           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Backward", "Columnwise", &mi, &ni, &ib, &a[
+   28296             :                     i__ * a_dim1 + 1], lda, t, &c__65, &c__[c_offset], ldc, &
+   28297             :                     work[1], &ldwork);
+   28298             :         }
+   28299             :     }
+   28300           0 :     work[1] = (float) lwkopt;
+   28301           0 :     return;
+   28302             : 
+   28303             : }
+   28304             : 
+   28305             : 
+   28306             : }
+   28307             : }
+   28308             : #include "lapack.h"
+   28309             : #include "lapack_limits.h"
+   28310             : 
+   28311             : #include "blas/blas.h"
+   28312             : namespace PLMD{
+   28313             : namespace lapack{
+   28314             : using namespace blas;
+   28315             : void 
+   28316           0 : PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(const char *side, 
+   28317             :         const char *trans, 
+   28318             :         int *m, 
+   28319             :         int *n, 
+   28320             :         int *k, 
+   28321             :         float *a, 
+   28322             :         int *lda, 
+   28323             :         float *tau, 
+   28324             :         float *c__, 
+   28325             :         int *ldc, 
+   28326             :         float *work, 
+   28327             :         int *lwork, 
+   28328             :         int *info)
+   28329             : {
+   28330             :    int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28331             : 
+   28332             :     int i__;
+   28333             :     float t[4160];
+   28334             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28335             :     int left;
+   28336             :     int nbmin, iinfo;
+   28337             :     int notran;
+   28338             :     int ldwork, lwkopt;
+   28339             :     int lquery;
+   28340           0 :     int ldt = 65;
+   28341             : 
+   28342           0 :     a_dim1 = *lda;
+   28343           0 :     a_offset = 1 + a_dim1;
+   28344           0 :     a -= a_offset;
+   28345             :     --tau;
+   28346           0 :     c_dim1 = *ldc;
+   28347           0 :     c_offset = 1 + c_dim1;
+   28348           0 :     c__ -= c_offset;
+   28349             :     --work;
+   28350             : 
+   28351           0 :     *info = 0;
+   28352           0 :     left = (*side=='L' || *side=='l');
+   28353           0 :     notran = (*trans=='N' || *trans=='n');
+   28354           0 :     lquery = *lwork == -1;
+   28355             : 
+   28356           0 :     if (left) {
+   28357           0 :         nq = *m;
+   28358           0 :         nw = *n;
+   28359             :     } else {
+   28360           0 :         nq = *n;
+   28361           0 :         nw = *m;
+   28362             :     }
+   28363             : 
+   28364             :      ic = jc = 0;
+   28365             :      nb = DORMQR_BLOCKSIZE;
+   28366           0 :      lwkopt = nw * nb;
+   28367           0 :      work[1] = (float) lwkopt;
+   28368             : 
+   28369           0 :     if (*info != 0) {
+   28370             :         return;
+   28371           0 :     } else if (lquery) {
+   28372             :       return;
+   28373             :     }
+   28374             : 
+   28375           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28376           0 :         work[1] = 1.;
+   28377           0 :         return;
+   28378             :     }
+   28379             : 
+   28380             :     nbmin = 2;
+   28381           0 :     ldwork = nw;
+   28382           0 :     if (nb > 1 && nb < *k) {
+   28383             :         iws = nw * nb;
+   28384           0 :         if (*lwork < iws) {
+   28385           0 :             nb = *lwork / ldwork;
+   28386             :             nbmin = DORMQR_MINBLOCKSIZE;
+   28387             :         }
+   28388             :     }
+   28389             : 
+   28390           0 :     if (nb < nbmin || nb >= *k) {
+   28391             : 
+   28392           0 :         PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28393             :                 c_offset], ldc, &work[1], &iinfo);
+   28394             :     } else {
+   28395             : 
+   28396           0 :         if ((left && !notran) || (!left && notran)) {
+   28397             :             i1 = 1;
+   28398             :             i2 = *k;
+   28399             :             i3 = nb;
+   28400             :         } else {
+   28401           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28402             :             i2 = 1;
+   28403           0 :             i3 = -nb;
+   28404             :         }
+   28405             : 
+   28406           0 :         if (left) {
+   28407           0 :             ni = *n;
+   28408             :             jc = 1;
+   28409             :         } else {
+   28410           0 :             mi = *m;
+   28411             :             ic = 1;
+   28412             :         }
+   28413             : 
+   28414             :         i__1 = i2;
+   28415             :         i__2 = i3;
+   28416           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28417           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28418           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28419             : 
+   28420           0 :             i__4 = nq - i__ + 1;
+   28421           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__4, &ib, &a[i__ + i__ * 
+   28422           0 :                     a_dim1], lda, &tau[i__], t, &ldt);
+   28423           0 :             if (left) {
+   28424             : 
+   28425           0 :                 mi = *m - i__ + 1;
+   28426             :                 ic = i__;
+   28427             :             } else {
+   28428           0 :                 ni = *n - i__ + 1;
+   28429             :                 jc = i__;
+   28430             :             }
+   28431             : 
+   28432           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Forward", "Columnwise", &mi, &ni, &ib, &a[
+   28433           0 :                     i__ + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * 
+   28434             :                     c_dim1], ldc, &work[1], &ldwork);
+   28435             :         }
+   28436             :     }
+   28437           0 :     work[1] = (float) lwkopt;
+   28438           0 :     return;
+   28439             : 
+   28440             : 
+   28441             : }
+   28442             : 
+   28443             : 
+   28444             : }
+   28445             : }
+   28446             : #include "lapack.h"
+   28447             : #include "lapack_limits.h"
+   28448             : 
+   28449             : 
+   28450             : #include "blas/blas.h"
+   28451             : namespace PLMD{
+   28452             : namespace lapack{
+   28453             : using namespace blas;
+   28454             : void
+   28455           0 : PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)(const char *side, 
+   28456             :         const char *uplo,
+   28457             :         const char *trans, 
+   28458             :         int *m, 
+   28459             :         int *n,
+   28460             :         float *a, 
+   28461             :         int *lda, 
+   28462             :         float *tau, 
+   28463             :         float *c__, 
+   28464             :         int *ldc,
+   28465             :         float *work, 
+   28466             :         int *lwork, 
+   28467             :         int *info)
+   28468             : {
+   28469             :     int a_dim1, a_offset, c_dim1, c_offset, i__2;
+   28470             : 
+   28471             :     int i1, i2, nb, mi, ni, nq, nw;
+   28472             :     int left;
+   28473             :     int iinfo;
+   28474             :     int upper;
+   28475             :     int lwkopt;
+   28476             :     int lquery;
+   28477             : 
+   28478             : 
+   28479           0 :     a_dim1 = *lda;
+   28480           0 :     a_offset = 1 + a_dim1;
+   28481           0 :     a -= a_offset;
+   28482             :     --tau;
+   28483           0 :     c_dim1 = *ldc;
+   28484           0 :     c_offset = 1 + c_dim1;
+   28485           0 :     c__ -= c_offset;
+   28486             :     --work;
+   28487             : 
+   28488           0 :     *info = 0;
+   28489           0 :     left = (*side=='L' || *side=='l');
+   28490           0 :     upper = (*uplo=='U' || *uplo=='u');
+   28491           0 :     lquery = *lwork == -1;
+   28492             : 
+   28493           0 :     if (left) {
+   28494           0 :         nq = *m;
+   28495           0 :         nw = *n;
+   28496             :     } else {
+   28497           0 :         nq = *n;
+   28498           0 :         nw = *m;
+   28499             :     }
+   28500             : 
+   28501             : 
+   28502             :     nb = DORMQL_BLOCKSIZE;
+   28503           0 :     lwkopt = nw * nb;
+   28504           0 :     work[1] = (float) lwkopt;
+   28505             :     
+   28506           0 :     if (*info != 0) {
+   28507             :         i__2 = -(*info);
+   28508             :         return;
+   28509           0 :     } else if (lquery) {
+   28510             :         return;
+   28511             :     }
+   28512             : 
+   28513           0 :     if (*m == 0 || *n == 0 || nq == 1) {
+   28514           0 :         work[1] = 1.;
+   28515           0 :         return;
+   28516             :     }
+   28517             : 
+   28518           0 :     if (left) {
+   28519           0 :         mi = *m - 1;
+   28520           0 :         ni = *n;
+   28521             :     } else {
+   28522           0 :         mi = *m;
+   28523           0 :         ni = *n - 1;
+   28524             :     }
+   28525             : 
+   28526           0 :     if (upper) {
+   28527           0 :         i__2 = nq - 1;
+   28528           0 :         PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(side, trans, &mi, &ni, &i__2, &a[(a_dim1 << 1) + 1], lda, &
+   28529             :                 tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo);
+   28530             :     } else {
+   28531           0 :         if (left) {
+   28532             :             i1 = 2;
+   28533             :             i2 = 1;
+   28534             :         } else {
+   28535             :             i1 = 1;
+   28536             :             i2 = 2;
+   28537             :         }
+   28538           0 :         i__2 = nq - 1;
+   28539           0 :         PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__2, &a[a_dim1 + 2], lda, &tau[1], &
+   28540           0 :                 c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   28541             :     }
+   28542           0 :     work[1] = (float) lwkopt;
+   28543           0 :     return;
+   28544             : 
+   28545             : }
+   28546             : 
+   28547             : 
+   28548             : }
+   28549             : }
+   28550             : #include <cmath>
+   28551             : #include "lapack.h"
+   28552             : #include "lapack_limits.h"
+   28553             : 
+   28554             : #include "real.h"
+   28555             : 
+   28556             : #include "blas/blas.h"
+   28557             : namespace PLMD{
+   28558             : namespace lapack{
+   28559             : using namespace blas;
+   28560             : void
+   28561           0 : PLUMED_BLAS_F77_FUNC(sstebz,SSTEBZ)(const char *range, 
+   28562             :                         const char *order,
+   28563             :                         int *n,
+   28564             :                         float *vl, 
+   28565             :                         float *vu, 
+   28566             :                         int *il,
+   28567             :                         int *iu,
+   28568             :                         float *abstol, 
+   28569             :                         float *d__,
+   28570             :                         float *e,
+   28571             :                         int *m, 
+   28572             :                         int *nsplit, 
+   28573             :                         float *w,
+   28574             :                         int *iblock,
+   28575             :                         int *isplit,
+   28576             :                         float *work, 
+   28577             :                         int *iwork, 
+   28578             :                         int *info)
+   28579             : {
+   28580             :     int i__1, i__2, i__3;
+   28581             :     float d__1, d__2, d__3, d__4, d__5;
+   28582           0 :     int c__1 = 1;
+   28583           0 :     int c__3 = 3;
+   28584           0 :     int c__2 = 2;
+   28585           0 :     int c__0 = 0;
+   28586             : 
+   28587             :     int j, ib, jb, ie, je, nb;
+   28588             :     float gl;
+   28589             :     int im, in;
+   28590             :     float gu;
+   28591             :     int iw;
+   28592             :     float wl, wu;
+   28593             :     int nwl;
+   28594             :     float ulp, wlu, wul;
+   28595             :     int nwu;
+   28596             :     float tmp1, tmp2;
+   28597             :     int iend, ioff, iout, itmp1, jdisc;
+   28598             :     int iinfo;
+   28599             :     float atoli;
+   28600             :     int iwoff;
+   28601             :     float bnorm;
+   28602             :     int itmax;
+   28603             :     float wkill, rtoli, tnorm;
+   28604             :     int ibegin;
+   28605             :     int irange, idiscl;
+   28606             :     int idumma[1];
+   28607             :     int idiscu, iorder;
+   28608             :     int ncnvrg;
+   28609             :     float pivmin;
+   28610             :     int toofew;
+   28611             :     const float safemn = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   28612             : 
+   28613           0 :     --iwork;
+   28614           0 :     --work;
+   28615           0 :     --isplit;
+   28616           0 :     --iblock;
+   28617           0 :     --w;
+   28618           0 :     --e;
+   28619           0 :     --d__;
+   28620             : 
+   28621           0 :     *info = 0;
+   28622             : 
+   28623           0 :     if (*range=='A' || *range=='a') {
+   28624             :         irange = 1;
+   28625           0 :     } else if (*range=='V' || *range=='v') {
+   28626             :         irange = 2;
+   28627             :     } else if (*range=='I' || *range=='i') {
+   28628             :         irange = 3;
+   28629             :     } else {
+   28630             :         irange = 0;
+   28631             :     }
+   28632             : 
+   28633           0 :     if (*order=='B' || *order=='b') {
+   28634             :         iorder = 2;
+   28635           0 :     } else if (*order=='E' || *order=='e') {
+   28636             :         iorder = 1;
+   28637             :     } else {
+   28638             :         iorder = 0;
+   28639             :     }
+   28640             : 
+   28641           0 :     if (irange <= 0) {
+   28642           0 :         *info = -1;
+   28643           0 :     } else if (iorder <= 0) {
+   28644           0 :         *info = -2;
+   28645           0 :     } else if (*n < 0) {
+   28646           0 :         *info = -3;
+   28647           0 :     } else if (irange == 2) {
+   28648           0 :         if (*vl >= *vu) {
+   28649           0 :             *info = -5;
+   28650             :         }
+   28651           0 :     } else if (irange == 3 && (*il < 1 || *il > (*n))) {
+   28652           0 :         *info = -6;
+   28653           0 :     } else if (irange == 3 && (*iu < ((*n<*il) ? *n : *il) || *iu > *n)) {
+   28654           0 :         *info = -7;
+   28655             :     }
+   28656             : 
+   28657           0 :     if (*info != 0) {
+   28658             :         return;
+   28659             :     }
+   28660             : 
+   28661           0 :     *info = 0;
+   28662             :     ncnvrg = 0;
+   28663             :     toofew = 0;
+   28664             : 
+   28665           0 :     *m = 0;
+   28666           0 :     if (*n == 0) {
+   28667             :         return;
+   28668             :     }
+   28669             : 
+   28670           0 :     if (irange == 3 && *il == 1 && *iu == *n) {
+   28671             :         irange = 1;
+   28672             :     }
+   28673             : 
+   28674             :     ulp = 2*PLUMED_GMX_FLOAT_EPS;
+   28675           0 :     rtoli = ulp * 2.;
+   28676             :     nb = DSTEBZ_BLOCKSIZE;
+   28677             :     // cppcheck-suppress knownConditionTrueFalse
+   28678             :     if (nb <= 1) {
+   28679           0 :         nb = 0;
+   28680             :     }
+   28681             : 
+   28682           0 :     if (*n == 1) {
+   28683           0 :         *nsplit = 1;
+   28684           0 :         isplit[1] = 1;
+   28685           0 :         if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
+   28686           0 :             *m = 0;
+   28687             :         } else {
+   28688           0 :             w[1] = d__[1];
+   28689           0 :             iblock[1] = 1;
+   28690           0 :             *m = 1;
+   28691             :         }
+   28692           0 :         return;
+   28693             :     }
+   28694             : 
+   28695           0 :     *nsplit = 1;
+   28696           0 :     work[*n] = 0.;
+   28697           0 :     pivmin = 1.;
+   28698           0 :     i__1 = *n;
+   28699           0 :     for (j = 2; j <= i__1; ++j) {
+   28700           0 :         d__1 = e[j - 1];
+   28701           0 :         tmp1 = d__1 * d__1;
+   28702             :         d__2 = ulp;
+   28703           0 :         if (std::abs(d__[j] * d__[j - 1]) * (d__2 * d__2) + safemn 
+   28704             :                 > tmp1) {
+   28705           0 :             isplit[*nsplit] = j - 1;
+   28706           0 :             ++(*nsplit);
+   28707           0 :             work[j - 1] = 0.;
+   28708             :         } else {
+   28709           0 :             work[j - 1] = tmp1;
+   28710           0 :             pivmin = (pivmin>tmp1) ? pivmin : tmp1;
+   28711             :         }
+   28712             :     }
+   28713           0 :     isplit[*nsplit] = *n;
+   28714           0 :     pivmin *= safemn;
+   28715             : 
+   28716           0 :     if (irange == 3) {
+   28717             : 
+   28718           0 :         gu = d__[1];
+   28719             :         gl = d__[1];
+   28720             :         tmp1 = 0.;
+   28721             : 
+   28722             :         i__1 = *n - 1;
+   28723           0 :         for (j = 1; j <= i__1; ++j) {
+   28724           0 :             tmp2 =  std::sqrt(work[j]);
+   28725           0 :             d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28726           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28727           0 :             d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28728           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28729             :             tmp1 = tmp2;
+   28730             :         }
+   28731             : 
+   28732           0 :         d__1 = gu, d__2 = d__[*n] + tmp1;
+   28733           0 :         gu = (d__1>d__2) ? d__1 : d__2;
+   28734           0 :         d__1 = gl, d__2 = d__[*n] - tmp1;
+   28735           0 :         gl = (d__1<d__2) ? d__1 : d__2;
+   28736             :         d__1 = std::abs(gl);
+   28737             :         d__2 = std::abs(gu);
+   28738           0 :         tnorm = (d__1>d__2) ? d__1 : d__2;
+   28739           0 :         gl = gl - tnorm * 2. * ulp * *n - pivmin * 4.;
+   28740           0 :         gu = gu + tnorm * 2. * ulp * *n + pivmin * 2.;
+   28741             : 
+   28742           0 :         itmax = (int) ((std::log(tnorm + pivmin) - std::log(pivmin)) / std::log(2.)) + 2;
+   28743           0 :         if (*abstol <= 0.) {
+   28744           0 :             atoli = ulp * tnorm;
+   28745             :         } else {
+   28746           0 :             atoli = *abstol;
+   28747             :         }
+   28748             : 
+   28749           0 :         work[*n + 1] = gl;
+   28750           0 :         work[*n + 2] = gl;
+   28751           0 :         work[*n + 3] = gu;
+   28752           0 :         work[*n + 4] = gu;
+   28753           0 :         work[*n + 5] = gl;
+   28754           0 :         work[*n + 6] = gu;
+   28755           0 :         iwork[1] = -1;
+   28756           0 :         iwork[2] = -1;
+   28757           0 :         iwork[3] = *n + 1;
+   28758           0 :         iwork[4] = *n + 1;
+   28759           0 :         iwork[5] = *il - 1;
+   28760           0 :         iwork[6] = *iu;
+   28761             : 
+   28762           0 :         PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, 
+   28763           0 :                 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n 
+   28764           0 :                 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
+   28765             : 
+   28766           0 :         if (iwork[6] == *iu) {
+   28767           0 :             wl = work[*n + 1];
+   28768           0 :             wlu = work[*n + 3];
+   28769           0 :             nwl = iwork[1];
+   28770           0 :             wu = work[*n + 4];
+   28771           0 :             wul = work[*n + 2];
+   28772           0 :             nwu = iwork[4];
+   28773             :         } else {
+   28774           0 :             wl = work[*n + 2];
+   28775           0 :             wlu = work[*n + 4];
+   28776           0 :             nwl = iwork[2];
+   28777           0 :             wu = work[*n + 3];
+   28778           0 :             wul = work[*n + 1];
+   28779           0 :             nwu = iwork[3];
+   28780             :         }
+   28781             : 
+   28782           0 :         if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
+   28783           0 :             *info = 4;
+   28784           0 :             return;
+   28785             :         }
+   28786             :     } else {
+   28787             : 
+   28788             : 
+   28789             :       /* avoid warnings for high gcc optimization */
+   28790             :       wlu = wul = 1.0;
+   28791             : 
+   28792           0 :         d__3 = std::abs(d__[1]) + std::abs(e[1]);
+   28793           0 :         d__4 = std::abs(d__[*n]) + std::abs(e[*n - 1]);
+   28794           0 :         tnorm = (d__3>d__4) ? d__3 : d__4;
+   28795             : 
+   28796             :         i__1 = *n - 1;
+   28797           0 :         for (j = 2; j <= i__1; ++j) {
+   28798             :             d__4 = tnorm;
+   28799           0 :             d__5 = std::abs(d__[j]) + std::abs(e[j - 1]) + std::abs(e[j]);
+   28800           0 :             tnorm = (d__4>d__5) ? d__4 : d__5;
+   28801             :         }
+   28802             : 
+   28803           0 :         if (*abstol <= 0.) {
+   28804           0 :             atoli = ulp * tnorm;
+   28805             :         } else {
+   28806           0 :             atoli = *abstol;
+   28807             :         }
+   28808             : 
+   28809           0 :         if (irange == 2) {
+   28810           0 :             wl = *vl;
+   28811           0 :             wu = *vu;
+   28812             :         } else {
+   28813             :             wl = 0.;
+   28814             :             wu = 0.;
+   28815             :         }
+   28816             :     }
+   28817             : 
+   28818           0 :     *m = 0;
+   28819             :     iend = 0;
+   28820           0 :     *info = 0;
+   28821             :     nwl = 0;
+   28822             :     nwu = 0;
+   28823             : 
+   28824           0 :     i__1 = *nsplit;
+   28825           0 :     for (jb = 1; jb <= i__1; ++jb) {
+   28826             :         ioff = iend;
+   28827           0 :         ibegin = ioff + 1;
+   28828           0 :         iend = isplit[jb];
+   28829           0 :         in = iend - ioff;
+   28830             : 
+   28831           0 :         if (in == 1) {
+   28832             : 
+   28833           0 :             if (irange == 1 || wl >= d__[ibegin] - pivmin) {
+   28834           0 :                 ++nwl;
+   28835             :             }
+   28836           0 :             if (irange == 1 || wu >= d__[ibegin] - pivmin) {
+   28837           0 :                 ++nwu;
+   28838             :             }
+   28839           0 :             if (irange == 1 || ((wl < d__[ibegin] - pivmin) && (wu >= d__[ibegin] - pivmin))) {
+   28840           0 :                 ++(*m);
+   28841           0 :                 w[*m] = d__[ibegin];
+   28842           0 :                 iblock[*m] = jb;
+   28843             :             }
+   28844             :         } else {
+   28845             : 
+   28846           0 :             gu = d__[ibegin];
+   28847             :             gl = d__[ibegin];
+   28848             :             tmp1 = 0.;
+   28849             : 
+   28850             :             i__2 = iend - 1;
+   28851           0 :             for (j = ibegin; j <= i__2; ++j) {
+   28852           0 :                 tmp2 = std::abs(e[j]);
+   28853           0 :                 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28854           0 :                 gu = (d__1>d__2) ? d__1 : d__2;
+   28855           0 :                 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28856           0 :                 gl = (d__1<d__2) ? d__1 : d__2;
+   28857             :                 tmp1 = tmp2;
+   28858             :             }
+   28859             : 
+   28860           0 :             d__1 = gu, d__2 = d__[iend] + tmp1;
+   28861           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28862           0 :             d__1 = gl, d__2 = d__[iend] - tmp1;
+   28863           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28864             :             d__1 = std::abs(gl);
+   28865             :             d__2 = std::abs(gu);
+   28866           0 :             bnorm = (d__1>d__2) ? d__1 : d__2;
+   28867           0 :             gl = gl - bnorm * 2. * ulp * in - pivmin * 2.;
+   28868           0 :             gu = gu + bnorm * 2. * ulp * in + pivmin * 2.;
+   28869             : 
+   28870           0 :             if (*abstol <= 0.) {
+   28871             :                 d__1 = std::abs(gl);
+   28872             :                 d__2 = std::abs(gu);
+   28873           0 :                 atoli = ulp * ((d__1>d__2) ? d__1 : d__2);
+   28874             :             } else {
+   28875           0 :                 atoli = *abstol;
+   28876             :             }
+   28877             : 
+   28878           0 :             if (irange > 1) {
+   28879           0 :                 if (gu < wl) {
+   28880           0 :                     nwl += in;
+   28881           0 :                     nwu += in;
+   28882             :                 }
+   28883             :                 gl = (gl>wl) ? gl : wl;
+   28884             :                 gu = (gu<wu) ? gu : wu;
+   28885             :                 if (gl >= gu) {
+   28886             :                 }
+   28887           0 :                 continue;
+   28888             :             }
+   28889             : 
+   28890           0 :             work[*n + 1] = gl;
+   28891           0 :             work[*n + in + 1] = gu;
+   28892           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28893             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28894           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
+   28895           0 :                     w[*m + 1], &iblock[*m + 1], &iinfo);
+   28896             : 
+   28897           0 :             nwl += iwork[1];
+   28898           0 :             nwu += iwork[in + 1];
+   28899           0 :             iwoff = *m - iwork[1];
+   28900             : 
+   28901           0 :             itmax = (int) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
+   28902           0 :                     ) + 2;
+   28903           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28904             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28905           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
+   28906           0 :                      &w[*m + 1], &iblock[*m + 1], &iinfo);
+   28907             : 
+   28908           0 :             i__2 = iout;
+   28909           0 :             for (j = 1; j <= i__2; ++j) {
+   28910           0 :                 tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
+   28911             : 
+   28912           0 :                 if (j > iout - iinfo) {
+   28913             :                     ncnvrg = 1;
+   28914           0 :                     ib = -jb;
+   28915             :                 } else {
+   28916             :                     ib = jb;
+   28917             :                 }
+   28918           0 :                 i__3 = iwork[j + in] + iwoff;
+   28919           0 :                 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
+   28920           0 :                     w[je] = tmp1;
+   28921           0 :                     iblock[je] = ib;
+   28922             :                 }
+   28923             :             }
+   28924             : 
+   28925           0 :             *m += im;
+   28926             :         }
+   28927             :     }
+   28928             : 
+   28929           0 :     if (irange == 3) {
+   28930           0 :         im = 0;
+   28931           0 :         idiscl = *il - 1 - nwl;
+   28932           0 :         idiscu = nwu - *iu;
+   28933             : 
+   28934           0 :         if (idiscl > 0 || idiscu > 0) {
+   28935           0 :             i__1 = *m;
+   28936           0 :             for (je = 1; je <= i__1; ++je) {
+   28937           0 :                 if (w[je] <= wlu && idiscl > 0) {
+   28938           0 :                     --idiscl;
+   28939           0 :                 } else if (w[je] >= wul && idiscu > 0) {
+   28940           0 :                     --idiscu;
+   28941             :                 } else {
+   28942           0 :                     ++im;
+   28943           0 :                     w[im] = w[je];
+   28944           0 :                     iblock[im] = iblock[je];
+   28945             :                 }
+   28946             :             }
+   28947           0 :             *m = im;
+   28948             :         }
+   28949           0 :         if (idiscl > 0 || idiscu > 0) {
+   28950             : 
+   28951           0 :             if (idiscl > 0) {
+   28952             :                 wkill = wu;
+   28953             :                 i__1 = idiscl;
+   28954           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28955             :                     iw = 0;
+   28956           0 :                     i__2 = *m;
+   28957           0 :                     for (je = 1; je <= i__2; ++je) {
+   28958           0 :                         if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
+   28959             :                             iw = je;
+   28960             :                             wkill = w[je];
+   28961             :                         }
+   28962             :                     }
+   28963           0 :                     iblock[iw] = 0;
+   28964             :                 }
+   28965             :             }
+   28966           0 :             if (idiscu > 0) {
+   28967             : 
+   28968             :                 wkill = wl;
+   28969             :                 i__1 = idiscu;
+   28970           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28971             :                     iw = 0;
+   28972           0 :                     i__2 = *m;
+   28973           0 :                     for (je = 1; je <= i__2; ++je) {
+   28974           0 :                         if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
+   28975             :                             iw = je;
+   28976             :                             wkill = w[je];
+   28977             :                         }
+   28978             :                     }
+   28979           0 :                     iblock[iw] = 0;
+   28980             :                 }
+   28981             :             }
+   28982           0 :             im = 0;
+   28983           0 :             i__1 = *m;
+   28984           0 :             for (je = 1; je <= i__1; ++je) {
+   28985           0 :                 if (iblock[je] != 0) {
+   28986           0 :                     ++im;
+   28987           0 :                     w[im] = w[je];
+   28988           0 :                     iblock[im] = iblock[je];
+   28989             :                 }
+   28990             :             }
+   28991           0 :             *m = im;
+   28992             :         }
+   28993           0 :         if (idiscl < 0 || idiscu < 0) {
+   28994             :             toofew = 1;
+   28995             :         }
+   28996             :     }
+   28997             : 
+   28998           0 :     if (iorder == 1 && *nsplit > 1) {
+   28999           0 :         i__1 = *m - 1;
+   29000           0 :         for (je = 1; je <= i__1; ++je) {
+   29001             :             ie = 0;
+   29002           0 :             tmp1 = w[je];
+   29003           0 :             i__2 = *m;
+   29004           0 :             for (j = je + 1; j <= i__2; ++j) {
+   29005           0 :                 if (w[j] < tmp1) {
+   29006             :                     ie = j;
+   29007             :                     tmp1 = w[j];
+   29008             :                 }
+   29009             :             }
+   29010             : 
+   29011           0 :             if (ie != 0) {
+   29012           0 :                 itmp1 = iblock[ie];
+   29013           0 :                 w[ie] = w[je];
+   29014           0 :                 iblock[ie] = iblock[je];
+   29015           0 :                 w[je] = tmp1;
+   29016           0 :                 iblock[je] = itmp1;
+   29017             :             }
+   29018             :         }
+   29019             :     }
+   29020             : 
+   29021           0 :     *info = 0;
+   29022           0 :     if (ncnvrg) {
+   29023           0 :         ++(*info);
+   29024             :     }
+   29025           0 :     if (toofew) {
+   29026           0 :         *info += 2;
+   29027             :     }
+   29028             :     return;
+   29029             : 
+   29030             : }
+   29031             : 
+   29032             : 
+   29033             : }
+   29034             : }
+   29035             : #include <cmath>
+   29036             : #include "blas/blas.h"
+   29037             : #include "lapack.h"
+   29038             : #include "lapack_limits.h"
+   29039             : 
+   29040             : #include "real.h"
+   29041             : 
+   29042             : #include "blas/blas.h"
+   29043             : namespace PLMD{
+   29044             : namespace lapack{
+   29045             : using namespace blas;
+   29046             : void
+   29047           0 : PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(const char *jobz, 
+   29048             :         const char *range, 
+   29049             :         int *n, 
+   29050             :         float *d__, 
+   29051             :         float *e, 
+   29052             :         float *vl, 
+   29053             :         float *vu, 
+   29054             :         int *il, 
+   29055             :         int *iu, 
+   29056             :         float *abstol, 
+   29057             :         int *m, 
+   29058             :         float *w, 
+   29059             :         float *z__, 
+   29060             :         int *ldz, 
+   29061             :         int *isuppz,
+   29062             :         float *work, 
+   29063             :         int *lwork, 
+   29064             :         int *iwork, 
+   29065             :         int *liwork, 
+   29066             :         int *info)
+   29067             : {
+   29068             :     int z_dim1, z_offset, i__1, i__2;
+   29069             :     float d__1, d__2;
+   29070           0 :     int c__1 = 1;
+   29071             : 
+   29072             :     int i__, j;
+   29073             :     int jj;
+   29074             :     float eps, tol, tmp, rmin, rmax;
+   29075             :     int itmp;
+   29076             :     float tnrm;
+   29077             :     float scale;
+   29078             :     int iinfo, iindw;
+   29079             :     int lwmin;
+   29080             :     int wantz;
+   29081             :     int iindbl;
+   29082             :     int valeig,alleig,indeig;
+   29083             :     float safmin,minval;
+   29084             :     float bignum;
+   29085             :     int iindwk, indgrs;
+   29086             :     float thresh;
+   29087             :     int iinspl, indwrk, liwmin, nsplit;
+   29088             :     float smlnum;
+   29089             :     int lquery;
+   29090             : 
+   29091             : 
+   29092             :     --d__;
+   29093             :     --e;
+   29094           0 :     --w;
+   29095           0 :     z_dim1 = *ldz;
+   29096           0 :     z_offset = 1 + z_dim1;
+   29097           0 :     z__ -= z_offset;
+   29098           0 :     --isuppz;
+   29099           0 :     --work;
+   29100           0 :     --iwork;
+   29101             : 
+   29102           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   29103           0 :     alleig = (*range=='A' || *range=='a');
+   29104           0 :     valeig = (*range=='V' || *range=='v');
+   29105           0 :     indeig = (*range=='I' || *range=='i');
+   29106             : 
+   29107           0 :     lquery = *lwork == -1 || *liwork == -1;
+   29108           0 :     lwmin = *n * 17;
+   29109           0 :     liwmin = *n * 10;
+   29110             : 
+   29111           0 :     *info = 0;
+   29112           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   29113           0 :         *info = -1;
+   29114           0 :     } else if (! (alleig || valeig || indeig)) {
+   29115           0 :         *info = -2;
+   29116           0 :     } else if (*n < 0) {
+   29117           0 :         *info = -3;
+   29118           0 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   29119           0 :         *info = -7;
+   29120           0 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   29121           0 :         *info = -8;
+   29122           0 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   29123           0 :         *info = -9;
+   29124           0 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   29125           0 :         *info = -14;
+   29126           0 :     } else if (*lwork < lwmin && ! lquery) {
+   29127           0 :         *info = -17;
+   29128           0 :     } else if (*liwork < liwmin && ! lquery) {
+   29129           0 :         *info = -19;
+   29130             :     }
+   29131           0 :     if (*info == 0) {
+   29132           0 :         work[1] = (float) lwmin;
+   29133           0 :         iwork[1] = liwmin;
+   29134             :     }
+   29135             : 
+   29136           0 :     if (*info != 0) {
+   29137             :         i__1 = -(*info);
+   29138             :         return;
+   29139           0 :     } else if (lquery) {
+   29140             :         return;
+   29141             :     }
+   29142             : 
+   29143           0 :     *m = 0;
+   29144           0 :     if (*n == 0) {
+   29145             :         return;
+   29146             :     }
+   29147             : 
+   29148           0 :     if (*n == 1) {
+   29149           0 :         if (alleig || indeig) {
+   29150           0 :             *m = 1;
+   29151           0 :             w[1] = d__[1];
+   29152             :         } else {
+   29153           0 :             if (*vl < d__[1] && *vu >= d__[1]) {
+   29154           0 :                 *m = 1;
+   29155           0 :                 w[1] = d__[1];
+   29156             :             }
+   29157             :         }
+   29158           0 :         if (wantz) {
+   29159           0 :             z__[z_dim1 + 1] = 1.;
+   29160             :         }
+   29161           0 :         return;
+   29162             :     }
+   29163             : 
+   29164             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29165             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29166             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29167             :     smlnum = safmin / eps;
+   29168             :     bignum = 1. / smlnum;
+   29169             :     rmin =  std::sqrt(smlnum);
+   29170           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   29171             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   29172           0 :     scale = 1.;
+   29173           0 :     tnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   29174           0 :     if (tnrm > 0. && tnrm < rmin) {
+   29175           0 :         scale = rmin / tnrm;
+   29176           0 :     } else if (tnrm > rmax) {
+   29177           0 :         scale = rmax / tnrm;
+   29178             :     }
+   29179           0 :     if ( std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29180           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(n, &scale, &d__[1], &c__1);
+   29181           0 :         i__1 = *n - 1;
+   29182           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &scale, &e[1], &c__1);
+   29183           0 :         tnrm *= scale;
+   29184             :     }
+   29185             :     indgrs = 1;
+   29186           0 :     indwrk = (*n << 1) + 1;
+   29187             : 
+   29188             :     iinspl = 1;
+   29189           0 :     iindbl = *n + 1;
+   29190             :     iindw = (*n << 1) + 1;
+   29191           0 :     iindwk = *n * 3 + 1;
+   29192             : 
+   29193           0 :     thresh = eps * tnrm;
+   29194           0 :     PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   29195           0 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   29196           0 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   29197             :     
+   29198           0 :     if (iinfo != 0) {
+   29199           0 :         *info = 1;
+   29200           0 :         return;
+   29201             :     }
+   29202             : 
+   29203           0 :     if (wantz) {
+   29204           0 :         d__1 = *abstol, d__2 = (float) (*n) * eps;
+   29205           0 :         tol = (d__1>d__2) ? d__1 : d__2;
+   29206           0 :         PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(n, &d__[1], &e[1], &iwork[iinspl], m, &w[1], &iwork[iindbl], &
+   29207             :                 iwork[iindw], &work[indgrs], &tol, &z__[z_offset], ldz, &
+   29208             :                 isuppz[1], &work[indwrk], &iwork[iindwk], &iinfo);
+   29209           0 :         if (iinfo != 0) {
+   29210           0 :             *info = 2;
+   29211           0 :             return;
+   29212             :         }
+   29213             :     }
+   29214             : 
+   29215           0 :     i__1 = *m;
+   29216           0 :     for (j = 1; j <= i__1; ++j) {
+   29217           0 :         itmp = iwork[iindbl + j - 1];
+   29218           0 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   29219             :     } 
+   29220             : 
+   29221           0 :     if (std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29222           0 :         d__1 = 1. / scale;
+   29223           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(m, &d__1, &w[1], &c__1);
+   29224             :     }
+   29225           0 :     if (nsplit > 1) {
+   29226           0 :         i__1 = *m - 1;
+   29227           0 :         for (j = 1; j <= i__1; ++j) {
+   29228             :             i__ = 0;
+   29229           0 :             tmp = w[j];
+   29230           0 :             i__2 = *m;
+   29231           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   29232           0 :                 if (w[jj] < tmp) {
+   29233             :                     i__ = jj;
+   29234             :                     tmp = w[jj];
+   29235             :                 }
+   29236             :             }
+   29237           0 :             if (i__ != 0) {
+   29238           0 :                 w[i__] = w[j];
+   29239           0 :                 w[j] = tmp;
+   29240           0 :                 if (wantz) {
+   29241           0 :                     PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 
+   29242           0 :                             + 1], &c__1);
+   29243           0 :                     itmp = isuppz[(i__ << 1) - 1];
+   29244           0 :                     isuppz[(i__ << 1) - 1] = isuppz[(j << 1) - 1];
+   29245           0 :                     isuppz[(j << 1) - 1] = itmp;
+   29246           0 :                     itmp = isuppz[i__ * 2];
+   29247           0 :                     isuppz[i__ * 2] = isuppz[j * 2];
+   29248           0 :                     isuppz[j * 2] = itmp;
+   29249             :                 }
+   29250             :             }
+   29251             :         }
+   29252             :     }
+   29253             : 
+   29254           0 :     work[1] = (float) lwmin;
+   29255           0 :     iwork[1] = liwmin;
+   29256           0 :     return;
+   29257             : 
+   29258             : } 
+   29259             : }
+   29260             : }
+   29261             : #include <cmath>
+   29262             : #include "blas/blas.h"
+   29263             : #include "lapack.h"
+   29264             : #include "lapack_limits.h"
+   29265             : 
+   29266             : #include "real.h"
+   29267             : 
+   29268             : #include "blas/blas.h"
+   29269             : namespace PLMD{
+   29270             : namespace lapack{
+   29271             : using namespace blas;
+   29272             : void
+   29273           0 : PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(int *n, 
+   29274             :         float *d__, 
+   29275             :         float *e, 
+   29276             :         int *m, 
+   29277             :         float *w, 
+   29278             :         int *iblock,
+   29279             :         int *isplit, 
+   29280             :         float *z__,
+   29281             :         int *ldz, 
+   29282             :         float *work,
+   29283             :         int *iwork, 
+   29284             :         int *ifail,
+   29285             :         int *info)
+   29286             : {
+   29287             :     int z_dim1, z_offset, i__1, i__2, i__3;
+   29288             :     float d__2, d__3, d__4, d__5;
+   29289             : 
+   29290             :     int i__, j, b1, j1, bn;
+   29291             :     float xj, scl, eps, sep, nrm, tol;
+   29292             :     int its;
+   29293             :     float xjm, ztr, eps1;
+   29294             :     int jblk, nblk;
+   29295             :     int jmax;
+   29296             : 
+   29297             :     int iseed[4], gpind, iinfo;
+   29298             :     float ortol;
+   29299             :     int indrv1, indrv2, indrv3, indrv4, indrv5;
+   29300             :     int nrmchk;
+   29301             :     int blksiz;
+   29302             :     float onenrm, dtpcrt, pertol;
+   29303           0 :     int c__2 = 2;
+   29304           0 :     int c__1 = 1;
+   29305           0 :     int c_n1 = -1;
+   29306             : 
+   29307           0 :     --d__;
+   29308           0 :     --e;
+   29309           0 :     --w;
+   29310           0 :     --iblock;
+   29311           0 :     --isplit;
+   29312           0 :     z_dim1 = *ldz;
+   29313           0 :     z_offset = 1 + z_dim1;
+   29314           0 :     z__ -= z_offset;
+   29315           0 :     --work;
+   29316             :     --iwork;
+   29317           0 :     --ifail;
+   29318             : 
+   29319           0 :     *info = 0;
+   29320             : 
+   29321             :     xjm = 0.0;
+   29322           0 :     i__1 = *m;
+   29323           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29324           0 :         ifail[i__] = 0;
+   29325             :     }
+   29326             : 
+   29327           0 :     if (*n < 0) {
+   29328           0 :         *info = -1;
+   29329           0 :     } else if (*m < 0 || *m > *n) {
+   29330           0 :         *info = -4;
+   29331           0 :     } else if (*ldz < (*n)) {
+   29332           0 :         *info = -9;
+   29333             :     } else {
+   29334             :         i__1 = *m;
+   29335           0 :         for (j = 2; j <= i__1; ++j) {
+   29336           0 :             if (iblock[j] < iblock[j - 1]) {
+   29337           0 :                 *info = -6;
+   29338           0 :                 break;
+   29339             :             }
+   29340           0 :             if (iblock[j] == iblock[j - 1] && w[j] < w[j - 1]) {
+   29341           0 :                 *info = -5;
+   29342           0 :                 break;
+   29343             :             }
+   29344             :         }
+   29345             :     }
+   29346             : 
+   29347           0 :     if (*info != 0) {
+   29348             :         return;
+   29349             :     }
+   29350             : 
+   29351           0 :     if (*n == 0 || *m == 0) {
+   29352             :         return;
+   29353           0 :     } else if (*n == 1) {
+   29354           0 :         z__[z_dim1 + 1] = 1.;
+   29355           0 :         return;
+   29356             :     }
+   29357             : 
+   29358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29359             : 
+   29360           0 :     for (i__ = 1; i__ <= 4; ++i__) {
+   29361           0 :         iseed[i__ - 1] = 1;
+   29362             :     }
+   29363             : 
+   29364             :     indrv1 = 0;
+   29365             :     indrv2 = indrv1 + *n;
+   29366           0 :     indrv3 = indrv2 + *n;
+   29367           0 :     indrv4 = indrv3 + *n;
+   29368           0 :     indrv5 = indrv4 + *n;
+   29369             : 
+   29370             :     j1 = 1;
+   29371           0 :     i__1 = iblock[*m];
+   29372           0 :     for (nblk = 1; nblk <= i__1; ++nblk) {
+   29373             : 
+   29374           0 :         if (nblk == 1) {
+   29375             :             b1 = 1;
+   29376             :         } else {
+   29377           0 :             b1 = isplit[nblk - 1] + 1;
+   29378             :         }
+   29379           0 :         bn = isplit[nblk];
+   29380           0 :         blksiz = bn - b1 + 1;
+   29381           0 :         if (blksiz == 1) {
+   29382           0 :             continue;
+   29383             :         }
+   29384             :         gpind = b1;
+   29385             : 
+   29386           0 :         onenrm = std::abs(d__[b1]) + std::abs(e[b1]);
+   29387             :         d__3 = onenrm;
+   29388           0 :         d__4 = std::abs(d__[bn]) + std::abs(e[bn - 1]);
+   29389           0 :         onenrm = (d__3>d__4) ? d__3 : d__4;
+   29390             :         i__2 = bn - 1;
+   29391           0 :         for (i__ = b1 + 1; i__ <= i__2; ++i__) {
+   29392             :           d__4 = onenrm;
+   29393           0 :           d__5 = std::abs(d__[i__]) + std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   29394           0 :             onenrm = (d__4>d__5) ? d__4 : d__5;
+   29395             :         }
+   29396           0 :         ortol = onenrm * .001;
+   29397             : 
+   29398           0 :         dtpcrt =  std::sqrt(.1 / blksiz);
+   29399             : 
+   29400             :         jblk = 0;
+   29401           0 :         i__2 = *m;
+   29402           0 :         for (j = j1; j <= i__2; ++j) {
+   29403           0 :             if (iblock[j] != nblk) {
+   29404             :                 j1 = j;
+   29405             :                 break;
+   29406             :             }
+   29407           0 :             ++jblk;
+   29408           0 :             xj = w[j];
+   29409             : 
+   29410           0 :             if (blksiz == 1) {
+   29411           0 :                 work[indrv1 + 1] = 1.;
+   29412           0 :                 goto L120;
+   29413             :             }
+   29414             : 
+   29415           0 :             if (jblk > 1) {
+   29416           0 :                 eps1 = std::abs(eps * xj);
+   29417           0 :                 pertol = eps1 * 10.;
+   29418           0 :                 sep = xj - xjm;
+   29419           0 :                 if (sep < pertol) {
+   29420           0 :                     xj = xjm + pertol;
+   29421             :                 }
+   29422             :             }
+   29423             : 
+   29424             :             its = 0;
+   29425             :             nrmchk = 0;
+   29426             : 
+   29427           0 :             PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(&c__2, iseed, &blksiz, &work[indrv1 + 1]);
+   29428             : 
+   29429           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&blksiz, &d__[b1], &c__1, &work[indrv4 + 1], &c__1);
+   29430           0 :             i__3 = blksiz - 1;
+   29431           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv2 + 2], &c__1);
+   29432           0 :             i__3 = blksiz - 1;
+   29433           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv3 + 1], &c__1);
+   29434             : 
+   29435           0 :             tol = 0.;
+   29436           0 :             PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(&blksiz, &work[indrv4 + 1], &xj, &work[indrv2 + 2], &work[
+   29437           0 :                     indrv3 + 1], &tol, &work[indrv5 + 1], &iwork[1], &iinfo);
+   29438             : 
+   29439           0 : L70:
+   29440           0 :             ++its;
+   29441           0 :             if (its > 5) {
+   29442           0 :                 goto L100;
+   29443             :             }
+   29444             : 
+   29445             :             d__2 = eps;
+   29446           0 :             d__3 = std::abs(work[indrv4 + blksiz]);
+   29447           0 :             scl = blksiz * onenrm * ((d__2>d__3) ? d__2 : d__3) / PLUMED_BLAS_F77_FUNC(sasum,SASUM)(&blksiz, &work[
+   29448             :                     indrv1 + 1], &c__1);
+   29449           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29450             : 
+   29451           0 :             PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(&c_n1, &blksiz, &work[indrv4 + 1], &work[indrv2 + 2], &
+   29452             :                     work[indrv3 + 1], &work[indrv5 + 1], &iwork[1], &work[
+   29453             :                     indrv1 + 1], &tol, &iinfo);
+   29454             : 
+   29455           0 :             if (jblk == 1) {
+   29456           0 :                 goto L90;
+   29457             :             }
+   29458           0 :             if (std::abs(xj - xjm) > ortol) {
+   29459             :                 gpind = j;
+   29460             :             }
+   29461           0 :             if (gpind != j) {
+   29462           0 :                 i__3 = j - 1;
+   29463           0 :                 for (i__ = gpind; i__ <= i__3; ++i__) {
+   29464           0 :                     ztr = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&blksiz, &work[indrv1 + 1], &c__1, &z__[b1 + 
+   29465           0 :                             i__ * z_dim1], &c__1);
+   29466           0 :                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&blksiz, &ztr, &z__[b1 + i__ * z_dim1], &c__1, &
+   29467             :                             work[indrv1 + 1], &c__1);
+   29468             :                 }
+   29469             :             }
+   29470             : 
+   29471           0 : L90:
+   29472           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29473           0 :             nrm = std::abs(work[indrv1 + jmax]);
+   29474             : 
+   29475           0 :             if (nrm < dtpcrt) {
+   29476           0 :                 goto L70;
+   29477             :             }
+   29478           0 :             ++nrmchk;
+   29479           0 :             if (nrmchk < 3) {
+   29480           0 :                 goto L70;
+   29481             :             }
+   29482             : 
+   29483           0 :             goto L110;
+   29484             : 
+   29485             : L100:
+   29486           0 :             ++(*info);
+   29487           0 :             ifail[*info] = j;
+   29488             : 
+   29489           0 : L110:
+   29490           0 :             scl = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&blksiz, &work[indrv1 + 1], &c__1);
+   29491           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29492           0 :             if (work[indrv1 + jmax] < 0.) {
+   29493           0 :                 scl = -scl;
+   29494             :             }
+   29495           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29496           0 : L120:
+   29497           0 :             i__3 = *n;
+   29498           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29499           0 :                 z__[i__ + j * z_dim1] = 0.;
+   29500             :             }
+   29501           0 :             i__3 = blksiz;
+   29502           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29503           0 :                 z__[b1 + i__ - 1 + j * z_dim1] = work[indrv1 + i__];
+   29504             :             }
+   29505             : 
+   29506           0 :             xjm = xj;
+   29507             :         }
+   29508             :     }
+   29509             : 
+   29510             :     return;
+   29511             : 
+   29512             : }
+   29513             : 
+   29514             : 
+   29515             : }
+   29516             : }
+   29517             : #include <cmath>
+   29518             : #include "real.h"
+   29519             : 
+   29520             : #include "blas/blas.h"
+   29521             : #include "lapack.h"
+   29522             : #include "lapack_limits.h"
+   29523             : 
+   29524             : #include "blas/blas.h"
+   29525             : namespace PLMD{
+   29526             : namespace lapack{
+   29527             : using namespace blas;
+   29528             : void
+   29529           0 : PLUMED_BLAS_F77_FUNC(ssteqr,SSTEQR)(const char *    compz, 
+   29530             :                         int *     n, 
+   29531             :                         float *  d__, 
+   29532             :                         float *  e, 
+   29533             :                         float *  z__, 
+   29534             :                         int *     ldz, 
+   29535             :                         float *  work, 
+   29536             :                         int *     info)
+   29537             : {
+   29538           0 :     float c_b9 = 0.;
+   29539           0 :     float c_b10 = 1.;
+   29540           0 :     int c__0 = 0;
+   29541           0 :     int c__1 = 1;
+   29542           0 :     int c__2 = 2;
+   29543             :     int z_dim1, z_offset, i__1, i__2;
+   29544             :     float d__1, d__2;
+   29545             : 
+   29546             :     float b, c__, f, g;
+   29547             :     int i__, j, k, l, m;
+   29548             :     float p, r__, s;
+   29549             :     int l1, ii, mm, lm1, mm1, nm1;
+   29550             :     float rt1, rt2, eps;
+   29551             :     int lsv;
+   29552             :     float tst, eps2;
+   29553             :     int lend, jtot;
+   29554             :     float anorm;
+   29555             :     int lendm1, lendp1;
+   29556             :     int iscale;
+   29557             :     float safmin,minval;
+   29558             :     float safmax;
+   29559             :     int lendsv;
+   29560             :     float ssfmin;
+   29561             :     int nmaxit, icompz;
+   29562             :     float ssfmax;
+   29563             : 
+   29564             : 
+   29565           0 :     --d__;
+   29566           0 :     --e;
+   29567           0 :     z_dim1 = *ldz;
+   29568           0 :     z_offset = 1 + z_dim1;
+   29569           0 :     z__ -= z_offset;
+   29570           0 :     --work;
+   29571             : 
+   29572           0 :     *info = 0;
+   29573             : 
+   29574           0 :     if (*compz=='N' || *compz=='n') {
+   29575             :         icompz = 0;
+   29576           0 :     } else if (*compz=='V' || *compz=='v') {
+   29577             :         icompz = 1;
+   29578             :     } else if (*compz=='I' || *compz=='i') {
+   29579             :         icompz = 2;
+   29580             :     } else {
+   29581             :         icompz = -1;
+   29582             :     }
+   29583             :     if (icompz < 0) {
+   29584           0 :         *info = -1;
+   29585           0 :     } else if (*n < 0) {
+   29586           0 :         *info = -2;
+   29587           0 :     } else if (*ldz < 1 || (icompz > 0 && *ldz < ((*n>1) ? *n : 1))) {
+   29588           0 :         *info = -6;
+   29589             :     }
+   29590           0 :     if (*info != 0) {
+   29591             :         return;
+   29592             :     }
+   29593             : 
+   29594             : 
+   29595           0 :     if (*n == 0) {
+   29596             :         return;
+   29597             :     }
+   29598             : 
+   29599           0 :     if (*n == 1) {
+   29600           0 :         if (icompz == 2) {
+   29601           0 :             z__[z_dim1 + 1] = 1.;
+   29602             :         }
+   29603           0 :         return;
+   29604             :     }
+   29605             : 
+   29606             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29607             :     d__1 = eps;
+   29608             :     eps2 = d__1 * d__1;
+   29609             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29610             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29611             : 
+   29612             :     safmax = 1. / safmin;
+   29613           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   29614           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   29615             : 
+   29616           0 :     if (icompz == 2) {
+   29617           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz);
+   29618             :     }
+   29619             : 
+   29620           0 :     nmaxit = *n * 30;
+   29621             :     jtot = 0;
+   29622             : 
+   29623             :     l1 = 1;
+   29624           0 :     nm1 = *n - 1;
+   29625             : 
+   29626           0 : L10:
+   29627           0 :     if (l1 > *n) {
+   29628           0 :         goto L160;
+   29629             :     }
+   29630           0 :     if (l1 > 1) {
+   29631           0 :         e[l1 - 1] = 0.;
+   29632             :     }
+   29633           0 :     if (l1 <= nm1) {
+   29634           0 :         i__1 = nm1;
+   29635           0 :         for (m = l1; m <= i__1; ++m) {
+   29636           0 :             tst = std::abs(e[m]);
+   29637           0 :             if (std::abs(tst)<PLUMED_GMX_FLOAT_MIN) {
+   29638           0 :                 goto L30;
+   29639             :             }
+   29640           0 :             if (tst <=  std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) {
+   29641           0 :                 e[m] = 0.;
+   29642           0 :                 goto L30;
+   29643             :             }
+   29644             :         }
+   29645             :     }
+   29646           0 :     m = *n;
+   29647             : 
+   29648           0 : L30:
+   29649             :     l = l1;
+   29650             :     lsv = l;
+   29651             :     lend = m;
+   29652             :     lendsv = lend;
+   29653           0 :     l1 = m + 1;
+   29654           0 :     if (lend == l) {
+   29655           0 :         goto L10;
+   29656             :     }
+   29657             : 
+   29658           0 :     i__1 = lend - l + 1;
+   29659           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   29660             :     iscale = 0;
+   29661           0 :     if (std::abs(anorm)<PLUMED_GMX_FLOAT_MIN) {
+   29662           0 :         goto L10;
+   29663             :     }
+   29664           0 :     if (anorm > ssfmax) {
+   29665             :         iscale = 1;
+   29666           0 :         i__1 = lend - l + 1;
+   29667           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   29668             :                 info);
+   29669           0 :         i__1 = lend - l;
+   29670           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   29671             :                 info);
+   29672           0 :     } else if (anorm < ssfmin) {
+   29673             :         iscale = 2;
+   29674           0 :         i__1 = lend - l + 1;
+   29675           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   29676             :                 info);
+   29677           0 :         i__1 = lend - l;
+   29678           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   29679             :                 info);
+   29680             :     }
+   29681             : 
+   29682           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   29683             :         lend = lsv;
+   29684             :         l = lendsv;
+   29685             :     }
+   29686             : 
+   29687           0 :     if (lend > l) {
+   29688             : 
+   29689           0 : L40:
+   29690           0 :         if (l != lend) {
+   29691           0 :             lendm1 = lend - 1;
+   29692           0 :             i__1 = lendm1;
+   29693           0 :             for (m = l; m <= i__1; ++m) {
+   29694           0 :                 d__2 = std::abs(e[m]);
+   29695           0 :                 tst = d__2 * d__2;
+   29696           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m+ 1]) + safmin) {
+   29697           0 :                     goto L60;
+   29698             :                 }
+   29699             :             }
+   29700             :         }
+   29701             : 
+   29702             :         m = lend;
+   29703             : 
+   29704           0 : L60:
+   29705           0 :         if (m < lend) {
+   29706           0 :             e[m] = 0.;
+   29707             :         }
+   29708           0 :         p = d__[l];
+   29709           0 :         if (m == l) {
+   29710           0 :             goto L80;
+   29711             :         }
+   29712             : 
+   29713           0 :         if (m == l + 1) {
+   29714           0 :             if (icompz > 0) {
+   29715           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s);
+   29716           0 :                 work[l] = c__;
+   29717           0 :                 work[*n - 1 + l] = s;
+   29718           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &
+   29719           0 :                         z__[l * z_dim1 + 1], ldz);
+   29720             :             } else {
+   29721           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2);
+   29722             :             }
+   29723           0 :             d__[l] = rt1;
+   29724           0 :             d__[l + 1] = rt2;
+   29725           0 :             e[l] = 0.;
+   29726           0 :             l += 2;
+   29727           0 :             if (l <= lend) {
+   29728           0 :                 goto L40;
+   29729             :             }
+   29730           0 :             goto L140;
+   29731             :         }
+   29732             : 
+   29733           0 :         if (jtot == nmaxit) {
+   29734           0 :             goto L140;
+   29735             :         }
+   29736           0 :         ++jtot;
+   29737             : 
+   29738           0 :         g = (d__[l + 1] - p) / (e[l] * 2.);
+   29739           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29740           0 :         g = d__[m] - p + e[l] / (g + ( (g>0) ? r__ : -r__ ) );
+   29741             : 
+   29742           0 :         s = 1.;
+   29743           0 :         c__ = 1.;
+   29744             :         p = 0.;
+   29745             : 
+   29746           0 :         mm1 = m - 1;
+   29747           0 :         i__1 = l;
+   29748           0 :         for (i__ = mm1; i__ >= i__1; --i__) {
+   29749           0 :             f = s * e[i__];
+   29750           0 :             b = c__ * e[i__];
+   29751           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29752           0 :             if (i__ != m - 1) {
+   29753           0 :                 e[i__ + 1] = r__;
+   29754             :             }
+   29755           0 :             g = d__[i__ + 1] - p;
+   29756           0 :             r__ = (d__[i__] - g) * s + c__ * 2. * b;
+   29757           0 :             p = s * r__;
+   29758           0 :             d__[i__ + 1] = g + p;
+   29759           0 :             g = c__ * r__ - b;
+   29760             : 
+   29761           0 :             if (icompz > 0) {
+   29762           0 :                 work[i__] = c__;
+   29763           0 :                 work[*n - 1 + i__] = -s;
+   29764             :             }
+   29765             :         }
+   29766             : 
+   29767           0 :         if (icompz > 0) {
+   29768           0 :             mm = m - l + 1;
+   29769           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z__[l 
+   29770           0 :                     * z_dim1 + 1], ldz);
+   29771             :         }
+   29772             : 
+   29773           0 :         d__[l] -= p;
+   29774           0 :         e[l] = g;
+   29775           0 :         goto L40;
+   29776             : 
+   29777             : L80:
+   29778             :         d__[l] = p;
+   29779             : 
+   29780           0 :         ++l;
+   29781           0 :         if (l <= lend) {
+   29782           0 :             goto L40;
+   29783             :         }
+   29784           0 :         goto L140;
+   29785             : 
+   29786             :     } else {
+   29787             : 
+   29788           0 : L90:
+   29789           0 :         if (l != lend) {
+   29790           0 :             lendp1 = lend + 1;
+   29791           0 :             i__1 = lendp1;
+   29792           0 :             for (m = l; m >= i__1; --m) {
+   29793           0 :                 d__2 = std::abs(e[m - 1]);
+   29794           0 :                 tst = d__2 * d__2;
+   29795           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) {
+   29796           0 :                     goto L110;
+   29797             :                 }
+   29798             :             }
+   29799             :         }
+   29800             : 
+   29801             :         m = lend;
+   29802             : 
+   29803           0 : L110:
+   29804           0 :         if (m > lend) {
+   29805           0 :             e[m - 1] = 0.;
+   29806             :         }
+   29807           0 :         p = d__[l];
+   29808           0 :         if (m == l) {
+   29809           0 :             goto L130;
+   29810             :         }
+   29811           0 :         if (m == l - 1) {
+   29812           0 :             if (icompz > 0) {
+   29813           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s)
+   29814             :                         ;
+   29815           0 :                 work[m] = c__;
+   29816           0 :                 work[*n - 1 + m] = s;
+   29817           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &
+   29818           0 :                         z__[(l - 1) * z_dim1 + 1], ldz);
+   29819             :             } else {
+   29820           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2);
+   29821             :             }
+   29822           0 :             d__[l - 1] = rt1;
+   29823           0 :             d__[l] = rt2;
+   29824           0 :             e[l - 1] = 0.;
+   29825           0 :             l += -2;
+   29826           0 :             if (l >= lend) {
+   29827           0 :                 goto L90;
+   29828             :             }
+   29829           0 :             goto L140;
+   29830             :         }
+   29831             : 
+   29832           0 :         if (jtot == nmaxit) {
+   29833           0 :             goto L140;
+   29834             :         }
+   29835           0 :         ++jtot;
+   29836             : 
+   29837           0 :         g = (d__[l - 1] - p) / (e[l - 1] * 2.);
+   29838           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29839           0 :         g = d__[m] - p + e[l - 1] / (g + ( (g>0) ? r__ : -r__ ));
+   29840             : 
+   29841           0 :         s = 1.;
+   29842           0 :         c__ = 1.;
+   29843             :         p = 0.;
+   29844             : 
+   29845             :         lm1 = l - 1;
+   29846           0 :         i__1 = lm1;
+   29847           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   29848           0 :             f = s * e[i__];
+   29849           0 :             b = c__ * e[i__];
+   29850           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29851           0 :             if (i__ != m) {
+   29852           0 :                 e[i__ - 1] = r__;
+   29853             :             }
+   29854           0 :             g = d__[i__] - p;
+   29855           0 :             r__ = (d__[i__ + 1] - g) * s + c__ * 2. * b;
+   29856           0 :             p = s * r__;
+   29857           0 :             d__[i__] = g + p;
+   29858           0 :             g = c__ * r__ - b;
+   29859             : 
+   29860           0 :             if (icompz > 0) {
+   29861           0 :                 work[i__] = c__;
+   29862           0 :                 work[*n - 1 + i__] = s;
+   29863             :             }
+   29864             :         }
+   29865             : 
+   29866           0 :         if (icompz > 0) {
+   29867           0 :             mm = l - m + 1;
+   29868           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z__[m 
+   29869           0 :                     * z_dim1 + 1], ldz);
+   29870             :         }
+   29871             : 
+   29872           0 :         d__[l] -= p;
+   29873           0 :         e[lm1] = g;
+   29874           0 :         goto L90;
+   29875             : 
+   29876             : L130:
+   29877             :         d__[l] = p;
+   29878             : 
+   29879           0 :         --l;
+   29880           0 :         if (l >= lend) {
+   29881           0 :             goto L90;
+   29882             :         }
+   29883           0 :         goto L140;
+   29884             : 
+   29885             :     }
+   29886             : 
+   29887           0 : L140:
+   29888           0 :     if (iscale == 1) {
+   29889           0 :         i__1 = lendsv - lsv + 1;
+   29890           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   29891             :                 n, info);
+   29892           0 :         i__1 = lendsv - lsv;
+   29893           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29894             :                 info);
+   29895           0 :     } else if (iscale == 2) {
+   29896           0 :         i__1 = lendsv - lsv + 1;
+   29897           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   29898             :                 n, info);
+   29899           0 :         i__1 = lendsv - lsv;
+   29900           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29901             :                 info);
+   29902             :     }
+   29903             : 
+   29904           0 :     if (jtot < nmaxit) {
+   29905           0 :         goto L10;
+   29906             :     }
+   29907           0 :     i__1 = *n - 1;
+   29908           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29909           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   29910           0 :             ++(*info);
+   29911             :         }
+   29912             :     }
+   29913           0 :     goto L190;
+   29914             : 
+   29915             : L160:
+   29916           0 :     if (icompz == 0) {
+   29917             : 
+   29918           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   29919             : 
+   29920             :     } else {
+   29921             : 
+   29922           0 :         i__1 = *n;
+   29923           0 :         for (ii = 2; ii <= i__1; ++ii) {
+   29924           0 :             i__ = ii - 1;
+   29925             :             k = i__;
+   29926           0 :             p = d__[i__];
+   29927           0 :             i__2 = *n;
+   29928           0 :             for (j = ii; j <= i__2; ++j) {
+   29929           0 :                 if (d__[j] < p) {
+   29930             :                     k = j;
+   29931             :                     p = d__[j];
+   29932             :                 }
+   29933             :             }
+   29934           0 :             if (k != i__) {
+   29935           0 :                 d__[k] = d__[i__];
+   29936           0 :                 d__[i__] = p;
+   29937           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[k * z_dim1 + 1],
+   29938             :                          &c__1);
+   29939             :             }
+   29940             :         }
+   29941             :     }
+   29942             : 
+   29943           0 : L190:
+   29944             :     return;
+   29945             : }
+   29946             : 
+   29947             : 
+   29948             : }
+   29949             : }
+   29950             : #include <cmath>
+   29951             : #include "lapack.h"
+   29952             : #include "lapack_limits.h"
+   29953             : 
+   29954             : #include "real.h"
+   29955             : 
+   29956             : #include "blas/blas.h"
+   29957             : namespace PLMD{
+   29958             : namespace lapack{
+   29959             : using namespace blas;
+   29960             : void
+   29961           0 : PLUMED_BLAS_F77_FUNC(ssterf,SSTERF)(int *n, 
+   29962             :         float *d__, 
+   29963             :         float *e, 
+   29964             :         int *info)
+   29965             : {
+   29966             :     int i__1;
+   29967             :     float d__1;
+   29968             : 
+   29969             :     float c__;
+   29970             :     int i__, l, m;
+   29971             :     float p, r__, s;
+   29972             :     int l1;
+   29973             :     float bb, rt1, rt2, eps, rte;
+   29974             :     int lsv;
+   29975             :     float eps2, oldc;
+   29976             :     int lend, jtot;
+   29977             :     float gamma, alpha, sigma, anorm;
+   29978             :       int iscale;
+   29979             :     float oldgam;
+   29980             :     float safmax;
+   29981             :     int lendsv;
+   29982             :     float ssfmin;
+   29983             :     int nmaxit;
+   29984             :     float ssfmax;
+   29985           0 :     int c__0 = 0;
+   29986           0 :     int c__1 = 1;
+   29987           0 :     float c_b32 = 1.;
+   29988             :     const float safmin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29989             : 
+   29990           0 :     --e;
+   29991           0 :     --d__;
+   29992             : 
+   29993           0 :     *info = 0;
+   29994             : 
+   29995           0 :     if (*n < 0) {
+   29996           0 :         *info = -1;
+   29997             :         i__1 = -(*info);
+   29998           0 :         return;
+   29999             :     }
+   30000           0 :     if (*n <= 1) {
+   30001             :         return;
+   30002             :     }
+   30003             : 
+   30004             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30005             :     d__1 = eps;
+   30006             :     eps2 = d__1 * d__1;
+   30007             :     safmax = 1. / safmin;
+   30008           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   30009           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   30010             : 
+   30011           0 :     nmaxit = *n * 30;
+   30012           0 :     sigma = 0.;
+   30013             :     jtot = 0;
+   30014             : 
+   30015             :     l1 = 1;
+   30016             : 
+   30017           0 : L10:
+   30018           0 :     if (l1 > *n) {
+   30019           0 :       PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   30020           0 :       return;
+   30021             :     }
+   30022           0 :     if (l1 > 1) {
+   30023           0 :         e[l1 - 1] = 0.;
+   30024             :     }
+   30025           0 :     i__1 = *n - 1;
+   30026           0 :     for (m = l1; m <= i__1; ++m) {
+   30027           0 :         if (std::abs(e[m]) <=  std::sqrt(std::abs(d__[m])) * 
+   30028           0 :                  std::sqrt(std::abs(d__[m + 1])) * eps) {
+   30029           0 :             e[m] = 0.;
+   30030           0 :             goto L30;
+   30031             :         }
+   30032             :     }
+   30033           0 :     m = *n;
+   30034             : 
+   30035           0 : L30:
+   30036             :     l = l1;
+   30037             :     lsv = l;
+   30038             :     lend = m;
+   30039             :     lendsv = lend;
+   30040           0 :     l1 = m + 1;
+   30041           0 :     if (lend == l) {
+   30042           0 :         goto L10;
+   30043             :     }
+   30044             : 
+   30045           0 :     i__1 = lend - l + 1;
+   30046           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   30047             :     iscale = 0;
+   30048           0 :     if (anorm > ssfmax) {
+   30049             :         iscale = 1;
+   30050           0 :         i__1 = lend - l + 1;
+   30051           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   30052             :                 info);
+   30053           0 :         i__1 = lend - l;
+   30054           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   30055             :                 info);
+   30056           0 :     } else if (anorm < ssfmin) {
+   30057             :         iscale = 2;
+   30058           0 :         i__1 = lend - l + 1;
+   30059           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   30060             :                 info);
+   30061           0 :         i__1 = lend - l;
+   30062           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   30063             :                 info);
+   30064             :     }
+   30065             : 
+   30066           0 :     i__1 = lend - 1;
+   30067           0 :     for (i__ = l; i__ <= i__1; ++i__) {
+   30068           0 :         d__1 = e[i__];
+   30069           0 :         e[i__] = d__1 * d__1;
+   30070             :     }
+   30071             : 
+   30072           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   30073             :         lend = lsv;
+   30074             :         l = lendsv;
+   30075             :     }
+   30076             : 
+   30077           0 :     if (lend >= l) {
+   30078             : 
+   30079           0 : L50:
+   30080           0 :         if (l != lend) {
+   30081           0 :             i__1 = lend - 1;
+   30082           0 :             for (m = l; m <= i__1; ++m) {
+   30083           0 :                 if (std::abs(e[m]) <= eps2 * std::abs(d__[m] * d__[m + 1])) {
+   30084           0 :                     goto L70;
+   30085             :                 }
+   30086             :             }
+   30087             :         }
+   30088             :         m = lend;
+   30089             : 
+   30090           0 : L70:
+   30091           0 :         if (m < lend) {
+   30092           0 :             e[m] = 0.;
+   30093             :         }
+   30094           0 :         p = d__[l];
+   30095           0 :         if (m == l) {
+   30096           0 :             goto L90;
+   30097             :         }
+   30098           0 :         if (m == l + 1) {
+   30099           0 :             rte =  std::sqrt(e[l]);
+   30100           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
+   30101           0 :             d__[l] = rt1;
+   30102           0 :             d__[l + 1] = rt2;
+   30103           0 :             e[l] = 0.;
+   30104           0 :             l += 2;
+   30105           0 :             if (l <= lend) {
+   30106           0 :                 goto L50;
+   30107             :             }
+   30108           0 :             goto L150;
+   30109             :         }
+   30110             : 
+   30111           0 :         if (jtot == nmaxit) {
+   30112           0 :             goto L150;
+   30113             :         }
+   30114           0 :         ++jtot;
+   30115             : 
+   30116           0 :         rte =  std::sqrt(e[l]);
+   30117           0 :         sigma = (d__[l + 1] - p) / (rte * 2.);
+   30118           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30119           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30120             : 
+   30121             :         c__ = 1.;
+   30122             :         s = 0.;
+   30123           0 :         gamma = d__[m] - sigma;
+   30124           0 :         p = gamma * gamma;
+   30125             : 
+   30126           0 :         i__1 = l;
+   30127           0 :         for (i__ = m - 1; i__ >= i__1; --i__) {
+   30128           0 :             bb = e[i__];
+   30129           0 :             r__ = p + bb;
+   30130           0 :             if (i__ != m - 1) {
+   30131           0 :                 e[i__ + 1] = s * r__;
+   30132             :             }
+   30133             :             oldc = c__;
+   30134           0 :             c__ = p / r__;
+   30135           0 :             s = bb / r__;
+   30136             :             oldgam = gamma;
+   30137           0 :             alpha = d__[i__];
+   30138           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30139           0 :             d__[i__ + 1] = oldgam + (alpha - gamma);
+   30140           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30141           0 :                 p = gamma * gamma / c__;
+   30142             :             } else {
+   30143           0 :                 p = oldc * bb;
+   30144             :             }
+   30145             :         }
+   30146             : 
+   30147           0 :         e[l] = s * p;
+   30148           0 :         d__[l] = sigma + gamma;
+   30149           0 :         goto L50;
+   30150             : 
+   30151             : L90:
+   30152             :         d__[l] = p;
+   30153             : 
+   30154           0 :         ++l;
+   30155           0 :         if (l <= lend) {
+   30156           0 :             goto L50;
+   30157             :         }
+   30158           0 :         goto L150;
+   30159             : 
+   30160             :     } else {
+   30161             : 
+   30162           0 : L100:
+   30163           0 :         i__1 = lend + 1;
+   30164           0 :         for (m = l; m >= i__1; --m) {
+   30165           0 :             if (std::abs(e[m - 1]) <= eps2 * std::abs(d__[m] * d__[m - 1])) {
+   30166           0 :                 goto L120;
+   30167             :             }
+   30168             :         }
+   30169             :         m = lend;
+   30170             : 
+   30171           0 : L120:
+   30172           0 :         if (m > lend) {
+   30173           0 :             e[m - 1] = 0.;
+   30174             :         }
+   30175           0 :         p = d__[l];
+   30176           0 :         if (m == l) {
+   30177           0 :             goto L140;
+   30178             :         }
+   30179             : 
+   30180           0 :         if (m == l - 1) {
+   30181           0 :             rte =  std::sqrt(e[l - 1]);
+   30182           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
+   30183           0 :             d__[l] = rt1;
+   30184           0 :             d__[l - 1] = rt2;
+   30185           0 :             e[l - 1] = 0.;
+   30186           0 :             l += -2;
+   30187           0 :             if (l >= lend) {
+   30188           0 :                 goto L100;
+   30189             :             }
+   30190           0 :             goto L150;
+   30191             :         }
+   30192             : 
+   30193           0 :         if (jtot == nmaxit) {
+   30194           0 :             goto L150;
+   30195             :         }
+   30196           0 :         ++jtot;
+   30197             : 
+   30198           0 :         rte =  std::sqrt(e[l - 1]);
+   30199           0 :         sigma = (d__[l - 1] - p) / (rte * 2.);
+   30200           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30201           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30202             : 
+   30203             :         c__ = 1.;
+   30204             :         s = 0.;
+   30205           0 :         gamma = d__[m] - sigma;
+   30206           0 :         p = gamma * gamma;
+   30207             : 
+   30208           0 :         i__1 = l - 1;
+   30209           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   30210           0 :             bb = e[i__];
+   30211           0 :             r__ = p + bb;
+   30212           0 :             if (i__ != m) {
+   30213           0 :                 e[i__ - 1] = s * r__;
+   30214             :             }
+   30215             :             oldc = c__;
+   30216           0 :             c__ = p / r__;
+   30217           0 :             s = bb / r__;
+   30218             :             oldgam = gamma;
+   30219           0 :             alpha = d__[i__ + 1];
+   30220           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30221           0 :             d__[i__] = oldgam + (alpha - gamma);
+   30222           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30223           0 :                 p = gamma * gamma / c__;
+   30224             :             } else {
+   30225           0 :                 p = oldc * bb;
+   30226             :             }
+   30227             :         }
+   30228             : 
+   30229           0 :         e[l - 1] = s * p;
+   30230           0 :         d__[l] = sigma + gamma;
+   30231           0 :         goto L100;
+   30232             : 
+   30233             : L140:
+   30234             :         d__[l] = p;
+   30235             : 
+   30236           0 :         --l;
+   30237           0 :         if (l >= lend) {
+   30238           0 :             goto L100;
+   30239             :         }
+   30240           0 :         goto L150;
+   30241             : 
+   30242             :     }
+   30243             : 
+   30244           0 : L150:
+   30245           0 :     if (iscale == 1) {
+   30246           0 :         i__1 = lendsv - lsv + 1;
+   30247           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   30248             :                 n, info);
+   30249             :     }
+   30250           0 :     if (iscale == 2) {
+   30251           0 :         i__1 = lendsv - lsv + 1;
+   30252           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   30253             :                 n, info);
+   30254             :     }
+   30255             : 
+   30256           0 :     if (jtot < nmaxit) {
+   30257           0 :         goto L10;
+   30258             :     }
+   30259           0 :     i__1 = *n - 1;
+   30260           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   30261           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   30262           0 :             ++(*info);
+   30263             :         }
+   30264             :     }
+   30265             :     return;
+   30266             : }
+   30267             : 
+   30268             : 
+   30269             : }
+   30270             : }
+   30271             : #include "lapack.h"
+   30272             : 
+   30273             : 
+   30274             : /* Normally, SSTEVR is the LAPACK wrapper which calls one
+   30275             :  * of the eigenvalue methods. However, our code includes a
+   30276             :  * version of SSTEGR which is never than LAPACK 3.0 and can
+   30277             :  * handle requests for a subset of eigenvalues/vectors too,
+   30278             :  * and it should not need to call SSTEIN.
+   30279             :  * Just in case somebody has a faster version in their lapack
+   30280             :  * library we still call the driver routine, but in our own
+   30281             :  * case this is just a wrapper to sstegr.
+   30282             :  */
+   30283             : #include "blas/blas.h"
+   30284             : namespace PLMD{
+   30285             : namespace lapack{
+   30286             : using namespace blas;
+   30287             : void
+   30288           0 : PLUMED_BLAS_F77_FUNC(sstevr,SSTEVR)(const char *jobz, 
+   30289             :                         const char *range,
+   30290             :                         int *n,
+   30291             :                         float *d,
+   30292             :                         float *e,
+   30293             :                         float *vl, 
+   30294             :                         float *vu,
+   30295             :                         int *il, 
+   30296             :                         int *iu, 
+   30297             :                         float *abstol,
+   30298             :                         int *m,
+   30299             :                         float *w, 
+   30300             :                         float *z,
+   30301             :                         int *ldz,
+   30302             :                         int *isuppz, 
+   30303             :                         float *work, 
+   30304             :                         int *lwork, 
+   30305             :                         int *iwork,
+   30306             :                         int *liwork, 
+   30307             :                         int *info)
+   30308             : {
+   30309           0 :   PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w,
+   30310             :           z, ldz, isuppz, work, lwork, iwork, liwork, info);
+   30311             :   
+   30312             : 
+   30313           0 :     return;
+   30314             : 
+   30315             : }
+   30316             : 
+   30317             : 
+   30318             : }
+   30319             : }
+   30320             : #include <cmath>
+   30321             : 
+   30322             : #include "real.h"
+   30323             : 
+   30324             : #include "blas/blas.h"
+   30325             : #include "lapack.h"
+   30326             : #include "lapack_limits.h"
+   30327             : 
+   30328             : #include "blas/blas.h"
+   30329             : namespace PLMD{
+   30330             : namespace lapack{
+   30331             : using namespace blas;
+   30332             : void
+   30333           0 : PLUMED_BLAS_F77_FUNC(ssyevr,SSYEVR)(const char *jobz, const char *range, const char *uplo, int *n, 
+   30334             :         float *a, int *lda, float *vl, float *vu, int *
+   30335             :         il, int *iu, float *abstol, int *m, float *w, 
+   30336             :         float *z__, int *ldz, int *isuppz, float *work, 
+   30337             :         int *lwork, int *iwork, int *liwork, int *info)
+   30338             : {
+   30339             :     /* System generated locals */
+   30340             :     int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
+   30341             :     float d__1, d__2;
+   30342             : 
+   30343             :     /* Local variables */
+   30344           0 :     int c__1 = 1;
+   30345             :     int i__, j, nb, jj;
+   30346             :     float eps, tmp1;
+   30347             :     int indd, inde;
+   30348             :     float anrm;
+   30349             :     int imax;
+   30350             :     float rmin, rmax;
+   30351             :     int itmp1, inddd, indee;
+   30352             :     float sigma;
+   30353             :     int iinfo;
+   30354             :     int indwk;
+   30355             :     int lwmin;
+   30356             :     int lower, wantz;
+   30357             :     int alleig, indeig;
+   30358             :     int iscale, indibl, indifl;
+   30359             :     int valeig;
+   30360             :     float safmin,minval;
+   30361             :     float bignum;
+   30362             :     int indtau;
+   30363             :     int indwkn;
+   30364             :     int liwmin;
+   30365             :     int llwrkn, llwork;
+   30366             :     float smlnum;
+   30367             :     int lwkopt;
+   30368             :     int lquery;
+   30369             :     
+   30370             :     /* Parameter adjustments */
+   30371           0 :     a_dim1 = *lda;
+   30372           0 :     a_offset = 1 + a_dim1;
+   30373           0 :     a -= a_offset;
+   30374           0 :     --w;
+   30375           0 :     z_dim1 = *ldz;
+   30376           0 :     z_offset = 1 + z_dim1;
+   30377           0 :     z__ -= z_offset;
+   30378             :     --isuppz;
+   30379           0 :     --work;
+   30380           0 :     --iwork;
+   30381             : 
+   30382           0 :     lower = (*uplo=='L' || *uplo=='l');
+   30383           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   30384           0 :     alleig = (*range=='A' || *range=='a');
+   30385           0 :     valeig = (*range=='V' || *range=='v');
+   30386           0 :     indeig = (*range=='I' || *range=='i');
+   30387             : 
+   30388             :     indibl = 0;
+   30389           0 :     lquery = *lwork == -1 || *liwork == -1;
+   30390             : 
+   30391             :     i__1 = 1;
+   30392           0 :     i__2 = *n * 26;
+   30393             : 
+   30394           0 :     if(*n>0) 
+   30395             :       lwmin = *n * 26;
+   30396             :     else
+   30397             :       lwmin = 1;
+   30398             : 
+   30399           0 :     if(*n>0) 
+   30400           0 :       liwmin = *n * 10;
+   30401             :     else
+   30402             :       liwmin = 1;
+   30403             : 
+   30404           0 :     *info = 0;
+   30405           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   30406           0 :         *info = -1;
+   30407           0 :     } else if (! (alleig || valeig || indeig)) {
+   30408           0 :         *info = -2;
+   30409           0 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   30410           0 :         *info = -3;
+   30411           0 :     } else if (*n < 0) {
+   30412           0 :         *info = -4;
+   30413           0 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   30414           0 :         *info = -6;
+   30415             :     } else {
+   30416           0 :         if (valeig) {
+   30417           0 :             if (*n > 0 && *vu <= *vl) {
+   30418           0 :                 *info = -8;
+   30419             :             }
+   30420           0 :         } else if (indeig) {
+   30421           0 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   30422           0 :                 *info = -9;
+   30423           0 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   30424           0 :                 *info = -10;
+   30425             :             }
+   30426             :         }
+   30427             :     }
+   30428           0 :     if (*info == 0) {
+   30429           0 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   30430           0 :             *info = -15;
+   30431           0 :         } else if (*lwork < lwmin && ! lquery) {
+   30432           0 :             *info = -18;
+   30433           0 :         } else if (*liwork < liwmin && ! lquery) {
+   30434           0 :             *info = -20;
+   30435             :         }
+   30436             :     }
+   30437             : 
+   30438           0 :     if (*info == 0) {
+   30439             :       nb = 32;
+   30440             :       /* Computing MAX */
+   30441           0 :       i__1 = (nb + 1) * *n;
+   30442             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   30443           0 :       work[1] = (float) lwkopt;
+   30444           0 :       iwork[1] = liwmin;
+   30445             :     } else 
+   30446             :       return;
+   30447             : 
+   30448           0 :     if (lquery) 
+   30449             :         return;
+   30450             :     
+   30451           0 :     *m = 0;
+   30452           0 :     if (*n == 0) {
+   30453           0 :         work[1] = 1.;
+   30454           0 :         return;
+   30455             :     }
+   30456             : 
+   30457           0 :     if (*n == 1) {
+   30458           0 :         work[1] = 7.;
+   30459           0 :         if (alleig || indeig) {
+   30460           0 :             *m = 1;
+   30461           0 :             w[1] = a[a_dim1 + 1];
+   30462             :         } else {
+   30463           0 :             if (*vl < a[a_dim1 + 1] && *vu >= a[a_dim1 + 1]) {
+   30464           0 :                 *m = 1;
+   30465           0 :                 w[1] = a[a_dim1 + 1];
+   30466             :             }
+   30467             :         }
+   30468           0 :         if (wantz) {
+   30469           0 :             z__[z_dim1 + 1] = 1.;
+   30470             :         }
+   30471           0 :         return;
+   30472             :     }
+   30473             :     minval = PLUMED_GMX_FLOAT_MIN;
+   30474             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   30475             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30476             : 
+   30477             :     smlnum = safmin / eps;
+   30478             :     bignum = 1. / smlnum;
+   30479             :     rmin =  std::sqrt(smlnum);
+   30480             : 
+   30481           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   30482             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   30483             : 
+   30484             :     iscale = 0;
+   30485           0 :     anrm = PLUMED_BLAS_F77_FUNC(slansy,SLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   30486           0 :     if (anrm > 0. && anrm < rmin) {
+   30487             :         iscale = 1;
+   30488           0 :         sigma = rmin / anrm;
+   30489           0 :     } else if (anrm > rmax) {
+   30490             :         iscale = 1;
+   30491           0 :         sigma = rmax / anrm; 
+   30492             :     }
+   30493             :     if (iscale == 1) {
+   30494           0 :         if (lower) {
+   30495           0 :             i__1 = *n;
+   30496           0 :             for (j = 1; j <= i__1; ++j) {
+   30497           0 :                 i__2 = *n - j + 1;
+   30498           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &sigma, &a[j + j * a_dim1], &c__1);
+   30499             :             }
+   30500             :         } else {
+   30501           0 :             i__1 = *n;
+   30502           0 :             for (j = 1; j <= i__1; ++j) {
+   30503           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&j, &sigma, &a[j * a_dim1 + 1], &c__1);
+   30504             : 
+   30505             :             }
+   30506             :         }
+   30507             :     }
+   30508             : 
+   30509             :     indtau = 1;
+   30510           0 :     inde = indtau + *n;
+   30511           0 :     indd = inde + *n;
+   30512           0 :     indee = indd + *n;
+   30513           0 :     inddd = indee + *n;
+   30514           0 :     indifl = inddd + *n;
+   30515           0 :     indwk = indifl + *n;
+   30516           0 :     llwork = *lwork - indwk + 1;
+   30517           0 :     PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   30518           0 :             indtau], &work[indwk], &llwork, &iinfo);
+   30519             : 
+   30520           0 :     i__1 = *n - 1;
+   30521           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   30522           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   30523             : 
+   30524           0 :     PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, &work[inddd], &work[indee], vl, vu, il, iu, 
+   30525             :             abstol, m, &w[1], &z__[z_offset], ldz, &isuppz[1], 
+   30526             :             &work[indwk], lwork, &iwork[1], liwork, info);
+   30527           0 :     if (wantz && *info == 0) {
+   30528             :       indwkn = inde;
+   30529           0 :       llwrkn = *lwork - indwkn + 1;
+   30530           0 :       PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)("L", uplo, "N", n, m, &a[a_offset], lda, &work[indtau]
+   30531             :               , &z__[z_offset], ldz, &work[indwkn], &llwrkn, &iinfo);
+   30532             :     }
+   30533             : 
+   30534           0 :     if (*info != 0) 
+   30535             :       return;
+   30536             : 
+   30537           0 :     if (iscale == 1) {
+   30538             :         if (*info == 0) {
+   30539           0 :             imax = *m;
+   30540             :         } else {
+   30541             :             imax = *info - 1;
+   30542             :         }
+   30543           0 :         d__1 = 1. / sigma;
+   30544           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&imax, &d__1, &w[1], &c__1);
+   30545             :     }
+   30546             : 
+   30547           0 :     if (wantz) {
+   30548           0 :         i__1 = *m - 1;
+   30549             :         
+   30550           0 :         for (j = 1; j <= i__1; ++j) {
+   30551             :             i__ = 0;
+   30552           0 :             tmp1 = w[j];
+   30553           0 :             i__2 = *m;
+   30554           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   30555           0 :                 if (w[jj] < tmp1) {
+   30556             :                     i__ = jj;
+   30557             :                     tmp1 = w[jj];
+   30558             :                 }
+   30559             :             }
+   30560             : 
+   30561           0 :             if (i__ != 0) {
+   30562           0 :                 itmp1 = iwork[indibl + i__ - 1];
+   30563           0 :                 w[i__] = w[j];
+   30564           0 :                 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
+   30565           0 :                 w[j] = tmp1;
+   30566           0 :                 iwork[indibl + j - 1] = itmp1;
+   30567           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
+   30568             :                          &c__1);
+   30569             :             }
+   30570             :         }
+   30571             :     }
+   30572             : 
+   30573           0 :     work[1] = (float) lwkopt;
+   30574           0 :     iwork[1] = liwmin;
+   30575           0 :     return;
+   30576             : 
+   30577             : }
+   30578             : }
+   30579             : }
+   30580             : #include <cctype>
+   30581             : #include <cmath>
+   30582             : 
+   30583             : #include "real.h"
+   30584             : 
+   30585             : #include "blas/blas.h"
+   30586             : #include "lapack.h"
+   30587             : 
+   30588             : #include "blas/blas.h"
+   30589             : namespace PLMD{
+   30590             : namespace lapack{
+   30591             : using namespace blas;
+   30592             : void
+   30593           0 : PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(const char *    uplo,
+   30594             :         int *     n,
+   30595             :         float *  a,
+   30596             :         int *     lda,
+   30597             :         float *  d,
+   30598             :         float *  e,
+   30599             :         float *  tau,
+   30600             :     int *     info)
+   30601             : {
+   30602             :   float minusone,zero;
+   30603             :   float taui,alpha,tmp;
+   30604             :   int ti1,ti2,ti3,i;
+   30605           0 :   const char ch=std::toupper(*uplo);
+   30606             : 
+   30607           0 :   zero = 0.0;
+   30608           0 :   minusone = -1.0;
+   30609             : 
+   30610           0 :   if(*n<=0)
+   30611             :     return;
+   30612             : 
+   30613           0 :   if(ch=='U') {
+   30614           0 :     for(i=*n-1;i>=1;i--) {
+   30615             : 
+   30616           0 :       ti1 = 1;
+   30617           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   30618           0 :       e[i-1] = a[i*(*lda) + (i-1)];
+   30619           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30620           0 :         a[i*(*lda)+(i-1)] = 1.0;
+   30621             :       
+   30622           0 :         ti1 = 1;
+   30623           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   30624             : 
+   30625           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   30626             : 
+   30627           0 :         alpha = -0.5*taui*tmp;
+   30628             : 
+   30629           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   30630             : 
+   30631           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   30632             : 
+   30633           0 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   30634             : 
+   30635             :       }
+   30636           0 :       d[i] = a[i*(*lda)+i];
+   30637           0 :       tau[i-1] = taui;
+   30638             :     }
+   30639           0 :     d[0] = a[0];
+   30640             :     
+   30641             :   } else {
+   30642             :     /* lower */
+   30643             : 
+   30644           0 :     for(i=1;i<*n;i++) {
+   30645             : 
+   30646           0 :       ti1 = *n - i;
+   30647           0 :       ti2 = ( *n < i+2) ? *n : i+2;
+   30648           0 :       ti3 = 1;
+   30649           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+ti2-1]),&ti3,&taui);
+   30650             : 
+   30651           0 :       e[i-1] = a[(i-1)*(*lda) + (i)];
+   30652             : 
+   30653           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30654           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   30655             :       
+   30656           0 :         ti1 = *n - i;
+   30657           0 :         ti2 = 1;
+   30658           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)(uplo,&ti1,&taui,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),
+   30659             :                &ti2,&zero,&(tau[i-1]),&ti2);
+   30660             :         
+   30661           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(tau[i-1]),&ti2,&(a[(i-1)*(*lda)+i]),&ti2);
+   30662             : 
+   30663           0 :         alpha = -0.5*taui*tmp;
+   30664             : 
+   30665           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2);
+   30666             : 
+   30667           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)(uplo,&ti1,&minusone,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2,
+   30668           0 :                &(a[(i)*(*lda)+i]),lda);
+   30669             : 
+   30670           0 :         a[(i-1)*(*lda)+(i)] = e[i-1]; 
+   30671             : 
+   30672             :       }
+   30673           0 :       d[i-1] = a[(i-1)*(*lda)+i-1];
+   30674           0 :       tau[i-1] = taui;
+   30675             :     }
+   30676           0 :     d[*n-1] = a[(*n-1)*(*lda)+(*n-1)];
+   30677             :  
+   30678             :   }
+   30679             :   return;
+   30680             : }
+   30681             : }
+   30682             : }
+   30683             : #include "blas/blas.h"
+   30684             : #include "lapack.h"
+   30685             : #include "lapack_limits.h"
+   30686             : 
+   30687             : #include "blas/blas.h"
+   30688             : namespace PLMD{
+   30689             : namespace lapack{
+   30690             : using namespace blas;
+   30691             : void
+   30692           0 : PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(const char *uplo, int *n, float *a, int *
+   30693             :         lda, float *d__, float *e, float *tau, float *
+   30694             :         work, int *lwork, int *info)
+   30695             : {
+   30696             :     /* System generated locals */
+   30697             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   30698             : 
+   30699             :     /* Local variables */
+   30700             :     int i__, j, nb, kk, nx, iws;
+   30701             :     int nbmin, iinfo;
+   30702             :     int upper;
+   30703             :     int ldwork, lwkopt;
+   30704             :     int lquery;
+   30705           0 :     float c_b22 = -1.;
+   30706           0 :     float c_b23 = 1.;
+   30707             : 
+   30708             : 
+   30709             :     /* Parameter adjustments */
+   30710           0 :     a_dim1 = *lda;
+   30711           0 :     a_offset = 1 + a_dim1;
+   30712           0 :     a -= a_offset;
+   30713           0 :     --d__;
+   30714           0 :     --e;
+   30715           0 :     --tau;
+   30716             :     --work;
+   30717             : 
+   30718             :     /* Function Body */
+   30719           0 :     *info = 0;
+   30720           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30721           0 :     lquery = (*lwork == -1);
+   30722             : 
+   30723           0 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   30724           0 :         *info = -1;
+   30725           0 :     } else if (*n < 0) {
+   30726           0 :         *info = -2;
+   30727           0 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   30728           0 :         *info = -4;
+   30729           0 :     } else if (*lwork < 1 && ! lquery) {
+   30730           0 :         *info = -9;
+   30731             :     }
+   30732             : 
+   30733           0 :     if (*info == 0) {
+   30734             : 
+   30735           0 :       nb = DSYTRD_BLOCKSIZE;
+   30736           0 :       lwkopt = *n * nb;
+   30737           0 :       work[1] = (float) lwkopt;
+   30738             :     } else
+   30739             :       return;
+   30740             : 
+   30741           0 :     if (lquery) 
+   30742             :       return;
+   30743             :   
+   30744           0 :     if (*n == 0) {
+   30745           0 :         work[1] = 1.;
+   30746           0 :         return;
+   30747             :     }
+   30748             : 
+   30749             :     nx = *n;
+   30750           0 :     if (nb > 1 && nb < *n) {
+   30751             : 
+   30752             :         nx = DSYTRD_CROSSOVER;
+   30753           0 :         if (nx < *n) {
+   30754             : 
+   30755           0 :             ldwork = *n;
+   30756           0 :             iws = ldwork * nb;
+   30757           0 :             if (*lwork < iws) {
+   30758             : 
+   30759           0 :                 i__1 = *lwork / ldwork;
+   30760           0 :                 nb = (i__1>1) ? i__1 : 1;
+   30761             :                 nbmin = DSYTRD_MINBLOCKSIZE;
+   30762           0 :                 if (nb < nbmin) {
+   30763             :                     nx = *n;
+   30764             :                 }
+   30765             :             }
+   30766             :         } else {
+   30767             :             nx = *n;
+   30768             :         }
+   30769             :     } else {
+   30770           0 :         nb = 1;
+   30771             :     }
+   30772             : 
+   30773           0 :     if (upper) {
+   30774             : 
+   30775           0 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   30776           0 :         i__1 = kk + 1;
+   30777             :         i__2 = -nb;
+   30778           0 :         for (i__ = *n - nb + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
+   30779             :                 i__2) {
+   30780             : 
+   30781           0 :             i__3 = i__ + nb - 1;
+   30782           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[a_offset], lda, &e[1], &tau[1], &
+   30783             :                     work[1], &ldwork);
+   30784             : 
+   30785           0 :             i__3 = i__ - 1;
+   30786           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ * a_dim1 
+   30787           0 :                     + 1], lda, &work[1], &ldwork, &c_b23, &a[a_offset], lda);
+   30788             : 
+   30789           0 :             i__3 = i__ + nb - 1;
+   30790           0 :             for (j = i__; j <= i__3; ++j) {
+   30791           0 :                 a[j - 1 + j * a_dim1] = e[j - 1];
+   30792           0 :                 d__[j] = a[j + j * a_dim1];
+   30793             : 
+   30794             :             }
+   30795             : 
+   30796             :         }
+   30797             : 
+   30798           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &kk, &a[a_offset], lda, &d__[1], &e[1], &tau[1], &iinfo);
+   30799             :     } else {
+   30800             : 
+   30801           0 :         i__2 = *n - nx;
+   30802           0 :         i__1 = nb;
+   30803           0 :         for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
+   30804             : 
+   30805             : 
+   30806           0 :             i__3 = *n - i__ + 1;
+   30807           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[i__ + i__ * a_dim1], lda, &e[i__], &
+   30808           0 :                     tau[i__], &work[1], &ldwork);
+   30809             : 
+   30810           0 :             i__3 = *n - i__ - nb + 1;
+   30811           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ + nb + 
+   30812           0 :                     i__ * a_dim1], lda, &work[nb + 1], &ldwork, &c_b23, &a[
+   30813           0 :                     i__ + nb + (i__ + nb) * a_dim1], lda);
+   30814             : 
+   30815             : 
+   30816           0 :             i__3 = i__ + nb - 1;
+   30817           0 :             for (j = i__; j <= i__3; ++j) {
+   30818           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   30819           0 :                 d__[j] = a[j + j * a_dim1];
+   30820             : 
+   30821             :             }
+   30822             : 
+   30823             :         }
+   30824             : 
+   30825             : 
+   30826           0 :         i__1 = *n - i__ + 1;
+   30827           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &i__1, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[i__], 
+   30828           0 :                 &tau[i__], &iinfo);
+   30829             :     }
+   30830             : 
+   30831           0 :     work[1] = (float) lwkopt;
+   30832           0 :     return;
+   30833             : 
+   30834             : }
+   30835             : 
+   30836             : 
+   30837             : }
+   30838             : }
+   30839             : #include "blas/blas.h"
+   30840             : #include "lapack.h"
+   30841             : #include "lapack_limits.h"
+   30842             : 
+   30843             : #include "blas/blas.h"
+   30844             : namespace PLMD{
+   30845             : namespace lapack{
+   30846             : using namespace blas;
+   30847             : void
+   30848           0 : PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(const char *uplo,
+   30849             :         const char *diag, 
+   30850             :         int *n, 
+   30851             :         float *a,
+   30852             :         int *lda,
+   30853             :         int *info)
+   30854             : {
+   30855             :     int a_dim1, a_offset, i__1, i__2;
+   30856             : 
+   30857             :     int j;
+   30858             :     float ajj;
+   30859             :     int upper, nounit;
+   30860           0 :     int c__1 = 1;
+   30861             : 
+   30862             : 
+   30863           0 :     a_dim1 = *lda;
+   30864           0 :     a_offset = 1 + a_dim1;
+   30865           0 :     a -= a_offset;
+   30866             : 
+   30867           0 :     *info = 0;
+   30868           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30869           0 :     nounit = (*diag=='N' || *diag=='n');
+   30870             : 
+   30871             :     if (*info != 0) {
+   30872             :         i__1 = -(*info);
+   30873             :         return;
+   30874             :     }
+   30875             : 
+   30876           0 :     if (upper) {
+   30877             : 
+   30878           0 :         i__1 = *n;
+   30879           0 :         for (j = 1; j <= i__1; ++j) {
+   30880           0 :             if (nounit) {
+   30881           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30882           0 :                 ajj = -a[j + j * a_dim1];
+   30883             :             } else {
+   30884           0 :                 ajj = -1.;
+   30885             :             }
+   30886             : 
+   30887           0 :             i__2 = j - 1;
+   30888           0 :             PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &
+   30889           0 :                     a[j * a_dim1 + 1], &c__1);
+   30890           0 :             i__2 = j - 1;
+   30891           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &ajj, &a[j * a_dim1 + 1], &c__1);
+   30892             :         }
+   30893             :     } else {
+   30894             : 
+   30895           0 :         for (j = *n; j >= 1; --j) {
+   30896           0 :             if (nounit) {
+   30897           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30898           0 :                 ajj = -a[j + j * a_dim1];
+   30899             :             } else {
+   30900           0 :                 ajj = -1.;
+   30901             :             }
+   30902           0 :             if (j < *n) {
+   30903             : 
+   30904           0 :                 i__1 = *n - j;
+   30905           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", diag, &i__1, &a[j + 1 + (j + 
+   30906           0 :                         1) * a_dim1], lda, &a[j + 1 + j * a_dim1], &c__1);
+   30907           0 :                 i__1 = *n - j;
+   30908           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &ajj, &a[j + 1 + j * a_dim1], &c__1);
+   30909             :             }
+   30910             :         }
+   30911             :     }
+   30912             :     return;
+   30913             : }
+   30914             : }
+   30915             : }
+   30916             : #include <cmath>
+   30917             : #include "blas/blas.h"
+   30918             : #include "lapack.h"
+   30919             : #include "lapack_limits.h"
+   30920             : 
+   30921             : #include "real.h"
+   30922             : 
+   30923             : #include "blas/blas.h"
+   30924             : namespace PLMD{
+   30925             : namespace lapack{
+   30926             : using namespace blas;
+   30927             : void
+   30928           0 : PLUMED_BLAS_F77_FUNC(strtri,STRTRI)(const char *uplo,
+   30929             :         const char *diag, 
+   30930             :         int *n,
+   30931             :         float *a, 
+   30932             :         int *lda,
+   30933             :         int *info)
+   30934             : {
+   30935             :     int a_dim1, a_offset, i__1, i__3, i__4, i__5;
+   30936             :     int j, jb, nb, nn;
+   30937           0 :     float c_b18 = 1.;
+   30938           0 :     float c_b22 = -1.;
+   30939             : 
+   30940             :     int upper;
+   30941             :     int nounit;
+   30942             : 
+   30943           0 :     a_dim1 = *lda;
+   30944           0 :     a_offset = 1 + a_dim1;
+   30945           0 :     a -= a_offset;
+   30946             : 
+   30947           0 :     *info = 0;
+   30948           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30949           0 :     nounit = (*diag=='N' || *diag=='n');
+   30950             : 
+   30951             :     if (*info != 0) {
+   30952             :         i__1 = -(*info);
+   30953             :         return;
+   30954             :     }
+   30955             : 
+   30956           0 :     if (*n == 0) {
+   30957             :         return;
+   30958             :     }
+   30959             : 
+   30960           0 :     if (nounit) {
+   30961           0 :         i__1 = *n;
+   30962           0 :         for (*info = 1; *info <= i__1; ++(*info)) {
+   30963           0 :             if (std::abs(a[*info + *info * a_dim1])<PLUMED_GMX_FLOAT_MIN) {
+   30964             :                 return;
+   30965             :             }
+   30966             :         }
+   30967           0 :         *info = 0;
+   30968             :     }
+   30969             : 
+   30970             :     nb = DTRTRI_BLOCKSIZE;
+   30971           0 :     if (nb <= 1 || nb >= *n) {
+   30972             : 
+   30973           0 :         PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(uplo, diag, n, &a[a_offset], lda, info);
+   30974             :     } else {
+   30975             : 
+   30976           0 :         if (upper) {
+   30977             : 
+   30978           0 :             i__1 = *n;
+   30979             :             i__3 = nb;
+   30980           0 :             for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) {
+   30981           0 :                 i__4 = nb, i__5 = *n - j + 1;
+   30982           0 :                 jb = (i__4<i__5) ? i__4 : i__5;
+   30983             : 
+   30984           0 :                 i__4 = j - 1;
+   30985           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Upper", "No transpose", diag, &i__4, &jb, &
+   30986           0 :                         c_b18, &a[a_offset], lda, &a[j * a_dim1 + 1], lda);
+   30987           0 :                 i__4 = j - 1;
+   30988           0 :                 PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Upper", "No transpose", diag, &i__4, &jb, &
+   30989           0 :                         c_b22, &a[j + j * a_dim1], lda, &a[j * a_dim1 + 1], 
+   30990             :                         lda);
+   30991             : 
+   30992           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Upper", diag, &jb, &a[j + j * a_dim1], lda, info);
+   30993             :             }
+   30994             :         } else {
+   30995             : 
+   30996           0 :             nn = (*n - 1) / nb * nb + 1;
+   30997             :             i__3 = -nb;
+   30998           0 :             for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) {
+   30999           0 :                 i__1 = nb, i__4 = *n - j + 1;
+   31000           0 :                 jb = (i__1<i__4) ? i__1 : i__4;
+   31001           0 :                 if (j + jb <= *n) {
+   31002             : 
+   31003           0 :                     i__1 = *n - j - jb + 1;
+   31004           0 :                     PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Lower", "No transpose", diag, &i__1, &jb, 
+   31005           0 :                             &c_b18, &a[j + jb + (j + jb) * a_dim1], lda, &a[j 
+   31006           0 :                             + jb + j * a_dim1], lda);
+   31007           0 :                     i__1 = *n - j - jb + 1;
+   31008           0 :                     PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", diag, &i__1, &jb,
+   31009           0 :                              &c_b22, &a[j + j * a_dim1], lda, &a[j + jb + j * 
+   31010           0 :                             a_dim1], lda);
+   31011             :                 }
+   31012             : 
+   31013           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Lower", diag, &jb, &a[j + j * a_dim1], lda, info);
+   31014             :             }
+   31015             :         }
+   31016             :     }
+   31017             :     return;
+   31018             : }
+   31019             : 
+   31020             : 
+   31021             : }
+   31022             : }
+   31023             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html new file mode 100644 index 0000000000..6212234fb2 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05:16Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv71
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev526
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1136
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1136
_ZN4PLMD6lepton18CompiledExpressionC2Ev1164
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1426
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1948
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2300
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2300
_ZN4PLMD6lepton18CompiledExpressionD2Ev2300
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3743
_ZN4PLMD6lepton9useAsmJitEv5877
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8589
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16042
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10695248
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901536
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func.html b/coverage-libs/lepton/CompiledExpression.cpp.func.html new file mode 100644 index 0000000000..9a0e5a93f4 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05:16Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2300
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2300
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16042
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1948
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8589
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3743
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMD6lepton18CompiledExpressionC2Ev1164
_ZN4PLMD6lepton18CompiledExpressionD2Ev2300
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1136
_ZN4PLMD6lepton9useAsmJitEv5877
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10695248
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1426
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev526
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901536
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv71
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.gcov.html b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html new file mode 100644 index 0000000000..bc0f0a5149 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html @@ -0,0 +1,585 @@ + + + + + + + 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-05-27 13:05:16Functions:181994.7 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.func.html b/coverage-libs/lepton/CompiledExpression.h.func.html new file mode 100644 index 0000000000..364f082d6b --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.gcov.html b/coverage-libs/lepton/CompiledExpression.h.gcov.html new file mode 100644 index 0000000000..19f87eaf9c --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.gcov.html @@ -0,0 +1,240 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZNK4PLMD6lepton9Exception4whatEv20
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE611
_ZN4PLMD6lepton9ExceptionD2Ev611
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func.html b/coverage-libs/lepton/Exception.h.func.html new file mode 100644 index 0000000000..c9675b8584 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:16Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE611
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZN4PLMD6lepton9ExceptionD2Ev611
_ZNK4PLMD6lepton9Exception4whatEv20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.gcov.html b/coverage-libs/lepton/Exception.h.gcov.html new file mode 100644 index 0000000000..35a18fe2c4 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.gcov.html @@ -0,0 +1,169 @@ + + + + + + + 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-05-27 13:05:16Functions:3475.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton17ExpressionProgram12buildProgramERKNS0_18ExpressionTreeNodeE0
_ZN4PLMD6lepton17ExpressionProgram12setOperationEiPNS0_9OperationE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKNS0_16ParsedExpressionE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKS1_0
_ZN4PLMD6lepton17ExpressionProgramC2Ev0
_ZN4PLMD6lepton17ExpressionProgramD2Ev0
_ZN4PLMD6lepton17ExpressionProgramaSERKS1_0
_ZNK4PLMD6lepton17ExpressionProgram12getOperationEi0
_ZNK4PLMD6lepton17ExpressionProgram12getStackSizeEv0
_ZNK4PLMD6lepton17ExpressionProgram16getNumOperationsEv0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.func.html b/coverage-libs/lepton/ExpressionProgram.cpp.func.html new file mode 100644 index 0000000000..281fbd332f --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:16Functions:0120.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton17ExpressionProgram12buildProgramERKNS0_18ExpressionTreeNodeE0
_ZN4PLMD6lepton17ExpressionProgram12setOperationEiPNS0_9OperationE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKNS0_16ParsedExpressionE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKS1_0
_ZN4PLMD6lepton17ExpressionProgramC2Ev0
_ZN4PLMD6lepton17ExpressionProgramD2Ev0
_ZN4PLMD6lepton17ExpressionProgramaSERKS1_0
_ZNK4PLMD6lepton17ExpressionProgram12getOperationEi0
_ZNK4PLMD6lepton17ExpressionProgram12getStackSizeEv0
_ZNK4PLMD6lepton17ExpressionProgram16getNumOperationsEv0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html new file mode 100644 index 0000000000..0fb2eacd5f --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + 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-05-27 13:05:16Functions:0120.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4104
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8433
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31689
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57700
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64603
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79706
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_86035
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119413
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021173
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094661
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136840
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2753562
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894636
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5837189
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7013501
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html new file mode 100644 index 0000000000..fb511d3f70 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:16Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31689
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021173
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4104
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8433
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57700
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2753562
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136840
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7013501
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094661
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64603
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79706
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5837189
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894636
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_86035
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119413
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html new file mode 100644 index 0000000000..8cdc828553 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + 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-05-27 13:05:16Functions:1515100.0 %
+
+ + + + + + + + +

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

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

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

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE597
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1088
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1112
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1136
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1136
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3320
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5818
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9949
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19812
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22789
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25877
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29780
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012034
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012733
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func.html b/coverage-libs/lepton/ParsedExpression.cpp.func.html new file mode 100644 index 0000000000..f2268eeb6e --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05:16Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29780
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5818
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3320
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19812
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25877
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22789
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012733
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012034
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1088
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9949
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013743
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE597
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1136
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1112
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1136
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.gcov.html b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html new file mode 100644 index 0000000000..8351cccfe9 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html @@ -0,0 +1,527 @@ + + + + + + + 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-05-27 13:05:16Functions:162176.2 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.func.html b/coverage-libs/lepton/ParsedExpression.h.func.html new file mode 100644 index 0000000000..b8cd5cd619 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.gcov.html b/coverage-libs/lepton/ParsedExpression.h.gcov.html new file mode 100644 index 0000000000..a48eb089a7 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + 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-05-27 13:05:16Functions:00-
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv40
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1693
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5036
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009189
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009208
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009208
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009212
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016749
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024272
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func.html b/coverage-libs/lepton/Parser.cpp.func.html new file mode 100644 index 0000000000..cc6241fd5f --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:16Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024272
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016749
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1693
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5036
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009208
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009208
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009212
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009189
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.gcov.html b/coverage-libs/lepton/Parser.cpp.gcov.html new file mode 100644 index 0000000000..980f177588 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.gcov.html @@ -0,0 +1,584 @@ + + + + + + + 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-05-27 13:05:16Functions:1010100.0 %
+
+ + + + + + + + +

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

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

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

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11put_trx_intEPNS0_7md_fileEi0
_ZN4PLMD7molfileL11strip_whiteEPc0
_ZN4PLMD7molfileL12g96_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12gro_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE195
_ZN4PLMD7molfileL10mdio_errnoEv195
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE195
_ZN4PLMD7molfileL9mdio_openEPKcii195
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj18106
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci18106
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18107
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18257
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_18257
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18297
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18452
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf199179
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi217846
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL13mdio_seterrorEi2419581
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_20188378
_ZN4PLMD7molfileL15xtc_receivebitsEPii90001066
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func.html b/coverage-libs/molfile/Gromacs.h.func.html new file mode 100644 index 0000000000..96d195d180 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-05-27 13:05:16Functions:223661.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE195
_ZN4PLMD7molfileL10mdio_errnoEv195
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE195
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18257
_ZN4PLMD7molfileL11put_trx_intEPNS0_7md_fileEi0
_ZN4PLMD7molfileL11strip_whiteEPc0
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL12g96_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12gro_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_18257
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18107
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18297
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13mdio_seterrorEi2419581
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18452
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj18106
_ZN4PLMD7molfileL15xtc_receivebitsEPii90001066
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_20188378
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi217846
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci18106
_ZN4PLMD7molfileL9mdio_openEPKcii195
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf199179
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.gcov.html b/coverage-libs/molfile/Gromacs.h.gcov.html new file mode 100644 index 0000000000..c0d780d7b1 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.gcov.html @@ -0,0 +1,2089 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-05-27 13:05:16Functions:223661.1 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_crdplugin_finiEv0
_ZN4PLMD7molfile22molfile_crdplugin_initEv8336
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8336
_ZN4PLMD7molfileL13open_crd_readEPKcS2_Pi2
_ZN4PLMD7molfileL14close_crd_readEPv2
_ZN4PLMD7molfileL14open_crd_writeEPKcS2_i0
_ZN4PLMD7molfileL15close_crd_writeEPv0
_ZN4PLMD7molfileL17read_crd_timestepEPviPNS0_18molfile_timestep_tE5
_ZN4PLMD7molfileL18write_crd_timestepEPvPKNS0_18molfile_timestep_tE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.gcov.html b/coverage-libs/molfile/crdplugin.cpp.gcov.html new file mode 100644 index 0000000000..20a502b112 --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.gcov.html @@ -0,0 +1,338 @@ + + + + + + + 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-05-27 13:05:16Functions: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        8336 : VMDPLUGIN_API int VMDPLUGIN_init(void) { 
+     226             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     227        8336 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     228        8336 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     229        8336 :   plugin.name = "crd";
+     230        8336 :   plugin.prettyname = "AMBER Coordinates";
+     231        8336 :   plugin.author = "Justin Gullingsrud, John Stone";
+     232             :   plugin.majorv = 0;
+     233        8336 :   plugin.minorv = 9;
+     234        8336 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     235        8336 :   plugin.filename_extension = "mdcrd,crd";
+     236        8336 :   plugin.open_file_read = open_crd_read;
+     237        8336 :   plugin.read_next_timestep = read_crd_timestep;
+     238        8336 :   plugin.close_file_read = close_crd_read;
+     239        8336 :   plugin.open_file_write = open_crd_write;
+     240        8336 :   plugin.write_timestep = write_crd_timestep;
+     241        8336 :   plugin.close_file_write = close_crd_write;
+     242             : 
+     243             :   memcpy(&crdboxplugin, &plugin, sizeof(molfile_plugin_t));
+     244        8336 :   crdboxplugin.name = "crdbox";
+     245        8336 :   crdboxplugin.prettyname = "AMBER Coordinates with Periodic Box";
+     246             : 
+     247        8336 :   return VMDPLUGIN_SUCCESS; 
+     248             : }
+     249             : 
+     250        8336 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     251        8336 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     252        8336 :   (*cb)(v, (vmdplugin_t *)&crdboxplugin);
+     253        8336 :   return VMDPLUGIN_SUCCESS;
+     254             : }
+     255             : 
+     256           0 : VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
+     257             : 
+     258             : }
+     259             : }
+     260             : 
+     261             : #endif
+     262             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html b/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html new file mode 100644 index 0000000000..94bfdc6ee6 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-05-27 13:05:16Functions: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_initEv8336
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8336
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.func.html b/coverage-libs/molfile/dcdplugin.cpp.func.html new file mode 100644 index 0000000000..88040920b5 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-05-27 13:05:16Functions:101952.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_dcdplugin_finiEv0
_ZN4PLMD7molfile22molfile_dcdplugin_initEv8336
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8336
_ZN4PLMD7molfileL12read_dcdstepEiiPfS1_S1_S1_iiPiS1_ii21
_ZN4PLMD7molfileL12skip_dcdstepEiiii0
_ZN4PLMD7molfileL13open_dcd_readEPKcS2_Pi1
_ZN4PLMD7molfileL13write_dcdstepEiiiiPKfS2_S2_PKdi0
_ZN4PLMD7molfileL14close_dcd_readEPiPf1
_ZN4PLMD7molfileL14open_dcd_writeEPKcS2_i0
_ZN4PLMD7molfileL14print_dcderrorEPKci0
_ZN4PLMD7molfileL14read_dcdheaderEiPiS1_S1_S1_PdS1_PS1_PPfS1_S1_1
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15close_file_readEPv1
_ZN4PLMD7molfileL15write_dcdheaderEiPKciiidii0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL16read_charmm_4dimEiii21
_ZN4PLMD7molfileL16read_fixed_atomsEiiiPKiiPKfPfS5_i0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE22
_ZN4PLMD7molfileL22read_charmm_extrablockEiiiPf21
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.gcov.html b/coverage-libs/molfile/dcdplugin.cpp.gcov.html new file mode 100644 index 0000000000..6e8388488e --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.gcov.html @@ -0,0 +1,1393 @@ + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-05-27 13:05:16Functions:101952.6 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL13swap8_alignedEPvl0
_ZN4PLMD7molfileL15swap4_unalignedEPvl0
_ZN4PLMD7molfileL15swap8_unalignedEPvl0
_ZN4PLMD7molfileL13swap4_alignedEPvl1461240
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.func.html b/coverage-libs/molfile/endianswap.h.func.html new file mode 100644 index 0000000000..73ecdc2333 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:16Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL13swap4_alignedEPvl1461240
_ZN4PLMD7molfileL13swap8_alignedEPvl0
_ZN4PLMD7molfileL15swap4_unalignedEPvl0
_ZN4PLMD7molfileL15swap8_unalignedEPvl0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.gcov.html b/coverage-libs/molfile/endianswap.h.gcov.html new file mode 100644 index 0000000000..fdb44e3654 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.gcov.html @@ -0,0 +1,293 @@ + + + + + + + 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-05-27 13:05:16Functions:1425.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10fio_fwriteEPvlli0
_ZN4PLMD7molfileL15fio_write_int32Eii0
_ZN4PLMD7molfileL10fio_fcloseEi1
_ZN4PLMD7molfileL8fio_openEPKciPi1
_ZN4PLMD7molfileL9fio_ftellEi1
_ZN4PLMD7molfileL9fio_fseekEili2
_ZN4PLMD7molfileL9fio_freadEPvlli219
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/fastio.h.func.html b/coverage-libs/molfile/fastio.h.func.html new file mode 100644 index 0000000000..1929f0a5d4 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10fio_fcloseEi1
_ZN4PLMD7molfileL10fio_fwriteEPvlli0
_ZN4PLMD7molfileL15fio_write_int32Eii0
_ZN4PLMD7molfileL8fio_openEPKciPi1
_ZN4PLMD7molfileL9fio_freadEPvlli219
_ZN4PLMD7molfileL9fio_fseekEili2
_ZN4PLMD7molfileL9fio_ftellEi1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/fastio.h.gcov.html b/coverage-libs/molfile/fastio.h.gcov.html new file mode 100644 index 0000000000..e7a2928748 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.gcov.html @@ -0,0 +1,759 @@ + + + + + + + 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-05-27 13:05:16Functions:5771.4 %
+
+ + + + + + + + +

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

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

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

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

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

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

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Gromacs.h +
45.6%45.6%
+
45.6 %342 / 75061.1 %22 / 36
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
dcdplugin.cpp +
43.6%43.6%
+
43.6 %201 / 46152.6 %10 / 19
endianswap.h +
12.5%12.5%
+
12.5 %6 / 4825.0 %1 / 4
fastio.h +
55.9%55.9%
+
55.9 %19 / 3471.4 %5 / 7
gromacsplugin.cpp +
29.7%29.7%
+
29.7 %107 / 36021.7 %5 / 23
pdbplugin.cpp +
41.2%41.2%
+
41.2 %87 / 21135.7 %5 / 14
periodic_table.h +
0.0%
+
0.0 %0 / 200.0 %0 / 4
readpdb.h +
32.6%32.6%
+
32.6 %44 / 13537.5 %3 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html b/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html new file mode 100644 index 0000000000..fcb736acbc --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:16Functions: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_Pi49
_ZN4PLMD7molfileL14close_pdb_readEPv49
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE109
_ZN4PLMD7molfile22molfile_pdbplugin_initEv8336
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8336
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.func.html b/coverage-libs/molfile/pdbplugin.cpp.func.html new file mode 100644 index 0000000000..8ffe184e7e --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:16Functions:51435.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_pdbplugin_finiEv0
_ZN4PLMD7molfile22molfile_pdbplugin_initEv8336
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8336
_ZN4PLMD7molfileL10read_bondsEPvPiPS2_S3_PPfS3_S2_PPPc0
_ZN4PLMD7molfileL12write_cryst1EP8_IO_FILEPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL13open_pdb_readEPKcS2_Pi49
_ZN4PLMD7molfileL14close_pdb_readEPv49
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15open_file_writeEPKcS2_i0
_ZN4PLMD7molfileL15write_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE109
_ZN4PLMD7molfileL18read_pdb_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL22read_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.gcov.html b/coverage-libs/molfile/pdbplugin.cpp.gcov.html new file mode 100644 index 0000000000..17c98df104 --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.gcov.html @@ -0,0 +1,724 @@ + + + + + + + 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-05-27 13:05:16Functions: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          49 : 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          49 :   fd = fopen(filepath, "r");
+      95          49 :   if (!fd) 
+      96             :     return NULL;
+      97          49 :   pdb = (pdbdata *)malloc(sizeof(pdbdata));
+      98          49 :   pdb->fd = fd;
+      99          49 :   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          49 :   *natoms=0;
+     106             :   nconect=0;
+     107             :   do {
+     108      101357 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     109      101357 :     if (indx == PDB_ATOM) {
+     110      101142 :       *natoms += 1;
+     111         215 :     } else if (indx == PDB_CONECT) {
+     112           0 :       nconect++;
+     113         215 :     } 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         215 :     } else if (indx == PDB_REMARK || indx == PDB_CONECT || indx == PDB_UNKNOWN) {
+     118         136 :       int len=strlen(pdbstr);
+     119         136 :       int newlen = len + pdb->meta->remarklen;
+     120             : 
+     121         136 :       char *newstr=(char*)realloc(pdb->meta->remarks, newlen + 1);
+     122         136 :       if (newstr != NULL) {
+     123         136 :         pdb->meta->remarks = newstr;
+     124         136 :         pdb->meta->remarks[pdb->meta->remarklen] = '\0';
+     125         136 :         memcpy(pdb->meta->remarks + pdb->meta->remarklen, pdbstr, len);
+     126         136 :         pdb->meta->remarks[newlen] = '\0';
+     127         136 :         pdb->meta->remarklen = newlen;
+     128             :       }
+     129             :     }
+     130             :  
+     131      101357 :   } while (indx != PDB_END && indx != PDB_EOF);
+     132             : 
+     133             :   /* If no atoms were found, this is probably not a PDB file! */
+     134          49 :   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          49 :   rewind(pdb->fd); /* if ok, rewind file and prepare to parse it for real */
+     145          49 :   pdb->natoms = *natoms;
+     146          49 :   pdb->nconect = nconect;
+     147          49 :   pdb->nbonds = 0;
+     148          49 :   pdb->maxbnum = 0;
+     149          49 :   pdb->from = NULL;
+     150          49 :   pdb->to = NULL;
+     151          49 :   pdb->idxmap = NULL;
+     152          49 :   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          49 :   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         109 : 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         109 :   if (pdb->natoms == 0) 
+     286             :     return MOLFILE_ERROR; /* EOF */
+     287         109 :   if (ts) {
+     288         109 :     x = ts->coords;
+     289         109 :     y = x+1;
+     290         109 :     z = x+2;
+     291             :   } else {
+     292             :     x = y = z = 0;
+     293             :   } 
+     294             :   i = 0;
+     295             :   do {
+     296      105533 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     297      105533 :     if((indx == PDB_END || indx == PDB_EOF) && (i < pdb->natoms)) {
+     298             :       return MOLFILE_ERROR;
+     299      105484 :     } else if(indx == PDB_ATOM) {
+     300      105240 :       if(i++ >= pdb->natoms) {
+     301             :         break;      
+     302             :       }
+     303             :       /* just get the coordinates, and store them */
+     304      105240 :       if (ts) {
+     305      105240 :         get_pdb_coordinates(pdbstr, x, y, z, &occup, &bfac);
+     306      105240 :         x += 3;
+     307      105240 :         y += 3;
+     308      105240 :         z += 3;
+     309             :       } 
+     310         244 :     } else if (indx == PDB_CRYST1) {
+     311          32 :       if (ts) {
+     312          32 :         get_pdb_cryst1(pdbstr, &ts->alpha, &ts->beta, &ts->gamma,
+     313             :                                &ts->A, &ts->B, &ts->C);
+     314             :       }
+     315             :     }
+     316      105484 :   } while(!(indx == PDB_END || indx == PDB_EOF));
+     317             : 
+     318             :   return MOLFILE_SUCCESS;
+     319             : }
+     320             : 
+     321          49 : static void close_pdb_read(void *v) { 
+     322             :   pdbdata *pdb = (pdbdata *)v;
+     323          49 :   if (pdb->fd != NULL)
+     324          49 :     fclose(pdb->fd);
+     325          49 :   if (pdb->idxmap != NULL)
+     326           0 :     free(pdb->idxmap);
+     327          49 :   if (pdb->meta->remarks != NULL)
+     328          38 :     free(pdb->meta->remarks);
+     329          49 :   if (pdb->meta != NULL) 
+     330          49 :     free(pdb->meta);
+     331          49 :   free(pdb);
+     332          49 : }
+     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        8336 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     613             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     614        8336 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     615        8336 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     616        8336 :   plugin.name = "pdb";
+     617        8336 :   plugin.prettyname = "PDB";
+     618        8336 :   plugin.author = "Justin Gullingsrud, John Stone";
+     619        8336 :   plugin.majorv = 1;
+     620        8336 :   plugin.minorv = 16;
+     621        8336 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     622        8336 :   plugin.filename_extension = "pdb,ent";
+     623        8336 :   plugin.open_file_read = open_pdb_read;
+     624        8336 :   plugin.read_structure = read_pdb_structure;
+     625        8336 :   plugin.read_bonds = read_bonds;
+     626        8336 :   plugin.read_next_timestep = read_next_timestep;
+     627        8336 :   plugin.close_file_read = close_pdb_read;
+     628        8336 :   plugin.open_file_write = open_file_write;
+     629        8336 :   plugin.write_structure = write_structure;
+     630        8336 :   plugin.write_timestep = write_timestep;
+     631        8336 :   plugin.close_file_write = close_file_write;
+     632        8336 :   plugin.read_molecule_metadata = read_molecule_metadata;
+     633        8336 :   return VMDPLUGIN_SUCCESS;
+     634             : }
+     635             : 
+     636        8336 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     637        8336 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     638        8336 :   return VMDPLUGIN_SUCCESS;
+     639             : }
+     640             : 
+     641           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+     642           0 :   return VMDPLUGIN_SUCCESS;
+     643             : }
+     644             : 
+     645             : }
+     646             : }
+     647             : 
+     648             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.func-sort-c.html b/coverage-libs/molfile/periodic_table.h.func-sort-c.html new file mode 100644 index 0000000000..90e82b2841 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:16Functions:040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL12get_pte_massEi0
_ZN4PLMD7molfileL13get_pte_labelEi0
_ZN4PLMD7molfileL18get_pte_vdw_radiusEi0
_ZN4PLMD7molfileL23get_pte_idx_from_stringEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.func.html b/coverage-libs/molfile/periodic_table.h.func.html new file mode 100644 index 0000000000..bd0322b547 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:16Functions:040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL12get_pte_massEi0
_ZN4PLMD7molfileL13get_pte_labelEi0
_ZN4PLMD7molfileL18get_pte_vdw_radiusEi0
_ZN4PLMD7molfileL23get_pte_idx_from_stringEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.gcov.html b/coverage-libs/molfile/periodic_table.h.gcov.html new file mode 100644 index 0000000000..9d052fec60 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.gcov.html @@ -0,0 +1,324 @@ + + + + + + + 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-05-27 13:05:16Functions:040.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_periodic_table_h
+      38             : #define __PLUMED_molfile_periodic_table_h
+      39             : /***************************************************************************
+      40             :  * RCS INFORMATION:
+      41             :  *
+      42             :  *      $RCSfile: periodic_table.h,v $
+      43             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      44             :  *      $Revision: 1.12 $       $Date: 2009/01/21 17:45:41 $
+      45             :  *
+      46             :  ***************************************************************************/
+      47             : 
+      48             : /*
+      49             :  * periodic table of elements and helper functions to convert
+      50             :  * ordinal numbers to labels and back.
+      51             :  * all tables and functions are declared static, so that it
+      52             :  * can be safely included by all plugins that may need it.
+      53             :  *
+      54             :  * 2002-2009 akohlmey@cmm.chem.upenn.edu, vmd@ks.uiuc.edu
+      55             :  */
+      56             : 
+      57             : #include <string.h>
+      58             : #include <ctype.h>
+      59             : 
+      60             : namespace PLMD{
+      61             : namespace molfile{
+      62             : /* periodic table of elements for translation of ordinal to atom type */
+      63             : static const char *pte_label[] = { 
+      64             :     "X",  "H",  "He", "Li", "Be", "B",  "C",  "N",  "O",  "F",  "Ne",
+      65             :     "Na", "Mg", "Al", "Si", "P" , "S",  "Cl", "Ar", "K",  "Ca", "Sc",
+      66             :     "Ti", "V",  "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", 
+      67             :     "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",  "Zr", "Nb", "Mo", "Tc",
+      68             :     "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I",  "Xe",
+      69             :     "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb",
+      70             :     "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W",  "Re", "Os",
+      71             :     "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr",
+      72             :     "Ra", "Ac", "Th", "Pa", "U",  "Np", "Pu", "Am", "Cm", "Bk", "Cf",
+      73             :     "Es", "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
+      74             :     "Ds", "Rg"
+      75             : };
+      76             : static const int nr_pte_entries = sizeof(pte_label) / sizeof(char *);
+      77             : 
+      78             : /* corresponding table of masses. */
+      79             : static const float pte_mass[] = { 
+      80             :     /* X  */ 0.00000, 1.00794, 4.00260, 6.941, 9.012182, 10.811,  
+      81             :     /* C  */ 12.0107, 14.0067, 15.9994, 18.9984032, 20.1797, 
+      82             :     /* Na */ 22.989770, 24.3050, 26.981538, 28.0855, 30.973761,
+      83             :     /* S  */ 32.065, 35.453, 39.948, 39.0983, 40.078, 44.955910,
+      84             :     /* Ti */ 47.867, 50.9415, 51.9961, 54.938049, 55.845, 58.9332,
+      85             :     /* Ni */ 58.6934, 63.546, 65.409, 69.723, 72.64, 74.92160, 
+      86             :     /* Se */ 78.96, 79.904, 83.798, 85.4678, 87.62, 88.90585, 
+      87             :     /* Zr */ 91.224, 92.90638, 95.94, 98.0, 101.07, 102.90550,
+      88             :     /* Pd */ 106.42, 107.8682, 112.411, 114.818, 118.710, 121.760, 
+      89             :     /* Te */ 127.60, 126.90447, 131.293, 132.90545, 137.327, 
+      90             :     /* La */ 138.9055, 140.116, 140.90765, 144.24, 145.0, 150.36,
+      91             :     /* Eu */ 151.964, 157.25, 158.92534, 162.500, 164.93032, 
+      92             :     /* Er */ 167.259, 168.93421, 173.04, 174.967, 178.49, 180.9479,
+      93             :     /* W  */ 183.84, 186.207, 190.23, 192.217, 195.078, 196.96655, 
+      94             :     /* Hg */ 200.59, 204.3833, 207.2, 208.98038, 209.0, 210.0, 222.0, 
+      95             :     /* Fr */ 223.0, 226.0, 227.0, 232.0381, 231.03588, 238.02891,
+      96             :     /* Np */ 237.0, 244.0, 243.0, 247.0, 247.0, 251.0, 252.0, 257.0,
+      97             :     /* Md */ 258.0, 259.0, 262.0, 261.0, 262.0, 266.0, 264.0, 269.0,
+      98             :     /* Mt */ 268.0, 271.0, 272.0
+      99             : };
+     100             : 
+     101             : /*
+     102             :  * corresponding table of VDW radii.
+     103             :  * van der Waals radii are taken from A. Bondi, 
+     104             :  * J. Phys. Chem., 68, 441 - 452, 1964, 
+     105             :  * except the value for H, which is taken from R.S. Rowland & R. Taylor, 
+     106             :  * J.Phys.Chem., 100, 7384 - 7391, 1996. Radii that are not available in 
+     107             :  * either of these publications have RvdW = 2.00 Å.
+     108             :  * The radii for Ions (Na, K, Cl, Ca, Mg, and Cs are based on the CHARMM27 
+     109             :  * Rmin/2 parameters for (SOD, POT, CLA, CAL, MG, CES) by default.
+     110             :  */
+     111             : static const float pte_vdw_radius[] = { 
+     112             :     /* X  */ 1.5, 1.2, 1.4, 1.82, 2.0, 2.0,  
+     113             :     /* C  */ 1.7, 1.55, 1.52, 1.47, 1.54, 
+     114             :     /* Na */ 1.36, 1.18, 2.0, 2.1, 1.8,
+     115             :     /* S  */ 1.8, 2.27, 1.88, 1.76, 1.37, 2.0,
+     116             :     /* Ti */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     117             :     /* Ni */ 1.63, 1.4, 1.39, 1.07, 2.0, 1.85,
+     118             :     /* Se */ 1.9, 1.85, 2.02, 2.0, 2.0, 2.0, 
+     119             :     /* Zr */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     120             :     /* Pd */ 1.63, 1.72, 1.58, 1.93, 2.17, 2.0, 
+     121             :     /* Te */ 2.06, 1.98, 2.16, 2.1, 2.0,
+     122             :     /* La */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     123             :     /* Eu */ 2.0, 2.0, 2.0, 2.0, 2.0,
+     124             :     /* Er */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     125             :     /* W  */ 2.0, 2.0, 2.0, 2.0, 1.72, 1.66,
+     126             :     /* Hg */ 1.55, 1.96, 2.02, 2.0, 2.0, 2.0, 2.0,
+     127             :     /* Fr */ 2.0, 2.0, 2.0, 2.0, 2.0, 1.86,
+     128             :     /* Np */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     129             :     /* Md */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     130             :     /* Mt */ 2.0, 2.0, 2.0
+     131             : };
+     132             : 
+     133             : /* lookup functions */
+     134             : 
+     135           0 : static const char *get_pte_label(const int idx)
+     136             : {
+     137           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_label[0];
+     138             : 
+     139           0 :     return pte_label[idx];
+     140             : }
+     141             : 
+     142           0 : static float get_pte_mass(const int idx)
+     143             : {
+     144           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_mass[0];
+     145             : 
+     146           0 :     return pte_mass[idx];
+     147             : }
+     148             : 
+     149           0 : static float get_pte_vdw_radius(const int idx)
+     150             : {
+     151           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_vdw_radius[0];
+     152             : 
+     153             : #if 1
+     154             :     /* Replace with Hydrogen radius with an "all-atom" radius */
+     155           0 :     if (idx == 1)
+     156             :       return 1.0;    /* H  */
+     157             : #else
+     158             :     /* Replace with old VMD atom radii values */
+     159             :     switch (idx) {
+     160             :       case  1: return 1.0;    /* H  */
+     161             :       case  6: return 1.5;    /* C  */
+     162             :       case  7: return 1.4;    /* N  */
+     163             :       case  8: return 1.3;    /* O  */
+     164             :       case  9: return 1.2;    /* F  */
+     165             :       case 15: return 1.5;    /* P  */
+     166             :       case 16: return 1.9;    /* S  */ 
+     167             :     }
+     168             : #endif
+     169             : 
+     170           0 :     return pte_vdw_radius[idx];
+     171             : }
+     172             : 
+     173             : static int get_pte_idx(const char *label)
+     174             : {
+     175             :     int i;
+     176             :     char atom[3];
+     177             :     
+     178             :     /* zap string */
+     179             :     atom[0] = (char) 0;
+     180             :     atom[1] = (char) 0;
+     181             :     atom[2] = (char) 0;
+     182             :     /* if we don't have a null-pointer, there must be at least two 
+     183             :      * chars, which is all we need. we convert to the capitalization 
+     184             :      * convention of the table above during assignment. */
+     185             :     if (label != NULL) {
+     186             :         atom[0] = (char) toupper((int) label[0]);
+     187             :         atom[1] = (char) tolower((int) label[1]);
+     188             :     }
+     189             :     /* discard numbers in atom label */
+     190             :     if (isdigit(atom[1])) atom[1] = (char) 0;
+     191             :     
+     192             :     for (i=0; i < nr_pte_entries; ++i) {
+     193             :         if ( (pte_label[i][0] == atom[0])
+     194             :              && (pte_label[i][1] == atom[1]) ) return i;
+     195             :     }
+     196             :     
+     197             :     return 0;
+     198             : }
+     199             : 
+     200           0 : static int get_pte_idx_from_string(const char *label) {
+     201             :   int i, ind;
+     202             :   char atom[3];
+     203             : 
+     204           0 :   if (label != NULL) {
+     205             :     /* zap string */
+     206           0 :     atom[0] = atom[1] = atom[2] = '\0';
+     207             : 
+     208           0 :     for (ind=0,i=0; (ind<2) && (label[i]!='\0'); i++) {
+     209           0 :       if (label[i] != ' ') {
+     210           0 :         atom[ind] = toupper(label[i]);
+     211           0 :         ind++;
+     212             :       }
+     213             :     }
+     214             : 
+     215           0 :     if (ind < 1)
+     216             :       return 0; /* no non-whitespace characters */
+     217             :  
+     218           0 :     for (i=0; i < nr_pte_entries; ++i) {
+     219           0 :       if ((toupper(pte_label[i][0]) == atom[0]) && (toupper(pte_label[i][1]) == atom[1])) 
+     220             :         return i;
+     221             :     }
+     222             :   }  
+     223             : 
+     224             :   return 0;
+     225             : }
+     226             : 
+     227             : #if 0
+     228             : #include <stdio.h>
+     229             : 
+     230             : int main() {
+     231             :   int i;
+     232             : 
+     233             :   printf("Periodic table check/dump\n");
+     234             :   printf("  Table contains data for %d elements\n", nr_pte_entries);
+     235             :   printf("   Mass table size check: %d\n", sizeof(pte_mass) / sizeof(float));
+     236             :   printf("    VDW table size check: %d\n", sizeof(pte_vdw_radius) / sizeof(float));
+     237             :   printf("\n");
+     238             :   printf("Symbol Num    Mass   rVDW\n");
+     239             :   for (i=0; i<nr_pte_entries; i++) {
+     240             :     printf("   %-2s  %3d  %6.2f  %4.2f\n",
+     241             :       get_pte_label(i), i, get_pte_mass(i), get_pte_vdw_radius(i));
+     242             :   } 
+     243             :   return 0;
+     244             : }
+     245             : #endif
+     246             : }
+     247             : }
+     248             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.func-sort-c.html b/coverage-libs/molfile/readpdb.h.func-sort-c.html new file mode 100644 index 0000000000..f60ef98bec --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:16Functions: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_32
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_105240
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc206890
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.func.html b/coverage-libs/molfile/readpdb.h.func.html new file mode 100644 index 0000000000..c577704cfb --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:16Functions: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_32
_ZN4PLMD7molfileL14get_pdb_fieldsEPKciPiPcS4_S4_S4_S4_S4_S4_S4_PfS5_S5_S5_S5_0
_ZN4PLMD7molfileL14get_pdb_headerEPKcPcS3_S3_0
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc206890
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_105240
_ZN4PLMD7molfileL20write_raw_pdb_recordEP8_IO_FILEPKciS4_S4_iS4_S4_S4_fffffS4_S4_0
_ZN4PLMD7molfileL23adjust_pdb_field_stringEPc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.gcov.html b/coverage-libs/molfile/readpdb.h.gcov.html new file mode 100644 index 0000000000..b192382189 --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.gcov.html @@ -0,0 +1,523 @@ + + + + + + + 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-05-27 13:05:16Functions: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      206890 : 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      206890 :   if (inbuf != fgets(inbuf, PDB_RECORD_LENGTH + 2, f)) {
+      93          49 :     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      206841 :     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         459 :     } else if (!strncmp(inbuf, "CONECT", 6)) {
+     113             :       recType = PDB_CONECT;
+     114         459 :     } else if (!strncmp(inbuf, "REMARK", 6)) {
+     115             :       recType = PDB_REMARK;
+     116         369 :     } else if (!strncmp(inbuf, "CRYST1", 6)) {
+     117             :       recType = PDB_CRYST1;
+     118         307 :     } else if (!strncmp(inbuf, "HEADER", 6)) {
+     119             :       recType = PDB_HEADER;
+     120         307 :     } 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      206890 :   ch = fgetc(f);
+     146      206890 :   if (ch != '\r')
+     147      206890 :     ungetc(ch, f);
+     148             :   
+     149      206890 :   return recType;
+     150             : }
+     151             : 
+     152             : 
+     153             : /* Extract the alpha/beta/gamma a/b/c unit cell info from a CRYST1 record */
+     154          32 : 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          32 :   s = tmp+6 ;          ch = tmp[15]; tmp[15] = 0;
+     163          32 :   *a = (float) atof(s);
+     164          32 :   s = tmp+15; *s = ch; ch = tmp[24]; tmp[24] = 0;
+     165          32 :   *b = (float) atof(s);
+     166          32 :   s = tmp+24; *s = ch; ch = tmp[33]; tmp[33] = 0;
+     167          32 :   *c = (float) atof(s);
+     168          32 :   s = tmp+33; *s = ch; ch = tmp[40]; tmp[40] = 0;
+     169          32 :   *alpha = (float) atof(s);
+     170          32 :   s = tmp+40; *s = ch; ch = tmp[47]; tmp[47] = 0;
+     171          32 :   *beta = (float) atof(s);
+     172          32 :   s = tmp+47; *s = ch; ch = tmp[54]; tmp[54] = 0;
+     173          32 :   *gamma = (float) atof(s);
+     174          32 : }
+     175             : 
+     176             : 
+     177             : /* Extract the x,y,z coords, occupancy, and beta from an ATOM record */
+     178      105240 : 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      105240 :   if (x != NULL) {
+     185      105240 :     strncpy(numstr, record + 30, 8);
+     186      105240 :     *x = (float) atof(numstr);
+     187             :   }
+     188             : 
+     189      105240 :   if (y != NULL) {
+     190      105240 :     strncpy(numstr+10, record + 38, 8);
+     191      105240 :     *y = (float) atof(numstr+10);
+     192             :   }
+     193             : 
+     194      105240 :   if (z != NULL) {
+     195      105240 :     strncpy(numstr+20, record + 46, 8);
+     196      105240 :     *z = (float) atof(numstr+20);
+     197             :   }
+     198             : 
+     199      105240 :   if (occup != NULL) {
+     200      105240 :     strncpy(numstr+30, record + 54, 6);
+     201      105240 :     *occup = (float) atof(numstr+30);
+     202             :   }
+     203             : 
+     204      105240 :   if (beta != NULL) {
+     205      105240 :     strncpy(numstr+40, record + 60, 6);
+     206      105240 :     *beta = (float) atof(numstr+40);
+     207             :   }
+     208      105240 : }
+     209             : 
+     210             : 
+     211             : /* remove leading and trailing spaces from PDB fields */
+     212           0 : static void adjust_pdb_field_string(char *field) {
+     213             :   int i, len;
+     214             : 
+     215           0 :   len = strlen(field);
+     216           0 :   while (len > 0 && field[len-1] == ' ') {
+     217           0 :     field[len-1] = '\0';
+     218           0 :     len--;
+     219             :   }
+     220             : 
+     221           0 :   while (len > 0 && field[0] == ' ') {
+     222           0 :     for (i=0; i < len; i++)
+     223           0 :       field[i] = field[i+1];
+     224           0 :     len--;
+     225             :   }
+     226           0 : }
+     227             : 
+     228           0 : static void get_pdb_header(const char *record, char *pdbcode, char *date,
+     229             :                            char *classification) {
+     230           0 :   if (date != NULL) {
+     231           0 :     strncpy(date, record + 50, 9);
+     232           0 :     date[9] = '\0';
+     233             :   }
+     234             : 
+     235           0 :   if (classification != NULL) {
+     236           0 :     strncpy(classification, record + 10, 40);
+     237           0 :     classification[40] = '\0';
+     238             :   }
+     239             : 
+     240           0 :   if (pdbcode != NULL) {
+     241           0 :     strncpy(pdbcode, record + 62, 4);
+     242           0 :     pdbcode[4] = '\0';
+     243           0 :     adjust_pdb_field_string(pdbcode); /* remove spaces from accession code */
+     244             :   }
+     245           0 : }
+     246             : 
+     247             : 
+     248           0 : static void get_pdb_conect(const char *record, int natoms, int *idxmap,
+     249             :                            int *maxbnum, int *nbonds, int **from, int **to) {
+     250             :   int bondto[11], numbonds, i;
+     251             : 
+     252           0 :   int reclen = strlen(record);
+     253           0 :   for (numbonds=0, i=0; i<11; i++) {
+     254             :     char bondstr[6];
+     255             :     const int fieldwidth = 5;
+     256           0 :     int start = 6 + i*fieldwidth;
+     257           0 :     int end = start + fieldwidth;
+     258             : 
+     259           0 :     if (end >= reclen)
+     260             :       break;
+     261             : 
+     262           0 :     memcpy(bondstr, record + start, fieldwidth);
+     263           0 :     bondstr[5] = '\0';
+     264           0 :     if (sscanf(bondstr, "%d", &bondto[numbonds]) < 0)
+     265             :       break;
+     266           0 :     numbonds++; 
+     267             :   }
+     268             : 
+     269           0 :   for (i=0; i<numbonds; i++) {
+     270             :     /* only add one bond per pair, PDBs list them redundantly */ 
+     271           0 :     if (bondto[i] > bondto[0]) {
+     272           0 :       int newnbonds = *nbonds + 1; /* add a new bond */
+     273             : 
+     274             :       /* allocate more bondlist space if necessary */
+     275           0 :       if (newnbonds >= *maxbnum) {
+     276             :         int newmax;
+     277             :         int *newfromlist, *newtolist;
+     278           0 :         newmax = (newnbonds + 11) * 1.25;
+     279             : 
+     280           0 :         newfromlist = (int *) realloc(*from, newmax * sizeof(int));
+     281           0 :         newtolist = (int *) realloc(*to, newmax * sizeof(int));
+     282             : 
+     283           0 :         if (newfromlist != NULL || newtolist != NULL) {
+     284           0 :           *maxbnum = newmax;
+     285           0 :           *from = newfromlist;
+     286           0 :           *to = newtolist;
+     287             :         } else {
+     288             :           printf("readpdb) failed to allocate memory for bondlists\n");
+     289           0 :           return; /* abort */
+     290             :         }
+     291             :       }
+     292             : 
+     293           0 :       *nbonds = newnbonds;
+     294           0 :       (*from)[newnbonds-1] = idxmap[bondto[0]] + 1;
+     295           0 :       (*to)[newnbonds-1] = idxmap[bondto[i]] + 1;
+     296             :     }
+     297             :   }
+     298             : }
+     299             : 
+     300             : /* ATOM field format according to PDB standard v2.2
+     301             :   COLUMNS        DATA TYPE       FIELD         DEFINITION
+     302             : ---------------------------------------------------------------------------------
+     303             :  1 -  6        Record name     "ATOM  "
+     304             :  7 - 11        Integer         serial        Atom serial number.
+     305             : 13 - 16        Atom            name          Atom name.
+     306             : 17             Character       altLoc        Alternate location indicator.
+     307             : 18 - 20        Residue name    resName       Residue name.
+     308             : 22             Character       chainID       Chain identifier.
+     309             : 23 - 26        Integer         resSeq        Residue sequence number.
+     310             : 27             AChar           iCode         Code for insertion of residues.
+     311             : 31 - 38        Real(8.3)       x             Orthogonal coordinates for X in Angstroms.
+     312             : 39 - 46        Real(8.3)       y             Orthogonal coordinates for Y in Angstroms.
+     313             : 47 - 54        Real(8.3)       z             Orthogonal coordinates for Z in Angstroms.
+     314             : 55 - 60        Real(6.2)       occupancy     Occupancy.
+     315             : 61 - 66        Real(6.2)       tempFactor    Temperature factor.
+     316             : 73 - 76        LString(4)      segID         Segment identifier, left-justified.
+     317             : 77 - 78        LString(2)      element       Element symbol, right-justified.
+     318             : 79 - 80        LString(2)      charge        Charge on the atom.
+     319             :  */
+     320             : 
+     321             : /* Break a pdb ATOM record into its fields.  The user must provide the
+     322             :    necessary space to store the atom name, residue name, and segment name.
+     323             :    Character strings will be null-terminated.
+     324             : */
+     325           0 : static void get_pdb_fields(const char *record, int reclength, int *serial,
+     326             :                            char *name, char *resname, char *chain, 
+     327             :                            char *segname, char *resid, char *insertion, 
+     328             :                            char *altloc, char *elementsymbol,
+     329             :                            float *x, float *y, float *z, 
+     330             :                            float *occup, float *beta) {
+     331             :   char serialbuf[6];
+     332             : 
+     333             :   /* get atom serial number */
+     334           0 :   strncpy(serialbuf, record + 6, 5);
+     335           0 :   serialbuf[5] = '\0';
+     336           0 :   *serial = 0;
+     337           0 :   sscanf(serialbuf, "%5d", serial);
+     338             :   
+     339             :   /* get atom name */
+     340           0 :   strncpy(name, record + 12, 4);
+     341           0 :   name[4] = '\0';
+     342           0 :   adjust_pdb_field_string(name); /* remove spaces from the name */
+     343             : 
+     344             :   /* get alternate location identifier */
+     345           0 :   strncpy(altloc, record + 16, 1);
+     346           0 :   altloc[1] = '\0';
+     347             : 
+     348             :   /* get residue name */
+     349           0 :   strncpy(resname, record + 17, 4);
+     350           0 :   resname[4] = '\0';
+     351           0 :   adjust_pdb_field_string(resname); /* remove spaces from the resname */
+     352             : 
+     353             :   /* get chain name */
+     354           0 :   chain[0] = record[21];
+     355           0 :   chain[1] = '\0';
+     356             : 
+     357             :   /* get residue id number */
+     358           0 :   strncpy(resid, record + 22, 4);
+     359           0 :   resid[4] = '\0';
+     360           0 :   adjust_pdb_field_string(resid); /* remove spaces from the resid */
+     361             : 
+     362             :   /* get the insertion code */
+     363           0 :   insertion[0] = record[26];
+     364           0 :   insertion[1] = '\0';
+     365             : 
+     366             :   /* get x, y, and z coordinates */
+     367           0 :   get_pdb_coordinates(record, x, y, z, occup, beta);
+     368             : 
+     369             :   /* get segment name */
+     370           0 :   if (reclength >= 73) {
+     371           0 :     strncpy(segname, record + 72, 4);
+     372           0 :     segname[4] = '\0';
+     373           0 :     adjust_pdb_field_string(segname); /* remove spaces from the segname */
+     374             :   } else {
+     375           0 :     segname[0] = '\0';
+     376             :   }
+     377             : 
+     378             :   /* get the atomic element symbol */
+     379           0 :   if (reclength >= 77) {
+     380           0 :     strncpy(elementsymbol, record + 76, 2);
+     381           0 :     elementsymbol[2] = '\0';
+     382             :   } else {
+     383           0 :     elementsymbol[0] = '\0';
+     384             :   }
+     385           0 : }  
+     386             : 
+     387             : 
+     388             : /* Write PDB data to given file descriptor; return success. */
+     389           0 : static int write_raw_pdb_record(FILE *fd, const char *recordname,
+     390             :     int index,const char *atomname, const char *resname,int resid, 
+     391             :     const char *insertion, const char *altloc, const char *elementsymbol,
+     392             :     float x, float y, float z, float occ, float beta, 
+     393             :     const char *chain, const char *segname) {
+     394             :   int rc;
+     395             :   char indexbuf[32];
+     396             :   char residbuf[32];
+     397             :   char segnamebuf[5];
+     398             :   char resnamebuf[5];
+     399             :   char altlocchar;
+     400             : 
+     401             :   /* XXX                                                          */
+     402             :   /* if the atom or residue indices exceed the legal PDB spec, we */
+     403             :   /* start emitting asterisks or hexadecimal strings rather than  */
+     404             :   /* aborting.  This is not really legal, but is an accepted hack */
+     405             :   /* among various other programs that deal with large PDB files  */
+     406             :   /* If we run out of hexadecimal indices, then we just print     */
+     407             :   /* asterisks.                                                   */
+     408           0 :   if (index < 100000) {
+     409             :     snprintf(indexbuf, 32, "%5d", index);
+     410           0 :   } else if (index < 1048576) {
+     411             :     snprintf(indexbuf, 32, "%05x", index);
+     412             :   } else {
+     413             :     snprintf(indexbuf, 32, "*****");
+     414             :   }
+     415             : 
+     416           0 :   if (resid < 10000) {
+     417             :     snprintf(residbuf, 32, "%4d", resid);
+     418           0 :   } else if (resid < 65536) {
+     419             :     snprintf(residbuf, 32, "%04x", resid);
+     420             :   } else { 
+     421             :     snprintf(residbuf, 32, "****");
+     422             :   }
+     423             : 
+     424           0 :   altlocchar = altloc[0];
+     425           0 :   if (altlocchar == '\0') {
+     426             :     altlocchar = ' ';
+     427             :   }
+     428             : 
+     429             :   /* make sure the segname or resname do not overflow the format */ 
+     430             :   strncpy(segnamebuf,segname,4);
+     431           0 :   segnamebuf[4] = '\0';
+     432             :   strncpy(resnamebuf,resname,4);
+     433           0 :   resnamebuf[4] = '\0';
+     434             : 
+     435             :  
+     436           0 :   rc = fprintf(fd,
+     437             :          "%-6s%5s %4s%c%-4s%c%4s%c   %8.3f%8.3f%8.3f%6.2f%6.2f      %-4s%2s\n",
+     438           0 :          recordname, indexbuf, atomname, altlocchar, resnamebuf, chain[0], 
+     439           0 :          residbuf, insertion[0], x, y, z, occ, beta, segnamebuf, elementsymbol);
+     440             : 
+     441           0 :   return (rc > 0);
+     442             : }
+     443             : 
+     444             : }
+     445             : }
+     446             : #endif
+     447             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/ruby.png b/coverage-libs/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage-libs/snow.png b/coverage-libs/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage-libs/updown.png b/coverage-libs/updown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa56a238b3e6c435265250f9266cd1b8caba0f20 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}Qd8;}%R+`Ae`*?77*hG?8mPH5^{)z4*}Q$iB}huR`+ literal 0 HcmV?d00001 diff --git a/coverage-libs/xdrfile/index-sort-f.html b/coverage-libs/xdrfile/index-sort-f.html new file mode 100644 index 0000000000..5400dde46c --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + 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-05-27 13:05:16Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/index-sort-l.html b/coverage-libs/xdrfile/index-sort-l.html new file mode 100644 index 0000000000..e3902ec406 --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + 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-05-27 13:05:16Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/index.html b/coverage-libs/xdrfile/index.html new file mode 100644 index 0000000000..f7c5d707fe --- /dev/null +++ b/coverage-libs/xdrfile/index.html @@ -0,0 +1,113 @@ + + + + + + + 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-05-27 13:05:16Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html b/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html new file mode 100644 index 0000000000..b896737b08 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html @@ -0,0 +1,396 @@ + + + + + + + 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-05-27 13:05:16Functions:318138.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile10xdrrshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrruchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile10xdrwshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrwuchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile11xdrrdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrropaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrrsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrrstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrrushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile11xdrwdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrwopaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrwsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrwstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrwushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile17xdrfile_read_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_read_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile29xdrfile_compress_coord_doubleEPdidPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile31xdrfile_decompress_coord_doubleEPdPiS1_PNS0_7XDRFILEE0
_ZN4PLMD7xdrfile6xddcd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrdcs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile8xdropen_EPiPcS2_ii0
_ZN4PLMD7xdrfile8xdrrint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile8xdrwint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile9xdrclose_EPi0
_ZN4PLMD7xdrfile9xdrrchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrruint_EPiPjS1_S1_0
_ZN4PLMD7xdrfile9xdrwchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrwuint_EPiPjS1_S1_0
_ZN4PLMD7xdrfileL10xdr_doubleEPNS0_3XDREPd0
_ZN4PLMD7xdrfileL10xdr_u_charEPNS0_3XDREPh0
_ZN4PLMD7xdrfileL11xdr_u_shortEPNS0_3XDREPt0
_ZN4PLMD7xdrfileL15xdrstdio_getposEPNS0_3XDRE0
_ZN4PLMD7xdrfileL15xdrstdio_setposEPNS0_3XDREj0
_ZN4PLMD7xdrfileL7ctofstrEPciS1_0
_ZN4PLMD7xdrfileL7ftocstrEPciS1_i0
_ZN4PLMD7xdrfileL8xdr_charEPNS0_3XDREPc0
_ZN4PLMD7xdrfileL9sizeofintEi0
_ZN4PLMD7xdrfileL9xdr_shortEPNS0_3XDREPs0
_ZN4PLMD7xdrfile12xdrfile_openEPKcS2_20
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE20
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE20
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE20
_ZN4PLMD7xdrfile19xdrfile_read_opaqueEPciPNS0_7XDRFILEE28
_ZN4PLMD7xdrfile30xdrfile_decompress_coord_floatEPfPiS1_PNS0_7XDRFILEE28
_ZN4PLMD7xdrfile19xdrfile_read_stringEPciPNS0_7XDRFILEE39
_ZN4PLMD7xdrfile20xdrfile_write_stringEPcPNS0_7XDRFILEE48
_ZN4PLMD7xdrfile20xdrfile_write_opaqueEPciPNS0_7XDRFILEE60
_ZN4PLMD7xdrfile28xdrfile_compress_coord_floatEPfifPNS0_7XDRFILEE72
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj87
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj87
_ZN4PLMD7xdrfileL10sizeofintsEiPj88
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj89
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfile19xdrfile_write_floatEPfiPNS0_7XDRFILEE174
_ZN4PLMD7xdrfileL10xdr_opaqueEPNS0_3XDREPcj175
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE470
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1448
_ZN4PLMD7xdrfileL10decodeintsEPiiiPjS1_1936
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2420
_ZN4PLMD7xdrfileL10encodeintsEPiiiPjS2_3960
_ZN4PLMD7xdrfileL9xdr_ntohlEi4054
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi4059
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf11524
_ZN4PLMD7xdrfileL13xdr_swapbytesEi14026
_ZN4PLMD7xdrfileL10decodebitsEPii14579
_ZN4PLMD7xdrfileL10encodebitsEPiii21991
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.func.html b/coverage-libs/xdrfile/xdrfile.cpp.func.html new file mode 100644 index 0000000000..8e4d848fb0 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func.html @@ -0,0 +1,396 @@ + + + + + + + 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-05-27 13:05:16Functions:318138.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile10xdrrshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrruchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile10xdrwshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrwuchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile11xdrrdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrropaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrrsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrrstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrrushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile11xdrwdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrwopaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrwsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrwstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrwushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile12xdrfile_openEPKcS2_20
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE20
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1448
_ZN4PLMD7xdrfile17xdrfile_read_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_read_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE470
_ZN4PLMD7xdrfile18xdrfile_read_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_opaqueEPciPNS0_7XDRFILEE28
_ZN4PLMD7xdrfile19xdrfile_read_stringEPciPNS0_7XDRFILEE39
_ZN4PLMD7xdrfile19xdrfile_read_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_floatEPfiPNS0_7XDRFILEE174
_ZN4PLMD7xdrfile19xdrfile_write_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_opaqueEPciPNS0_7XDRFILEE60
_ZN4PLMD7xdrfile20xdrfile_write_stringEPcPNS0_7XDRFILEE48
_ZN4PLMD7xdrfile20xdrfile_write_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile28xdrfile_compress_coord_floatEPfifPNS0_7XDRFILEE72
_ZN4PLMD7xdrfile29xdrfile_compress_coord_doubleEPdidPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile30xdrfile_decompress_coord_floatEPfPiS1_PNS0_7XDRFILEE28
_ZN4PLMD7xdrfile31xdrfile_decompress_coord_doubleEPdPiS1_PNS0_7XDRFILEE0
_ZN4PLMD7xdrfile6xddcd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrdcs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile8xdropen_EPiPcS2_ii0
_ZN4PLMD7xdrfile8xdrrint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile8xdrwint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile9xdrclose_EPi0
_ZN4PLMD7xdrfile9xdrrchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrruint_EPiPjS1_S1_0
_ZN4PLMD7xdrfile9xdrwchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrwuint_EPiPjS1_S1_0
_ZN4PLMD7xdrfileL10decodebitsEPii14579
_ZN4PLMD7xdrfileL10decodeintsEPiiiPjS1_1936
_ZN4PLMD7xdrfileL10encodebitsEPiii21991
_ZN4PLMD7xdrfileL10encodeintsEPiiiPjS2_3960
_ZN4PLMD7xdrfileL10sizeofintsEiPj88
_ZN4PLMD7xdrfileL10xdr_doubleEPNS0_3XDREPd0
_ZN4PLMD7xdrfileL10xdr_opaqueEPNS0_3XDREPcj175
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj87
_ZN4PLMD7xdrfileL10xdr_u_charEPNS0_3XDREPh0
_ZN4PLMD7xdrfileL11xdr_u_shortEPNS0_3XDREPt0
_ZN4PLMD7xdrfileL13xdr_swapbytesEi14026
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE20
_ZN4PLMD7xdrfileL15xdrstdio_getposEPNS0_3XDRE0
_ZN4PLMD7xdrfileL15xdrstdio_setposEPNS0_3XDREj0
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE20
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi4059
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj89
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfileL7ctofstrEPciS1_0
_ZN4PLMD7xdrfileL7ftocstrEPciS1_i0
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2420
_ZN4PLMD7xdrfileL8xdr_charEPNS0_3XDREPc0
_ZN4PLMD7xdrfileL9sizeofintEi0
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf11524
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL9xdr_ntohlEi4054
_ZN4PLMD7xdrfileL9xdr_shortEPNS0_3XDREPs0
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj87
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html new file mode 100644 index 0000000000..9d91b2a76d --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html @@ -0,0 +1,2724 @@ + + + + + + + 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-05-27 13:05:16Functions:318138.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi3
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_39
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_84
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi87
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_87
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE90
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html b/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html new file mode 100644 index 0000000000..79bfa07084 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:16Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi3
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_39
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi87
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE90
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_87
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_84
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html new file mode 100644 index 0000000000..02a2297576 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html @@ -0,0 +1,605 @@ + + + + + + + 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-05-27 13:05:16Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_xtc_natomsEPcPi2
_ZN4PLMD7xdrfile8read_xtcEPNS0_7XDRFILEEiPiPfPA3_fS6_S4_30
_ZN4PLMD7xdrfile9write_xtcEPNS0_7XDRFILEEiifPA3_fS4_f72
_ZN4PLMD7xdrfileL9xtc_coordEPNS0_7XDRFILEEPiPA3_fS5_Pfi100
_ZN4PLMD7xdrfileL10xtc_headerEPNS0_7XDRFILEEPiS3_Pfi104
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html new file mode 100644 index 0000000000..f8895d0ce4 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:16Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_xtc_natomsEPcPi2
_ZN4PLMD7xdrfile8read_xtcEPNS0_7XDRFILEEiPiPfPA3_fS6_S4_30
_ZN4PLMD7xdrfile9write_xtcEPNS0_7XDRFILEEiifPA3_fS4_f72
_ZN4PLMD7xdrfileL10xtc_headerEPNS0_7XDRFILEEPiS3_Pfi104
_ZN4PLMD7xdrfileL9xtc_coordEPNS0_7XDRFILEEPiPA3_fS5_Pfi100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html new file mode 100644 index 0000000000..53a3208e85 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + 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-05-27 13:05:16Functions:55100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrixC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getBaseMultiColvarERKj7
_ZN4PLMD6adjmat21ActionWithInputMatrixC2ERKNS_13ActionOptionsE27
_ZNK4PLMD6adjmat21ActionWithInputMatrix23getNumberOfAtomsInGroupERKj34
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE37
_ZNK4PLMD6adjmat21ActionWithInputMatrix20getNumberOfNodeTypesEv66
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getAbsoluteIndexOfCentralAtomERKj504
_ZNK4PLMD6adjmat21ActionWithInputMatrix24addConnectionDerivativesERKjS3_RNS_10MultiValueES5_1440
_ZNK4PLMD6adjmat21ActionWithInputMatrix19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE1679
_ZNK4PLMD6adjmat21ActionWithInputMatrix12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE2004
_ZNK4PLMD6adjmat21ActionWithInputMatrix21getNumberOfQuantitiesEv2181
_ZN4PLMD6adjmat21ActionWithInputMatrix22getNumberOfDerivativesEv13250
_ZNK4PLMD6adjmat21ActionWithInputMatrix23retrieveConnectionValueERKjS3_RSt6vectorIdSaIdEE46452
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getPositionOfAtomForLinkCellsERKj54763
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getAdjacencyVesselEv78058
_ZNK4PLMD6adjmat21ActionWithInputMatrix16getNumberOfNodesEv16261547
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.func.html b/coverage/adjmat/ActionWithInputMatrix.cpp.func.html new file mode 100644 index 0000000000..84a476d0c2 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD6adjmat21ActionWithInputMatrix22getNumberOfDerivativesEv13250
_ZN4PLMD6adjmat21ActionWithInputMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat21ActionWithInputMatrixC2ERKNS_13ActionOptionsE27
_ZNK4PLMD6adjmat21ActionWithInputMatrix12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE2004
_ZNK4PLMD6adjmat21ActionWithInputMatrix16getNumberOfNodesEv16261547
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getAdjacencyVesselEv78058
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getBaseMultiColvarERKj7
_ZNK4PLMD6adjmat21ActionWithInputMatrix19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE1679
_ZNK4PLMD6adjmat21ActionWithInputMatrix20getNumberOfNodeTypesEv66
_ZNK4PLMD6adjmat21ActionWithInputMatrix21getNumberOfQuantitiesEv2181
_ZNK4PLMD6adjmat21ActionWithInputMatrix23getNumberOfAtomsInGroupERKj34
_ZNK4PLMD6adjmat21ActionWithInputMatrix23retrieveConnectionValueERKjS3_RSt6vectorIdSaIdEE46452
_ZNK4PLMD6adjmat21ActionWithInputMatrix24addConnectionDerivativesERKjS3_RNS_10MultiValueES5_1440
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getAbsoluteIndexOfCentralAtomERKj504
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getPositionOfAtomForLinkCellsERKj54763
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html b/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html new file mode 100644 index 0000000000..f78f7d4f76 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + 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-05-27 13:05: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          37 : void ActionWithInputMatrix::registerKeywords( Keywords& keys ) {
+      33          37 :   MultiColvarBase::registerKeywords( keys );
+      34          74 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      35          37 : }
+      36             : 
+      37             : 
+      38          27 : ActionWithInputMatrix::ActionWithInputMatrix(const ActionOptions& ao):
+      39             :   Action(ao),
+      40             :   MultiColvarBase(ao),
+      41          27 :   mymatrix(NULL)
+      42             : {
+      43          27 :   matsums=true;
+      44          54 :   if( keywords.exists("MATRIX") ) {
+      45             :     std::vector<AtomNumber> fake_atoms;
+      46          50 :     if( !parseMultiColvarAtomList("MATRIX",-1,fake_atoms ) ) error("unable to interpret input matrix");
+      47          25 :     if( mybasemulticolvars.size()!=1 ) error("should be exactly one matrix input");
+      48             : 
+      49             :     // Retrieve the adjacency matrix of interest
+      50          25 :     for(unsigned i=0; i<mybasemulticolvars[0]->getNumberOfVessels(); ++i) {
+      51          25 :       mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mybasemulticolvars[0]->getPntrToVessel(i) );
+      52          25 :       if( mymatrix ) break ;
+      53             :     }
+      54          25 :     if( !mymatrix ) error( mybasemulticolvars[0]->getLabel() + " does not calculate an adjacency matrix");
+      55             : 
+      56          25 :     atom_lab.resize(0); unsigned nnodes; // Delete all the atom labels that have been created
+      57          25 :     if( mymatrix->undirectedGraph() ) nnodes = (mymatrix->function)->ablocks[0].size();
+      58           2 :     else nnodes = (mymatrix->function)->ablocks[0].size() + (mymatrix->function)->ablocks[1].size();
+      59        6816 :     for(unsigned i=0; i<nnodes; ++i) atom_lab.push_back( std::pair<unsigned,unsigned>( 1, i ) );
+      60             :   }
+      61          27 : }
+      62             : 
+      63       13250 : unsigned ActionWithInputMatrix::getNumberOfDerivatives() {
+      64       13250 :   return (mymatrix->function)->getNumberOfDerivatives();
+      65             : }
+      66             : 
+      67    16261547 : unsigned ActionWithInputMatrix::getNumberOfNodes() const {
+      68    16261547 :   return (mymatrix->function)->ablocks[0].size();
+      69             : }
+      70             : 
+      71       78058 : AdjacencyMatrixVessel* ActionWithInputMatrix::getAdjacencyVessel() const {
+      72       78058 :   return mymatrix;
+      73             : }
+      74             : 
+      75         504 : AtomNumber ActionWithInputMatrix::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+      76         504 :   return (mymatrix->function)->getAbsoluteIndexOfCentralAtom(i);
+      77             : }
+      78             : 
+      79       46452 : double ActionWithInputMatrix::retrieveConnectionValue( const unsigned& i, const unsigned& j, std::vector<double>& vals ) const {
+      80       46452 :   if( !mymatrix->matrixElementIsActive( i, j ) ) return 0;
+      81       25360 :   unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
+      82             : 
+      83             :   // unsigned vi; double df;
+      84       25360 :   mymatrix->retrieveValueWithIndex( myelem, false, vals );
+      85       25360 :   return vals[0]*vals[1];       // (mymatrix->function)->transformStoredValues( vals, vi, df );
+      86             : }
+      87             : 
+      88        2004 : void ActionWithInputMatrix::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
+      89        2004 :   if( (mymatrix->function)->mybasemulticolvars.size()==0  ) {
+      90         305 :     std::vector<double> tvals( mymatrix->getNumberOfComponents() ); orient0.assign(orient0.size(),0);
+      91       38263 :     for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
+      92       37958 :       if( mymatrix->undirectedGraph() && ind==i ) continue;
+      93       37678 :       orient0[1]+=retrieveConnectionValue( ind, i, tvals );
+      94             :     }
+      95         305 :     orient0[0]=1.0; return;
+      96             :   }
+      97        1699 :   (mymatrix->function)->getInputData( ind, normed, myatoms, orient0 );
+      98             : }
+      99             : 
+     100        1440 : void ActionWithInputMatrix::addConnectionDerivatives( const unsigned& i, const unsigned& j, MultiValue& myvals, MultiValue& myvout ) const {
+     101        1440 :   if( !mymatrix->matrixElementIsActive( i, j ) ) return;
+     102        1440 :   unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
+     103             :   // Get derivatives and add
+     104        1440 :   mymatrix->retrieveDerivatives( myelem, false, myvals );
+     105       31086 :   for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
+     106       29646 :     unsigned ider=myvals.getActiveIndex(jd);
+     107       29646 :     myvout.addDerivative( 1, ider, myvals.getDerivative( 1, ider ) );
+     108             :   }
+     109             : }
+     110             : 
+     111        1679 : MultiValue& ActionWithInputMatrix::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
+     112        1679 :   if( (mymatrix->function)->mybasemulticolvars.size()==0  ) {
+     113          90 :     MultiValue& myder=mymatrix->getTemporyMultiValue(0);
+     114          90 :     if( myder.getNumberOfValues()!=2 || myder.getNumberOfDerivatives()!=(mymatrix->function)->getNumberOfDerivatives() ) {
+     115           3 :       myder.resize( 2, (mymatrix->function)->getNumberOfDerivatives() );
+     116             :     }
+     117          90 :     myder.clearAll();
+     118          90 :     MultiValue myvals( (mymatrix->function)->getNumberOfQuantities(), (mymatrix->function)->getNumberOfDerivatives() );
+     119         885 :     for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
+     120         795 :       if( mymatrix->undirectedGraph() && ind==i ) continue;
+     121         730 :       addConnectionDerivatives( ind, i, myvals, myder );
+     122             :     }
+     123             :     myder.updateDynamicList(); return myder;
+     124          90 :   }
+     125        1589 :   return (mymatrix->function)->getInputDerivatives( ind, normed, myatoms );
+     126             : }
+     127             : 
+     128          66 : unsigned ActionWithInputMatrix::getNumberOfNodeTypes() const {
+     129          66 :   unsigned size = (mymatrix->function)->mybasemulticolvars.size();
+     130             :   if( size==0 ) return 1;
+     131             :   return size;
+     132             : }
+     133             : 
+     134        2181 : unsigned ActionWithInputMatrix::getNumberOfQuantities() const {
+     135        2181 :   if( (mymatrix->function)->mybasemulticolvars.size()==0 ) return 2;
+     136        2082 :   return (mymatrix->function)->mybasemulticolvars[0]->getNumberOfQuantities();
+     137             : }
+     138             : 
+     139          34 : unsigned ActionWithInputMatrix::getNumberOfAtomsInGroup( const unsigned& igrp ) const {
+     140             :   plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
+     141          34 :   return (mymatrix->function)->mybasemulticolvars[igrp]->getFullNumberOfTasks();
+     142             : }
+     143             : 
+     144           7 : multicolvar::MultiColvarBase* ActionWithInputMatrix::getBaseMultiColvar( const unsigned& igrp ) const {
+     145             :   plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
+     146           7 :   return (mymatrix->function)->mybasemulticolvars[igrp];
+     147             : }
+     148             : 
+     149       54763 : Vector ActionWithInputMatrix::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     150       54763 :   return (getAdjacencyVessel()->function)->getPositionOfAtomForLinkCells( iatom );
+     151             : }
+     152             : 
+     153             : }
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html b/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html new file mode 100644 index 0000000000..32bc7dddbf --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.func.html b/coverage/adjmat/ActionWithInputMatrix.h.func.html new file mode 100644 index 0000000000..7eb37aedd3 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.gcov.html b/coverage/adjmat/ActionWithInputMatrix.h.gcov.html new file mode 100644 index 0000000000..ab14d64afd --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..0f4a4d716a --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE35
_ZN4PLMD6adjmat19AdjacencyMatrixBase27parseConnectionDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbRKj46
_ZNK4PLMD6adjmat19AdjacencyMatrixBase20getNumberOfNodeTypesEv132
_ZNK4PLMD6adjmat19AdjacencyMatrixBase21getSizeOfInputVectorsEv5807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html new file mode 100644 index 0000000000..2199984c03 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6adjmat19AdjacencyMatrixBase17finishMatrixSetupERKbRKSt6vectorINS_10AtomNumberESaIS5_EE23
_ZN4PLMD6adjmat19AdjacencyMatrixBase23readMaxTwoSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKb13
_ZN4PLMD6adjmat19AdjacencyMatrixBase24recalculateMatrixElementERKjRNS_10MultiValueE0
_ZN4PLMD6adjmat19AdjacencyMatrixBase25readMaxThreeSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKb10
_ZN4PLMD6adjmat19AdjacencyMatrixBase27parseConnectionDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbRKj46
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE23
_ZNK4PLMD6adjmat19AdjacencyMatrixBase20getNumberOfNodeTypesEv132
_ZNK4PLMD6adjmat19AdjacencyMatrixBase21getSizeOfInputVectorsEv5807
_ZNK4PLMD6adjmat19AdjacencyMatrixBase22retrieveTypeDimensionsERjS2_S2_24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html new file mode 100644 index 0000000000..c7c1a0ca49 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + 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-05-27 13:05: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          35 : void AdjacencyMatrixBase::registerKeywords( Keywords& keys ) {
+      33          35 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      34          70 :   keys.remove("LOWMEM"); keys.use("HIGHMEM");
+      35          35 : }
+      36             : 
+      37          23 : AdjacencyMatrixBase::AdjacencyMatrixBase(const ActionOptions& ao):
+      38             :   Action(ao),
+      39             :   MultiColvarBase(ao),
+      40          23 :   connect_id(0),
+      41          23 :   no_third_dim_accum(true),
+      42          23 :   mat(NULL)
+      43             : {
+      44          46 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      45          23 : }
+      46             : 
+      47          46 : void AdjacencyMatrixBase::parseConnectionDescriptions( const std::string& key, const bool& multiple, const unsigned& nrow_t ) {
+      48          46 :   if( getNumberOfNodeTypes()==1 || (getNumberOfNodeTypes()==2 && nrow_t==1) ) {
+      49             :     std::vector<std::string> sw;
+      50          45 :     if( !multiple ) {
+      51          44 :       sw.resize(1); parse(key,sw[0]);
+      52          44 :       if(sw[0].length()==0) error("could not find " + key + " keyword");
+      53             :     } else {
+      54             :       std::string input;
+      55           2 :       for(int i=1;; i++) {
+      56           3 :         if( !parseNumbered(key, i, input ) ) break;
+      57           2 :         sw.push_back( input );
+      58             :       }
+      59             :     }
+      60          45 :     setupConnector( connect_id, 0, 0, sw );
+      61          45 :   } else {
+      62           1 :     if( multiple ) error("keyword " + key + " does not work with multiple input strings");
+      63             :     unsigned nr, nc;
+      64           1 :     if( nrow_t==0 ) {
+      65           1 :       nr=nc=getNumberOfNodeTypes();
+      66             :     } else {
+      67           0 :       nr=nrow_t; nc = getNumberOfNodeTypes() - nr;
+      68             :     }
+      69           3 :     for(unsigned i=0; i<nr; ++i) {
+      70             :       // Retrieve the base number
+      71             :       unsigned ibase;
+      72           2 :       if( nc<10 ) {
+      73           2 :         ibase=(i+1)*10;
+      74           0 :       } else if ( nc<100 ) {
+      75           0 :         ibase=(i+1)*100;
+      76             :       } else {
+      77           0 :         error("wow this is an error I never would have expected");
+      78             :       }
+      79             : 
+      80           5 :       for(unsigned j=i; j<nc; ++j) {
+      81           3 :         std::vector<std::string> sw(1); parseNumbered(key,ibase+j+1,sw[0]);
+      82           3 :         if(sw[0].length()==0) {
+      83           0 :           std::string num; Tools::convert(ibase+j+1,num);
+      84           0 :           error("could not find " + key + num + " keyword. Need one " + key + " keyword for each distinct base-multicolvar-pair type");
+      85             :         }
+      86           3 :         setupConnector( connect_id, i, j, sw );
+      87           3 :       }
+      88             :     }
+      89             :   }
+      90          46 :   connect_id++;
+      91          46 : }
+      92             : 
+      93        5807 : unsigned AdjacencyMatrixBase::getSizeOfInputVectors() const {
+      94        5807 :   if( mybasemulticolvars.size()==0 ) return 2;
+      95             : 
+      96        5807 :   unsigned nq = mybasemulticolvars[0]->getNumberOfQuantities();
+      97        5807 :   for(unsigned i=1; i<mybasemulticolvars.size(); ++i) {
+      98           0 :     if( mybasemulticolvars[i]->getNumberOfQuantities()!=nq ) error("mismatch between vectors in base colvars");
+      99             :   }
+     100             :   return nq;
+     101             : }
+     102             : 
+     103         132 : unsigned AdjacencyMatrixBase::getNumberOfNodeTypes() const {
+     104         132 :   unsigned size=mybasemulticolvars.size();
+     105             :   if( size==0 ) return 1;
+     106             :   return size;
+     107             : }
+     108             : 
+     109          24 : void AdjacencyMatrixBase::retrieveTypeDimensions( unsigned& nrows, unsigned& ncols, unsigned& ntype ) const {
+     110          24 :   bool allsame=(ablocks[0].size()==ablocks[1].size());
+     111          24 :   if( allsame ) {
+     112        6952 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     113        6929 :       if( ablocks[0][i]!=ablocks[1][i] ) allsame=false;
+     114             :     }
+     115             :   }
+     116             : 
+     117          24 :   if( allsame ) {
+     118          23 :     std::vector<unsigned> types(1); types[0]=atom_lab[ablocks[0][0]].first;
+     119        6929 :     for(unsigned i=1; i<ablocks[0].size(); ++i) {
+     120             :       bool found = false;
+     121        6913 :       for(unsigned j=0; j<types.size(); ++j) {
+     122        6912 :         if( atom_lab[ablocks[0][i]].first==types[j] ) { found=true; break; }
+     123             :       }
+     124        6906 :       if( !found ) types.push_back( atom_lab[ablocks[0][i]].first );
+     125             :     }
+     126          23 :     ntype=0; nrows=ncols=types.size();
+     127             :   } else {
+     128           1 :     std::vector<unsigned> types(1); types[0]=atom_lab[ablocks[0][0]].first;
+     129           5 :     for(unsigned i=1; i<ablocks[0].size(); ++i) {
+     130             :       bool found = false;
+     131           4 :       for(unsigned j=0; j<types.size(); ++j) {
+     132           4 :         if( atom_lab[ablocks[0][i]].first==types[j] ) { found=true; break; }
+     133             :       }
+     134           4 :       if( !found ) types.push_back( atom_lab[ablocks[0][i]].first );
+     135             :     }
+     136           1 :     nrows=ntype=types.size();
+     137          11 :     for(unsigned i=0; i<ablocks[1].size(); ++i) {
+     138             :       bool found = false;
+     139          10 :       for(unsigned j=0; j<types.size(); ++j) {
+     140          10 :         if( atom_lab[ablocks[1][i]].first==types[j] ) { found=true; break; }
+     141             :       }
+     142          10 :       if( !found ) types.push_back( atom_lab[ablocks[1][i]].first );
+     143             :     }
+     144           1 :     if( types.size()==nrows ) { ntype=0; ncols=1; plumed_assert( types.size()==1 && atom_lab[ablocks[0][0]].first==0 ); }
+     145           0 :     else ncols = types.size() - ntype;
+     146             :   }
+     147          24 : }
+     148             : 
+     149          23 : void AdjacencyMatrixBase::finishMatrixSetup( const bool& symmetric, const std::vector<AtomNumber>& all_atoms ) {
+     150             :   std::string param;
+     151          23 :   if( symmetric && ablocks[0].size()==ablocks[1].size() ) param="SYMMETRIC";
+     152          23 :   if( !symmetric ) {
+     153           4 :     bool usehbonds=( ablocks[0].size()==ablocks[1].size() );
+     154           4 :     if( usehbonds ) {
+     155         138 :       for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     156         134 :         if( ablocks[0][i]!=ablocks[1][i] ) { usehbonds = false; break; }
+     157             :       }
+     158           4 :       if( usehbonds ) param="HBONDS";
+     159             :     }
+     160             :   }
+     161             : 
+     162          46 :   vesselbase::VesselOptions da("","",0,param,this);
+     163          23 :   Keywords keys; AdjacencyMatrixVessel::registerKeywords( keys );
+     164          23 :   vesselbase::VesselOptions da2(da,keys);
+     165          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.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html new file mode 100644 index 0000000000..77728e5324 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func.html b/coverage/adjmat/AdjacencyMatrixBase.h.func.html new file mode 100644 index 0000000000..7bfb3dfc6d --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html new file mode 100644 index 0000000000..4a8e6374d2 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html @@ -0,0 +1,181 @@ + + + + + + + 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-05-27 13:05: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"); }
+      78             : /// Get the atom number
+      79             :   AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const ;
+      80             : };
+      81             : 
+      82             : inline
+      83             : AdjacencyMatrixVessel* AdjacencyMatrixBase::getAdjacencyVessel() {
+      84             :   return mat;
+      85             : }
+      86             : 
+      87             : inline
+      88             : unsigned AdjacencyMatrixBase::getBaseColvarNumber( const unsigned& inum ) const {
+      89   224925223 :   if( atom_lab[inum].first>0 ) return atom_lab[inum].first-1;
+      90             :   return 0;
+      91             : }
+      92             : 
+      93             : inline
+      94         504 : AtomNumber AdjacencyMatrixBase::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      95         504 :   if( atom_lab[iatom].first>0 ) {
+      96         156 :     unsigned mmc=atom_lab[ iatom ].first - 1;
+      97         156 :     return mybasemulticolvars[mmc]->getAbsoluteIndexOfCentralAtom( atom_lab[iatom].second );
+      98             :   }
+      99         348 :   return ActionAtomistic::getAbsoluteIndex( atom_lab[iatom].second );
+     100             : }
+     101             : 
+     102             : }
+     103             : }
+     104             : 
+     105             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..5d0f5ef7f9 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html new file mode 100644 index 0000000000..0f204d146f --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html new file mode 100644 index 0000000000..c8a1878ede --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..4211545bc6 --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.func.html b/coverage/adjmat/AlignedMatrixBase.cpp.func.html new file mode 100644 index 0000000000..cd211c4600 --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17AlignedMatrixBase14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD6adjmat17AlignedMatrixBase16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat17AlignedMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17AlignedMatrixBaseC2ERKNS_13ActionOptionsE1
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html b/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html new file mode 100644 index 0000000000..1bd215bcfc --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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-05-27 13:05: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           5 : void AlignedMatrixBase::registerKeywords( Keywords& keys ) {
+      31           5 :   AdjacencyMatrixBase::registerKeywords( keys );
+      32          10 :   keys.add("atoms","ATOMS","The list of molecules for which you would like to calculate the contact matrix.  The molecules involved must "
+      33             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      34             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      35             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      36          10 :   keys.add("atoms-1","ATOMSA","The list of molecules that you would like to use for the rows of the contact matrix.  The molecules involved must "
+      37             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      38             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      39             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      40          10 :   keys.add("atoms-1","ATOMSB","The list of molecules that you would like to use for the columns of the contact matrix.  The molecules involved must "
+      41             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      42             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      43             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      44          10 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      45             :            "The following provides information on the \\ref switchingfunction that are available.");
+      46           5 : }
+      47             : 
+      48           1 : AlignedMatrixBase::AlignedMatrixBase( const ActionOptions& ao ):
+      49             :   Action(ao),
+      50           1 :   AdjacencyMatrixBase(ao)
+      51             : {
+      52             :   // Read in the atomic positions
+      53           2 :   readMaxTwoSpeciesMatrix( "ATOMS", "ATOMSA", "ATOMSB", true );
+      54           1 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ncol_t );
+      55           1 :   if( mybasemulticolvars.size()==0 ) error("cannot use atom indices as input to this variable / input was not specified");
+      56           1 :   if( getSizeOfInputVectors()<3 ) error("base multicolvars do not calculate an orientation");
+      57             :   // Read in the switching function
+      58           1 :   switchingFunction.resize( nrows, ncols );
+      59           2 :   parseConnectionDescriptions("SWITCH",false,ncol_t);
+      60             : 
+      61             :   // Find the largest sf cutoff
+      62           1 :   double sfmax=switchingFunction(0,0).get_dmax();
+      63           2 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+      64           2 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+      65           1 :       double tsf=switchingFunction(i,j).get_dmax();
+      66           1 :       if( tsf>sfmax ) sfmax=tsf;
+      67             :     }
+      68             :   }
+      69             :   // And set the link cell cutoff
+      70           1 :   setLinkCellCutoff( sfmax );
+      71           1 : }
+      72             : 
+      73           2 : void AlignedMatrixBase::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+      74           2 :   plumed_assert( id<2 );
+      75           2 :   if( id==0 ) {
+      76           1 :     plumed_assert( desc.size()==1 ); std::string errors; switchingFunction(j,i).set(desc[0],errors);
+      77           1 :     if( errors.length()!=0 ) error("problem reading switching function in SWITCH keywrd description " + errors);
+      78           1 :     if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+      79           2 :     log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+      80           1 :   } else if( id==1 ) {
+      81           1 :     readOrientationConnector( i, j, desc );
+      82             :   }
+      83           2 : }
+      84             : 
+      85       57063 : double AlignedMatrixBase::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+      86       57063 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+      87      171189 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t ).get_dmax2() ) return 1.0;
+      88             :   return 0.0;
+      89             : }
+      90             : 
+      91        5806 : double AlignedMatrixBase::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      92        5806 :   unsigned ncomp=getSizeOfInputVectors(); Vector ddistance;
+      93        5806 :   std::vector<double> orient0(ncomp), orient1(ncomp), dorient0(ncomp), dorient1(ncomp);
+      94        5806 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+      95        5806 :   getInputData( 0, true, myatoms, orient0 ); getInputData( 1, true, myatoms, orient1 );
+      96       17418 :   double f_dot = computeVectorFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t,
+      97             :                                         distance, orient0, orient1, ddistance, dorient0, dorient1 );
+      98             : 
+      99             :   // Retrieve the weight of the connection
+     100       11612 :   double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t ).calculate( distance.modulo(), dfunc );
+     101             : 
+     102        5806 :   if( !doNotCalculateDerivatives() ) {
+     103           0 :     addAtomDerivatives( 1, 0, (-dfunc)*f_dot*distance - sw*ddistance, myatoms );
+     104           0 :     addAtomDerivatives( 1, 1, (+dfunc)*f_dot*distance + sw*ddistance, myatoms );
+     105           0 :     myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) - sw*extProduct( distance, ddistance ) );
+     106             : 
+     107             :     // Add derivatives of orientation
+     108           0 :     for(unsigned k=2; k<orient0.size(); ++k) { dorient0[k]*=sw; dorient1[k]*=sw; }
+     109           0 :     mergeInputDerivatives( 1, 2, orient0.size(), 0, dorient0, getInputDerivatives( 0, true, myatoms ), myatoms );
+     110           0 :     mergeInputDerivatives( 1, 2, orient1.size(), 1, dorient1, getInputDerivatives( 1, true, myatoms ), myatoms );
+     111             :   }
+     112       11612 :   return sw*f_dot;
+     113             : }
+     114             : 
+     115             : }
+     116             : }
+     117             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html b/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..f35c9f234a --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE62
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.func.html b/coverage/adjmat/ClusterAnalysisBase.cpp.func.html new file mode 100644 index 0000000000..92fe07e697 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterAnalysisBase10isPeriodicEv11
_ZN4PLMD6adjmat19ClusterAnalysisBase16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD6adjmat19ClusterAnalysisBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat19ClusterAnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19ClusterAnalysisBaseC2ERKNS_13ActionOptionsE54
_ZNK4PLMD6adjmat19ClusterAnalysisBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat19ClusterAnalysisBase12nodeIsActiveERKj1
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getNumberOfClustersEv4
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase22getCutoffForConnectionEv0
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html b/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html new file mode 100644 index 0000000000..8c0219dbf4 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + 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-05-27 13:05: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          62 : void ClusterAnalysisBase::registerKeywords( Keywords& keys ) {
+      28          62 :   MultiColvarBase::registerKeywords( keys );
+      29         124 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      30          62 : }
+      31             : 
+      32          54 : ClusterAnalysisBase::ClusterAnalysisBase(const ActionOptions& ao):
+      33             :   Action(ao),
+      34             :   MultiColvarBase(ao),
+      35         108 :   myfvals(0,0),
+      36          54 :   myfatoms( myfvals, this ),
+      37          54 :   myclusters(NULL)
+      38             : {
+      39             :   // This makes these colvars behave appropriately with dump and analysis
+      40          54 :   matsums=usespecies=true; std::vector<AtomNumber> fake_atoms;
+      41             :   // Find what action we are taking the clusters from
+      42         108 :   if( !parseMultiColvarAtomList("CLUSTERS",-1,fake_atoms ) ) error("unable to interpret input CLUSTERS" );
+      43          54 :   if( mybasemulticolvars.size()!=1 ) error("should be exactly one multicolvar input");
+      44          54 :   atom_lab.resize(0); myclusters = dynamic_cast<ClusteringBase*>( mybasemulticolvars[0] );
+      45          54 :   if( !myclusters ) error("input label is not that of a DFS object");
+      46             :   // Setup the atom pack
+      47          54 :   myfatoms.setNumberOfAtoms( myclusters->getNumberOfNodes() );
+      48          54 :   myfvals.getIndices().resize( myclusters->getNumberOfNodes() );
+      49       33703 :   for(unsigned i=0; i<myclusters->getNumberOfNodes(); ++i) myfatoms.setAtomIndex( i, i );
+      50          54 : }
+      51             : 
+      52           8 : void ClusterAnalysisBase::turnOnDerivatives() {
+      53             :   // Check for dubious vessels
+      54          18 :   for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+      55          20 :     if( getPntrToVessel(i)->getName()=="MEAN" ) error("MEAN of cluster is not differentiable");
+      56          20 :     if( getPntrToVessel(i)->getName()=="VMEAN" ) error("VMEAN of cluster is not differentiable");
+      57             :   }
+      58           8 :   MultiColvarBase::turnOnDerivatives();
+      59           8 : }
+      60             : 
+      61        2073 : unsigned ClusterAnalysisBase::getNumberOfQuantities() const {
+      62        2073 :   return myclusters->getNumberOfQuantities();
+      63             : }
+      64             : 
+      65    15981876 : unsigned ClusterAnalysisBase::getNumberOfNodes() const {
+      66    15981876 :   return myclusters->getNumberOfNodes();
+      67             : }
+      68             : 
+      69           4 : unsigned ClusterAnalysisBase::getNumberOfClusters() const {
+      70           4 :   return myclusters->getNumberOfClusters();
+      71             : }
+      72             : 
+      73          11 : bool ClusterAnalysisBase::isPeriodic() {
+      74          11 :   return mybasemulticolvars[0]->isPeriodic();
+      75             : }
+      76             : 
+      77          66 : void ClusterAnalysisBase::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+      78          66 :   myclusters->retrieveAtomsInCluster( clust, myatoms );
+      79          66 : }
+      80             : 
+      81           1 : bool ClusterAnalysisBase::nodeIsActive( const unsigned& ind ) const {
+      82           1 :   return myclusters->isCurrentlyActive( ind );
+      83             : }
+      84             : 
+      85        1801 : void ClusterAnalysisBase::getPropertiesOfNode( const unsigned& ind, std::vector<double>& vals ) const {
+      86        1801 :   myclusters->getInputData( ind, false, myfatoms, vals );
+      87        1801 : }
+      88             : 
+      89        1604 : void ClusterAnalysisBase::getNodePropertyDerivatives( const unsigned& ind, MultiValue& myvals ) const {
+      90        1604 :   myvals=myclusters->getInputDerivatives( ind, false, myfatoms );
+      91        1604 : }
+      92             : 
+      93        1975 : Vector ClusterAnalysisBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+      94        1975 :   return myclusters->getPositionOfAtomForLinkCells( iatom );
+      95             : }
+      96             : 
+      97           0 : double ClusterAnalysisBase::getCutoffForConnection() const {
+      98           0 :   return myclusters->getCutoffForConnection();
+      99             : }
+     100             : 
+     101           0 : bool ClusterAnalysisBase::areConnected( const unsigned& ind1, const unsigned& ind2 ) const {
+     102           0 :   return myclusters->areConnected( ind1, ind2 );
+     103             : }
+     104             : 
+     105             : }
+     106             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html b/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html new file mode 100644 index 0000000000..75d5769572 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.func.html b/coverage/adjmat/ClusterAnalysisBase.h.func.html new file mode 100644 index 0000000000..b41b4a9eb9 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.gcov.html b/coverage/adjmat/ClusterAnalysisBase.h.gcov.html new file mode 100644 index 0000000000..135ee4e120 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.gcov.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html b/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html new file mode 100644 index 0000000000..4d00bc31ac --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.func.html b/coverage/adjmat/ClusterDiameter.cpp.func.html new file mode 100644 index 0000000000..28f191c34e --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe806createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_127ClusterDiameterRegisterMe80D2Ev4168
_ZN4PLMD6adjmat15ClusterDiameter16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat15ClusterDiameter17turnOnDerivativesEv0
_ZN4PLMD6adjmat15ClusterDiameter9calculateEv2
_ZN4PLMD6adjmat15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.gcov.html b/coverage/adjmat/ClusterDiameter.cpp.gcov.html new file mode 100644 index 0000000000..e814786ced --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ClusterDiameter,"CLUSTER_DIAMETER")
+      81             : 
+      82           4 : void ClusterDiameter::registerKeywords( Keywords& keys ) {
+      83           4 :   ClusterAnalysisBase::registerKeywords( keys );
+      84           8 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      85           4 : }
+      86             : 
+      87           2 : ClusterDiameter::ClusterDiameter(const ActionOptions&ao):
+      88             :   Action(ao),
+      89           2 :   ClusterAnalysisBase(ao)
+      90             : {
+      91             :   // Find out which cluster we want
+      92           2 :   parse("CLUSTER",clustr);
+      93             : 
+      94           2 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      95           2 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      96             : 
+      97             :   // Create the task list
+      98        3994 :   for(unsigned  i=0; i<getNumberOfNodes(); ++i) {
+      99     7972024 :     for(unsigned j=0; j<getNumberOfNodes(); ++j) addTaskToList( i*getNumberOfNodes() + j );
+     100             :   }
+     101             :   // Now create a highest vessel
+     102           4 :   addVessel("HIGHEST", "", -1); std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     103           2 : }
+     104             : 
+     105           0 : void ClusterDiameter::turnOnDerivatives() {
+     106           0 :   error("cannot calculate derivatives of cluster radius.  This quantity is not differentiable");
+     107             : }
+     108             : 
+     109           2 : void ClusterDiameter::calculate() {
+     110             :   // Retrieve the atoms in the largest cluster
+     111           2 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( clustr, myatoms );
+     112             :   // Activate the relevant tasks
+     113           2 :   deactivateAllTasks();
+     114         128 :   for(unsigned i=1; i<myatoms.size(); ++i) {
+     115        4158 :     for(unsigned j=0; j<i; ++j) taskFlags[ myatoms[i]*getNumberOfNodes() + myatoms[j] ] = 1;
+     116             :   }
+     117           2 :   lockContributors();
+     118             :   // Now do the calculation
+     119           2 :   runAllTasks();
+     120           2 : }
+     121             : 
+     122        2016 : void ClusterDiameter::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     123        2016 :   unsigned iatom=std::floor(current/getNumberOfNodes()), jatom = current - iatom*getNumberOfNodes();
+     124        2016 :   Vector distance=getSeparation( getPosition(iatom), getPosition(jatom) );
+     125        2016 :   double dd = distance.modulo();
+     126             :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, dd );
+     127        2016 : }
+     128             : 
+     129             : }
+     130             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html b/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html new file mode 100644 index 0000000000..634bc87292 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.func.html b/coverage/adjmat/ClusterDistribution.cpp.func.html new file mode 100644 index 0000000000..11838d87e0 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_131ClusterDistributionRegisterMe83D2Ev4168
_ZN4PLMD6adjmat19ClusterDistribution16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat19ClusterDistribution9calculateEv1
_ZN4PLMD6adjmat19ClusterDistributionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.gcov.html b/coverage/adjmat/ClusterDistribution.cpp.gcov.html new file mode 100644 index 0000000000..fcf958e3ff --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(ClusterDistribution,"CLUSTER_DISTRIBUTION")
+      84             : 
+      85           3 : void ClusterDistribution::registerKeywords( Keywords& keys ) {
+      86           3 :   ClusterAnalysisBase::registerKeywords( keys );
+      87           6 :   keys.add("compulsory","TRANSFORM","none","the switching function to use to convert the crystallinity parameter to a number between zero and one");
+      88           6 :   keys.addFlag("INVERSE_TRANSFORM",false,"when TRANSFORM appears alone the input symmetry functions, \\f$x\\f$ are transformed used \\f$1-s(x)\\f$ "
+      89             :                "where \\f$s(x)\\f$ is a switching function.  When this option is used you instead transform using \\f$s(x)\\f$ only.");
+      90           9 :   keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("BETWEEN");
+      91          12 :   keys.use("HISTOGRAM"); keys.use("ALT_MIN"); keys.use("MIN"); keys.use("MAX");
+      92           3 : }
+      93             : 
+      94           1 : ClusterDistribution::ClusterDistribution(const ActionOptions&ao):
+      95             :   Action(ao),
+      96             :   ClusterAnalysisBase(ao),
+      97           1 :   nderivatives(0)
+      98             : {
+      99           1 :   use_switch=false;
+     100           2 :   std::string input, errors; parse("TRANSFORM",input);
+     101           1 :   if( input!="none" ) {
+     102           0 :     use_switch=true; sf.set( input, errors );
+     103           0 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     104             :   }
+     105           1 :   parseFlag("INVERSE_TRANSFORM",inverse);
+     106           1 :   if( inverse && !use_switch ) error("INVERSE_TRANSFORM option was specified but no TRANSOFRM switching function was given");
+     107             : 
+     108             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+     109           7 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+     110             : 
+     111             :   // And now finish the setup of everything in the base
+     112           1 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     113           1 : }
+     114             : 
+     115           1 : void ClusterDistribution::calculate() {
+     116             :   // Activate the relevant tasks
+     117           1 :   nderivatives = getNumberOfDerivatives();
+     118           1 :   deactivateAllTasks();
+     119           4 :   for(unsigned i=0; i<getNumberOfClusters(); ++i) taskFlags[i]=1;
+     120           1 :   lockContributors();
+     121             :   // Now do the calculation
+     122           1 :   runAllTasks();
+     123           1 : }
+     124             : 
+     125           3 : void ClusterDistribution::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     126           3 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( current+1, myatoms );
+     127             :   // This deals with filters
+     128           3 :   if( myatoms.size()==1 && !nodeIsActive(myatoms[0]) ) return ;
+     129             : 
+     130           3 :   std::vector<double> vals( getNumberOfQuantities() );
+     131           3 :   MultiValue tvals( getNumberOfQuantities(), nderivatives );
+     132             : 
+     133             :   // And this builds everything for this particular atom
+     134             :   double vv, df, tval=0;
+     135           9 :   for(unsigned j=0; j<myatoms.size(); ++j) {
+     136           6 :     unsigned i=myatoms[j];
+     137           6 :     getPropertiesOfNode( i, vals );
+     138           6 :     if( use_switch && !inverse ) {
+     139           0 :       vv = 1.0 - sf.calculate( vals[1], df );
+     140           0 :       tval += vals[0]*vv; df=-df*vals[1];
+     141           6 :     } else if( use_switch ) {
+     142           0 :       vv = sf.calculate( vals[1], df );
+     143           0 :       tval += vals[0]*vv; df=df*vals[1];
+     144             :     } else {
+     145           6 :       tval += vals[0]*vals[1]; df=1.; vv=vals[1];
+     146             :     }
+     147           6 :     if( !doNotCalculateDerivatives() ) {
+     148           6 :       getNodePropertyDerivatives( i, tvals );
+     149         168 :       for(unsigned k=0; k<tvals.getNumberActive(); ++k) {
+     150         162 :         unsigned kat=tvals.getActiveIndex(k);
+     151         162 :         myvals.addDerivative( 1, kat, vals[0]*df*tvals.getDerivative(1,kat) + vv*tvals.getDerivative(0,kat) );
+     152             :       }
+     153           6 :       tvals.clearAll();
+     154             :     }
+     155             :   }
+     156             :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, tval );
+     157           3 : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html b/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html new file mode 100644 index 0000000000..ae3961c976 --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe746createERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.func.html b/coverage/adjmat/ClusterProperties.cpp.func.html new file mode 100644 index 0000000000..ed77c77f6a --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe746createERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_129ClusterPropertiesRegisterMe74D2Ev4168
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.gcov.html b/coverage/adjmat/ClusterProperties.cpp.gcov.html new file mode 100644 index 0000000000..9a9d301792 --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + 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-05-27 13:05: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       12558 : PLUMED_REGISTER_ACTION(ClusterProperties,"CLUSTER_PROPERTIES")
+      75             : 
+      76          29 : void ClusterProperties::registerKeywords( Keywords& keys ) {
+      77          29 :   ClusterAnalysisBase::registerKeywords( keys );
+      78          58 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      79          87 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      80          87 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      81          87 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+      82         116 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("ALT_MIN");
+      83         145 :   keys.use("MIN"); keys.use("MAX"); keys.use("SUM"); keys.use("LOWEST"); keys.use("HIGHEST");
+      84          29 : }
+      85             : 
+      86          27 : ClusterProperties::ClusterProperties(const ActionOptions&ao):
+      87             :   Action(ao),
+      88          27 :   ClusterAnalysisBase(ao)
+      89             : {
+      90             :   // Find out which cluster we want
+      91          27 :   parse("CLUSTER",clustr);
+      92             : 
+      93          27 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      94          27 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      95             : 
+      96             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+      97       18214 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+      98             : 
+      99             :   // And now finish the setup of everything in the base
+     100          27 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     101          27 : }
+     102             : 
+     103          34 : void ClusterProperties::calculate() {
+     104             :   // Retrieve the atoms in the largest cluster
+     105          34 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( clustr, myatoms );
+     106             :   // Activate the relevant tasks
+     107          34 :   deactivateAllTasks();
+     108        1373 :   for(unsigned i=0; i<myatoms.size(); ++i) taskFlags[myatoms[i]]=1;
+     109          34 :   lockContributors();
+     110             :   // Now do the calculation
+     111          34 :   runAllTasks();
+     112          34 : }
+     113             : 
+     114        1795 : void ClusterProperties::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     115        1795 :   std::vector<double> vals( myvals.getNumberOfValues() ); getPropertiesOfNode( current, vals );
+     116        1795 :   if( !doNotCalculateDerivatives() ) getNodePropertyDerivatives( current, myvals );
+     117        5385 :   for(unsigned k=0; k<vals.size(); ++k) myvals.setValue( k, vals[k] );
+     118        1795 : }
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.func-sort-c.html b/coverage/adjmat/ClusterSize.cpp.func-sort-c.html new file mode 100644 index 0000000000..967e206a7b --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE26
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.func.html b/coverage/adjmat/ClusterSize.cpp.func.html new file mode 100644 index 0000000000..002ca58c7b --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11ClusterSize16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD6adjmat11ClusterSize17turnOnDerivativesEv0
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
_ZN4PLMD6adjmat11ClusterSizeC1ERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat11ClusterSizeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe796createERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_123ClusterSizeRegisterMe79D2Ev4168
_ZNK4PLMD6adjmat11ClusterSize11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.gcov.html b/coverage/adjmat/ClusterSize.cpp.gcov.html new file mode 100644 index 0000000000..35f7bfc829 --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + 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-05-27 13:05: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       12552 : PLUMED_REGISTER_ACTION(ClusterSize,"CLUSTER_NATOMS")
+      80             : 
+      81          26 : void ClusterSize::registerKeywords( Keywords& keys ) {
+      82          26 :   ClusterAnalysisBase::registerKeywords( keys );
+      83          52 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      84          26 : }
+      85             : 
+      86          24 : ClusterSize::ClusterSize(const ActionOptions&ao):
+      87             :   Action(ao),
+      88          24 :   ClusterAnalysisBase(ao)
+      89             : {
+      90             :   // Find out which cluster we want
+      91          24 :   parse("CLUSTER",clustr);
+      92             : 
+      93          24 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      94          24 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      95             : 
+      96             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+      97       11488 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+      98             :   // And now finish the setup of everything in the base
+      99          24 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     100          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.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html b/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html new file mode 100644 index 0000000000..cb5e412c74 --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98D2Ev4168
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.func.html b/coverage/adjmat/ClusterWithSurface.cpp.func.html new file mode 100644 index 0000000000..6930b07d2e --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe986createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_130ClusterWithSurfaceRegisterMe98D2Ev4168
_ZN4PLMD6adjmat18ClusterWithSurface16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat18ClusterWithSurface17performClusteringEv2
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZN4PLMD6adjmat18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat18ClusterWithSurface12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE0
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
_ZNK4PLMD6adjmat18ClusterWithSurface19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface22getCutoffForConnectionEv2
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZNK4PLMD6adjmat18ClusterWithSurface29getPositionOfAtomForLinkCellsERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.gcov.html b/coverage/adjmat/ClusterWithSurface.cpp.gcov.html new file mode 100644 index 0000000000..c7f8bac7ce --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ClusterWithSurface,"CLUSTER_WITHSURFACE")
+      99             : 
+     100           4 : void ClusterWithSurface::registerKeywords( Keywords& keys ) {
+     101           4 :   ClusteringBase::registerKeywords( keys );
+     102           4 :   keys.remove("MATRIX");
+     103           8 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     104           8 :   keys.add("compulsory","RCUT_SURF","you also have the option to find the atoms on the surface of the cluster.  An atom must be within this distance of one of the atoms "
+     105             :            "of the cluster in order to be considered a surface atom");
+     106           4 : }
+     107             : 
+     108           2 : ClusterWithSurface::ClusterWithSurface(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           2 :   ClusteringBase(ao)
+     111             : {
+     112             :   std::vector<AtomNumber> fake_atoms;
+     113           4 :   if( !parseMultiColvarAtomList("CLUSTERS",-1,fake_atoms ) ) error("unable to find CLUSTERS input");
+     114           2 :   if( mybasemulticolvars.size()!=1 ) error("should be exactly one multicolvar input");
+     115             : 
+     116             :   // Retrieve the adjacency matrix of interest
+     117           2 :   atom_lab.resize(0); myclusters = dynamic_cast<ClusteringBase*>( mybasemulticolvars[0] );
+     118           2 :   if( !myclusters ) error( mybasemulticolvars[0]->getLabel() + " does not calculate clusters");
+     119             : 
+     120             :   // Setup switching function for surface atoms
+     121           2 :   double rcut_surf; parse("RCUT_SURF",rcut_surf);
+     122           2 :   if( rcut_surf>0 ) log.printf("  counting surface atoms that are within %f of the cluster atoms \n",rcut_surf);
+     123           2 :   rcut_surf2=rcut_surf*rcut_surf;
+     124             : 
+     125             :   // And now finish the setup of everything in the base
+     126           2 :   setupMultiColvarBase( fake_atoms );
+     127           2 : }
+     128             : 
+     129           4 : unsigned ClusterWithSurface::getNumberOfDerivatives() {
+     130           4 :   return myclusters->getNumberOfDerivatives();
+     131             : }
+     132             : 
+     133    16155834 : unsigned ClusterWithSurface::getNumberOfNodes() const {
+     134    16155834 :   return myclusters->getNumberOfNodes();
+     135             : }
+     136             : 
+     137         128 : AtomNumber ClusterWithSurface::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+     138         128 :   return myclusters->getAbsoluteIndexOfCentralAtom(i);
+     139             : }
+     140             : 
+     141           0 : void ClusterWithSurface::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
+     142           0 :   myclusters->getInputData( ind, normed, myatoms, orient0 );
+     143           0 : }
+     144             : 
+     145           0 : MultiValue& ClusterWithSurface::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
+     146           0 :   return myclusters->getInputDerivatives( ind, normed, myatoms );
+     147             : }
+     148             : 
+     149          14 : unsigned ClusterWithSurface::getNumberOfQuantities() const {
+     150          14 :   return myclusters->getNumberOfQuantities();
+     151             : }
+     152             : 
+     153           2 : double  ClusterWithSurface::getCutoffForConnection() const {
+     154           2 :   double tcut = myclusters->getCutoffForConnection();
+     155           2 :   if( tcut>std::sqrt(rcut_surf2) ) return tcut;
+     156           0 :   return std::sqrt(rcut_surf2);
+     157             : }
+     158             : 
+     159           6 : void ClusterWithSurface::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+     160           6 :   std::vector<unsigned> tmpat; myclusters->retrieveAtomsInCluster( clust, tmpat );
+     161             : 
+     162             :   // Prevent double counting
+     163           6 :   std::vector<bool> incluster( getNumberOfNodes(), false );
+     164          90 :   for(unsigned i=0; i<tmpat.size(); ++i) incluster[tmpat[i]]=true;
+     165             : 
+     166             :   // Find the atoms in the the clusters
+     167           6 :   std::vector<bool> surface_atom( getNumberOfNodes(), false );
+     168          90 :   for(unsigned i=0; i<tmpat.size(); ++i) {
+     169      167748 :     for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     170      167664 :       if( incluster[j] ) continue;
+     171      166488 :       double dist2=getSeparation( getPosition(tmpat[i]), getPosition(j) ).modulo2();
+     172      166488 :       if( dist2<rcut_surf2 ) { surface_atom[j]=true; }
+     173             :     }
+     174             :   }
+     175             :   unsigned nsurf_at=0;
+     176       11982 :   for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     177       11976 :     if( surface_atom[j] ) nsurf_at++;
+     178             :   }
+     179           6 :   myatoms.resize( nsurf_at + tmpat.size() );
+     180          90 :   for(unsigned i=0; i<tmpat.size(); ++i) myatoms[i]=tmpat[i];
+     181           6 :   unsigned nn=tmpat.size();
+     182       11982 :   for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     183       11976 :     if( surface_atom[j] ) { myatoms[nn]=j; nn++; }
+     184             :   }
+     185           6 :   plumed_assert( nn==myatoms.size() );
+     186           6 : }
+     187             : 
+     188           0 : Vector ClusterWithSurface::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     189           0 :   return myclusters->getPositionOfAtomForLinkCells( iatom );
+     190             : }
+     191             : 
+     192             : }
+     193             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html b/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..e47946d262 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.func.html b/coverage/adjmat/ClusteringBase.cpp.func.html new file mode 100644 index 0000000000..c5dbdef4fa --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.gcov.html b/coverage/adjmat/ClusteringBase.cpp.gcov.html new file mode 100644 index 0000000000..da956cc6cf --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + 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-05-27 13:05: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          21 : void ClusteringBase::registerKeywords( Keywords& keys ) {
+      30          21 :   ActionWithInputMatrix::registerKeywords( keys );
+      31          21 : }
+      32             : 
+      33          17 : ClusteringBase::ClusteringBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithInputMatrix(ao),
+      36          17 :   number_of_cluster(-1)
+      37             : {
+      38          17 :   if( getAdjacencyVessel() ) {
+      39          15 :     cluster_sizes.resize(getNumberOfNodes()); which_cluster.resize(getNumberOfNodes());
+      40          15 :     if( getNumberOfNodeTypes()!=1 ) error("should only be running clustering with one base multicolvar in function");
+      41          15 :     if( !getAdjacencyVessel()->undirectedGraph() ) error("input contact matrix is incompatible with clustering");
+      42             :   }
+      43          34 :   if( keywords.exists("MATRIX") ) {
+      44          15 :     std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+      45             :   }
+      46          17 : }
+      47             : 
+      48           8 : void ClusteringBase::turnOnDerivatives() {
+      49             :   // Check base multicolvar isn't density probably other things shouldn't be allowed here as well
+      50           8 :   if( (getAdjacencyVessel()->getMatrixAction())->getNumberOfBaseMultiColvars()>0 ) {
+      51           7 :     if( getBaseMultiColvar(0)->isDensity() ) error("DFS clustering cannot be differentiated if base multicolvar is DENSITY");
+      52             :   }
+      53             : 
+      54             :   // Ensure that derivatives are turned on in base classes
+      55           8 :   ActionWithInputMatrix::turnOnDerivatives();
+      56           8 : }
+      57             : 
+      58          26 : void ClusteringBase::calculate() {
+      59             :   // All the clusters have zero size initially
+      60        8219 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+      61             :   // Do the clustering bit
+      62          26 :   performClustering();
+      63             :   // Order the clusters in the system by size (this returns ascending order )
+      64          26 :   std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+      65          26 : }
+      66             : 
+      67          74 : void ClusteringBase::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+      68          74 :   unsigned n=0; myatoms.resize( cluster_sizes[cluster_sizes.size() - clust].first );
+      69       45287 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+      70       45213 :     if( which_cluster[i]==cluster_sizes[cluster_sizes.size() - clust].second ) { myatoms[n]=i; n++; }
+      71             :   }
+      72          74 : }
+      73             : 
+      74           0 : bool ClusteringBase::areConnected( const unsigned& iatom, const unsigned& jatom ) const {
+      75           0 :   return getAdjacencyVessel()->nodesAreConnected( iatom, jatom );
+      76             : }
+      77             : 
+      78           8 : double ClusteringBase::getCutoffForConnection() const {
+      79           8 :   return getAdjacencyVessel()->getCutoffForConnection();
+      80             : }
+      81             : 
+      82             : }
+      83             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.func-sort-c.html b/coverage/adjmat/ClusteringBase.h.func-sort-c.html new file mode 100644 index 0000000000..4ea8c2f63a --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.func.html b/coverage/adjmat/ClusteringBase.h.func.html new file mode 100644 index 0000000000..a7f3b93ca1 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.gcov.html b/coverage/adjmat/ClusteringBase.h.gcov.html new file mode 100644 index 0000000000..0d928f5b84 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.gcov.html @@ -0,0 +1,146 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html b/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..dcd09ac3dd --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.func.html b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html new file mode 100644 index 0000000000..b1532ab3f5 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe876createERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_132ContactAlignedMatrixRegisterMe87D2Ev4168
_ZN4PLMD6adjmat20ContactAlignedMatrix16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat20ContactAlignedMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat20ContactAlignedMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html b/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html new file mode 100644 index 0000000000..45480508d8 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(ContactAlignedMatrix,"ALIGNED_MATRIX")
+      88             : 
+      89           2 : void ContactAlignedMatrix::registerKeywords( Keywords& keys ) {
+      90           2 :   AlignedMatrixBase::registerKeywords( keys );
+      91           4 :   keys.add("numbered","ORIENTATION_SWITCH","A switching function that transforms the dot product of the input vectors.");
+      92           2 : }
+      93             : 
+      94           0 : ContactAlignedMatrix::ContactAlignedMatrix( const ActionOptions& ao ):
+      95             :   Action(ao),
+      96           0 :   AlignedMatrixBase(ao)
+      97             : {
+      98           0 :   unsigned nrows, ncols, ig; retrieveTypeDimensions( nrows, ncols, ig );
+      99           0 :   sf.resize( nrows, ncols );
+     100           0 :   parseConnectionDescriptions("ORIENTATION_SWITCH",false,0);
+     101           0 : }
+     102             : 
+     103           0 : void ContactAlignedMatrix::readOrientationConnector( const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     104           0 :   plumed_assert( desc.size()==1 ); std::string errors; sf(j,i).set(desc[0],errors);
+     105           0 :   if( j!=i ) sf(i,j).set(desc[0],errors);
+     106           0 :   log.printf("  vectors in %u th and %u th groups must have a dot product that is greater than %s \n",i+1,j+1,(sf(i,j).description()).c_str() );
+     107           0 : }
+     108             : 
+     109           0 : double ContactAlignedMatrix::computeVectorFunction( const unsigned& iv, const unsigned& jv,
+     110             :     const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     111             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     112           0 :   double dot_df, dot=0; dconn.zero();
+     113           0 :   for(unsigned k=2; k<vec1.size(); ++k) dot+=vec1[k]*vec2[k];
+     114           0 :   double f_dot = sf(iv,jv).calculate( dot, dot_df );
+     115           0 :   for(unsigned k=2; k<vec1.size(); ++k) { dvec1[k]=dot_df*vec2[k]; dvec2[k]=dot_df*vec1[k]; }
+     116           0 :   return f_dot;
+     117             : }
+     118             : 
+     119             : }
+     120             : }
+     121             : 
+     122             : 
+     123             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..8bf10d59bd --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe836createERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83D2Ev4168
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func.html b/coverage/adjmat/ContactMatrix.cpp.func.html new file mode 100644 index 0000000000..fe5f461323 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe836createERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125ContactMatrixRegisterMe83D2Ev4168
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.gcov.html b/coverage/adjmat/ContactMatrix.cpp.gcov.html new file mode 100644 index 0000000000..3fb6072480 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-05-27 13:05: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       12528 : PLUMED_REGISTER_ACTION(ContactMatrix,"CONTACT_MATRIX")
+      84             : 
+      85          14 : void ContactMatrix::registerKeywords( Keywords& keys ) {
+      86          14 :   AdjacencyMatrixBase::registerKeywords( keys );
+      87          28 :   keys.add("atoms","ATOMS","The list of atoms for which you would like to calculate the contact matrix.  The atoms involved must be specified "
+      88             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      89             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      90             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      91             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      92          28 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      93             :            "The following provides information on the \\ref switchingfunction that are available. ");
+      94             : // I added these keywords so I can test the results I get for column and row sums against output from COORDINATIONNUMBERS
+      95             : /// These  should never be used in production as I think they will be much slower than COORDINATIONNUMBERS
+      96          42 :   keys.add("hidden","ATOMSA",""); keys.add("hidden","ATOMSB","");
+      97          14 : }
+      98             : 
+      99          12 : ContactMatrix::ContactMatrix( const ActionOptions& ao ):
+     100             :   Action(ao),
+     101          12 :   AdjacencyMatrixBase(ao)
+     102             : {
+     103             :   // Read in the atoms and setup the matrix
+     104          24 :   readMaxTwoSpeciesMatrix( "ATOMS", "ATOMSA", "ATOMSB", true );
+     105          12 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ncol_t );
+     106          12 :   switchingFunction.resize( nrows, ncols );
+     107             :   // Read in the switching functions
+     108          24 :   parseConnectionDescriptions("SWITCH",false,ncol_t);
+     109             : 
+     110             :   // Find the largest sf cutoff
+     111          12 :   double sfmax=switchingFunction(0,0).get_dmax();
+     112          25 :   for(unsigned i=0; i<switchingFunction.nrows(); ++i) {
+     113          28 :     for(unsigned j=0; j<switchingFunction.ncols(); ++j) {
+     114          15 :       double tsf=switchingFunction(i,j).get_dmax();
+     115          15 :       if( tsf>sfmax ) sfmax=tsf;
+     116             :     }
+     117             :   }
+     118             :   // And set the link cell cutoff
+     119          12 :   setLinkCellCutoff( sfmax );
+     120          12 : }
+     121             : 
+     122          14 : void ContactMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     123          14 :   plumed_assert( id==0 && desc.size()==1 ); std::string errors; switchingFunction(j,i).set(desc[0],errors);
+     124          14 :   if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     125          14 :   if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+     126          28 :   log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+     127          14 : }
+     128             : 
+     129       55746 : double ContactMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     130       55746 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     131      166288 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).get_dmax2() ) return 1.0;
+     132             :   return 0.0;
+     133             : }
+     134             : 
+     135       28888 : double ContactMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     136       28888 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     137             :   double dfunc;
+     138       57301 :   double sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).calculate( distance.modulo(), dfunc );
+     139             : 
+     140       28888 :   if( !doNotCalculateDerivatives() ) {
+     141       28654 :     addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
+     142       28654 :     addAtomDerivatives( 1, 1, (+dfunc)*distance, myatoms );
+     143       28654 :     myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor(distance,distance) );
+     144             :   }
+     145       28888 :   return sw;
+     146             : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.func-sort-c.html b/coverage/adjmat/DFSClustering.cpp.func-sort-c.html new file mode 100644 index 0000000000..5305cdb197 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe946createERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94D2Ev4168
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.func.html b/coverage/adjmat/DFSClustering.cpp.func.html new file mode 100644 index 0000000000..ee1d703281 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe946createERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125DFSClusteringRegisterMe94D2Ev4168
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.gcov.html b/coverage/adjmat/DFSClustering.cpp.gcov.html new file mode 100644 index 0000000000..926c35295a --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + 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-05-27 13:05: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       12534 : PLUMED_REGISTER_ACTION(DFSClustering,"DFSCLUSTERING")
+      95             : 
+      96          17 : void DFSClustering::registerKeywords( Keywords& keys ) {
+      97          17 :   ClusteringBase::registerKeywords( keys );
+      98          34 :   keys.add("compulsory","MAXCONNECT","0","maximum number of connections that can be formed by any given node in the graph. "
+      99             :            "By default this is set equal to zero and the number of connections is set equal to the number "
+     100             :            "of nodes.  You only really need to set this if you are working with a very large system and "
+     101             :            "memory is at a premium");
+     102          17 : }
+     103             : 
+     104          15 : DFSClustering::DFSClustering(const ActionOptions&ao):
+     105             :   Action(ao),
+     106          15 :   ClusteringBase(ao)
+     107             : {
+     108          15 :   unsigned maxconnections; parse("MAXCONNECT",maxconnections);
+     109             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+     110             :   if( maxconnections>0 ) edge_list.resize( getNumberOfNodes()*maxconnections );
+     111             :   else edge_list.resize(0.5*getNumberOfNodes()*(getNumberOfNodes()-1));
+     112             : #else
+     113          15 :   nneigh.resize( getNumberOfNodes() ); color.resize(getNumberOfNodes());
+     114          15 :   if( maxconnections>0 ) adj_list.resize(getNumberOfNodes(),maxconnections);
+     115          15 :   else adj_list.resize(getNumberOfNodes(),getNumberOfNodes());
+     116             : #endif
+     117          15 : }
+     118             : 
+     119          24 : void DFSClustering::performClustering() {
+     120             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+     121             :   // Get the list of edges
+     122             :   unsigned nedges=0; getAdjacencyVessel()->retrieveEdgeList( nedges, edge_list );
+     123             : 
+     124             :   // Build the graph using boost
+     125             :   boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS> sg(&edge_list[0],&edge_list[nedges],getNumberOfNodes());
+     126             : 
+     127             :   // Find the connected components using boost (-1 here for compatibility with non-boost version)
+     128             :   number_of_cluster=boost::connected_components(sg,&which_cluster[0]) - 1;
+     129             : 
+     130             :   // And work out the size of each cluster
+     131             :   for(unsigned i=0; i<which_cluster.size(); ++i) cluster_sizes[which_cluster[i]].first++;
+     132             : #else
+     133             :   // Get the adjacency matrix
+     134          24 :   getAdjacencyVessel()->retrieveAdjacencyLists( nneigh, adj_list );
+     135             : 
+     136             :   // Perform clustering
+     137          24 :   number_of_cluster=-1; color.assign(color.size(),0);
+     138        8217 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+     139        8193 :     if( color[i]==0 ) { number_of_cluster++; color[i]=explore(i); }
+     140             :   }
+     141             : #endif
+     142          24 : }
+     143             : 
+     144             : #ifndef __PLUMED_HAS_BOOST_GRAPH
+     145        8193 : int DFSClustering::explore( const unsigned& index ) {
+     146             : 
+     147        8193 :   color[index]=1;
+     148       38219 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     149       30026 :     unsigned j=adj_list(index,i);
+     150       30026 :     if( color[j]==0 ) color[j]=explore(j);
+     151             :   }
+     152             : 
+     153             :   // Count the size of the cluster
+     154        8193 :   cluster_sizes[number_of_cluster].first++;
+     155        8193 :   which_cluster[index] = number_of_cluster;
+     156        8193 :   return color[index];
+     157             : }
+     158             : #endif
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.func-sort-c.html b/coverage/adjmat/DumpGraph.cpp.func-sort-c.html new file mode 100644 index 0000000000..c7f0c23f31 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.func.html b/coverage/adjmat/DumpGraph.cpp.func.html new file mode 100644 index 0000000000..bf015008d7 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe636createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_121DumpGraphRegisterMe63D2Ev4168
_ZN4PLMD6adjmat9DumpGraph16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat9DumpGraph5applyEv4
_ZN4PLMD6adjmat9DumpGraph6updateEv4
_ZN4PLMD6adjmat9DumpGraph9calculateEv4
_ZN4PLMD6adjmat9DumpGraphC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraphC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.gcov.html b/coverage/adjmat/DumpGraph.cpp.gcov.html new file mode 100644 index 0000000000..4bee25b344 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(DumpGraph,"DUMPGRAPH")
+      64             : 
+      65           6 : void DumpGraph::registerKeywords( Keywords& keys ) {
+      66           6 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      67          12 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      68          12 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the graph");
+      69          12 :   keys.add("compulsory","FILE","the name of the file on which to output the data");
+      70          12 :   keys.add("compulsory","MAXCONNECT","0","maximum number of connections that can be formed by any given node in the graph. "
+      71             :            "By default this is set equal to zero and the number of connections is set equal to the number "
+      72             :            "of nodes.  You only really need to set this if you are working with a very large system and "
+      73             :            "memory is at a premium");
+      74             : 
+      75           6 : }
+      76             : 
+      77           4 : DumpGraph::DumpGraph( const ActionOptions& ao):
+      78             :   Action(ao),
+      79             :   ActionPilot(ao),
+      80           4 :   mymatrix(NULL)
+      81             : {
+      82           8 :   parse("MAXCONNECT",maxconnections); std::string mstring; parse("MATRIX",mstring);
+      83           4 :   AdjacencyMatrixBase* mm = plumed.getActionSet().selectWithLabel<AdjacencyMatrixBase*>( mstring );
+      84           4 :   if( !mm ) error("found no action in set with label " + mstring + " that calculates matrix");
+      85           4 :   log.printf("  printing graph for matrix calculated by action %s\n", mm->getLabel().c_str() );
+      86             : 
+      87             :   // Retrieve the adjacency matrix of interest
+      88           4 :   for(unsigned i=0; i<mm->getNumberOfVessels(); ++i) {
+      89           4 :     mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mm->getPntrToVessel(i) );
+      90           4 :     if( mymatrix ) break ;
+      91             :   }
+      92           4 :   if( !mymatrix ) error( mm->getLabel() + " does not calculate an adjacency matrix");
+      93           4 :   if( !mymatrix->isSymmetric() ) error("input contact matrix must be symmetric");
+      94           4 :   if( maxconnections==0 ) maxconnections=mymatrix->getNumberOfRows();
+      95           4 :   parse("FILE",filename);
+      96           4 :   log.printf("  printing graph to file named %s \n",filename.c_str() );
+      97           4 :   checkRead();
+      98           4 : }
+      99             : 
+     100           4 : void DumpGraph::update() {
+     101           4 :   OFile ofile; ofile.link(*this); ofile.setBackupString("graph");
+     102           4 :   ofile.open( filename ); ofile.printf("graph G { \n");
+     103             :   // Print all nodes
+     104        1336 :   for(unsigned i=0; i<mymatrix->getNumberOfRows(); ++i) ofile.printf("%u [label=\"%u\"];\n",i,i);
+     105             :   // Now retrieve connectivitives
+     106           4 :   unsigned nedge; std::vector<std::pair<unsigned,unsigned> > edge_list( mymatrix->getNumberOfRows()*maxconnections );
+     107           4 :   mymatrix->retrieveEdgeList( nedge, edge_list );
+     108        6388 :   for(unsigned i=0; i<nedge; ++i) ofile.printf("%u -- %u \n", edge_list[i].first, edge_list[i].second );
+     109           4 :   ofile.printf("} \n");
+     110           4 : }
+     111             : 
+     112             : }
+     113             : }
+     114             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..554862434f --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe1076createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107D2Ev4168
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func.html b/coverage/adjmat/HbondMatrix.cpp.func.html new file mode 100644 index 0000000000..92ee9f1402 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe1076createERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_124HBondMatrixRegisterMe107D2Ev4168
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.gcov.html b/coverage/adjmat/HbondMatrix.cpp.gcov.html new file mode 100644 index 0000000000..2617e3bd11 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.gcov.html @@ -0,0 +1,308 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(HBondMatrix,"HBOND_MATRIX")
+     108             : 
+     109           4 : void HBondMatrix::registerKeywords( Keywords& keys ) {
+     110           4 :   AdjacencyMatrixBase::registerKeywords( keys );
+     111           8 :   keys.add("atoms","ATOMS","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+     112             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+     113             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     114             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     115             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     116             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     117           8 :   keys.add("atoms","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list, "
+     118             :            "an index range or by using a \\ref GROUP.  A list of hydrogen atoms is always required even if you specify the other atoms using "
+     119             :            "DONORS and ACCEPTORS as described below.");
+     120           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+     121             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     122             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     123             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     124             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     125           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+     126             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     127             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     128             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     129             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     130           8 :   keys.add("numbered","SWITCH","The \\ref switchingfunction that specifies how close a pair of atoms must be together for there to be a hydrogen bond between them");
+     131           8 :   keys.add("numbered","HSWITCH","The \\ref switchingfunction that specifies how close the hydrogen must be to the donor atom of the hydrogen bond for it to be "
+     132             :            "considered a hydrogen bond");
+     133           8 :   keys.add("numbered","ASWITCH","A \\ref switchingfunction that is used to specify what the angle between the vector connecting the donor atom to the acceptor atom and "
+     134             :            "the vector connecting the donor atom to the hydrogen must be in order for it considered to be a hydrogen bond");
+     135           4 :   keys.use("SUM");
+     136           4 : }
+     137             : 
+     138           2 : HBondMatrix::HBondMatrix( const ActionOptions& ao ):
+     139             :   Action(ao),
+     140           2 :   AdjacencyMatrixBase(ao)
+     141             : {
+     142           4 :   readMaxThreeSpeciesMatrix( "ATOMS", "DONORS", "ACCEPTORS", "HYDROGENS", false );
+     143           2 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+     144           2 :   distanceOOSwitch.resize( nrows, ncols ); distanceOHSwitch.resize( nrows, ncols ); angleSwitch.resize( nrows, ncols );
+     145           2 :   parseConnectionDescriptions("SWITCH",false,ndonor_types);
+     146           2 :   parseConnectionDescriptions("HSWITCH",false,ndonor_types);
+     147           4 :   parseConnectionDescriptions("ASWITCH",false,ndonor_types);
+     148             : 
+     149             :   // Find the largest sf cutoff
+     150           2 :   double sfmax=distanceOOSwitch(0,0).get_dmax();
+     151           4 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     152           4 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     153           2 :       double tsf=distanceOOSwitch(i,j).get_dmax();
+     154           2 :       if( tsf>sfmax ) sfmax=tsf;
+     155             :     }
+     156             :   }
+     157             :   // Set the link cell cutoff
+     158           2 :   setLinkCellCutoff( sfmax );
+     159           2 : }
+     160             : 
+     161           6 : void HBondMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     162           6 :   plumed_assert( id<3 && desc.size()==1 );
+     163           6 :   if( id==0 ) {
+     164           2 :     std::string errors; distanceOOSwitch(j,i).set(desc[0],errors);
+     165           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     166           2 :     if( j!=i) distanceOOSwitch(i,j).set(desc[0],errors);
+     167           4 :     log.printf("  atoms of type %u and %u must be within %s\n",i+1,j+1,(distanceOOSwitch(i,j).description()).c_str() );
+     168           4 :   } else if( id==1 ) {
+     169           2 :     std::string errors; distanceOHSwitch(j,i).set(desc[0],errors);
+     170           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     171           2 :     if( j!=i) distanceOHSwitch(i,j).set(desc[0],errors);
+     172           4 :     log.printf("  for atoms of type %u and %u the OH distance must be less than %s \n",i+1,j+1,(distanceOHSwitch(i,j).description()).c_str() );
+     173           2 :   } else if( id==2 ) {
+     174           2 :     std::string errors; angleSwitch(j,i).set(desc[0],errors);
+     175           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     176           2 :     if( j!=i) angleSwitch(i,j).set(desc[0],errors);
+     177           4 :     log.printf("  for atoms of type %u and %u the OOH angle must be less than %s \n",i+1,j+1,(angleSwitch(i,j).description()).c_str() );
+     178             :   }
+     179           6 : }
+     180             : 
+     181        4038 : double HBondMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     182             :   // Ensure we skip diagonal elements of square matrix
+     183        4038 :   if( myatoms.getIndex(0)==myatoms.getIndex(1) ) return 0.0;
+     184             : 
+     185        4038 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     186        8076 :   if( distance.modulo2()<distanceOOSwitch( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) return 1.0;
+     187             :   return 0.0;
+     188             : }
+     189             : 
+     190        4038 : double HBondMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     191        4038 :   Vector ood = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double ood_l = ood.modulo(); // acceptor - donor
+     192             :   double ood_df, ood_sw=distanceOOSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     193        4038 :                                           getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( ood_l, ood_df );
+     194             : 
+     195             :   // Get the base colvar numbers
+     196        4038 :   unsigned ano, dno = getBaseColvarNumber( myatoms.getIndex(0) );
+     197        8076 :   if( ndonor_types==0 ) ano = getBaseColvarNumber( myatoms.getIndex(1) );
+     198           0 :   else ano = getBaseColvarNumber( myatoms.getIndex(1) ) - ndonor_types;
+     199             : 
+     200             :   double value=0;
+     201        4038 :   if( myatoms.getNumberOfAtoms()>3 ) {
+     202      520170 :     for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) value+=calculateForThree( i, ano, dno, ood, ood_df, ood_sw,  myatoms );
+     203             :   } else {
+     204             :     plumed_dbg_assert( myatoms.getNumberOfAtoms()==3 );
+     205           0 :     value=calculateForThree( 2, ano, dno, ood, ood_df, ood_sw, myatoms );
+     206             :   }
+     207        4038 :   return value;
+     208             : }
+     209             : 
+     210      516132 : double HBondMatrix::calculateForThree( const unsigned& iat, const unsigned& ano, const unsigned& dno, const Vector& ood,
+     211             :                                        const double& ood_df, const double& ood_sw, multicolvar::AtomValuePack& myatoms ) const {
+     212      516132 :   Vector ohd=getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) ); double ohd_l=ohd.modulo();
+     213             :   double ohd_df, ohd_sw=distanceOHSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     214      516132 :                                           getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( ohd_l, ohd_df );
+     215             : 
+     216      516132 :   Angle a; Vector ood_adf, ohd_adf; double angle=a.compute( ood, ohd, ood_adf, ohd_adf );
+     217             :   double angle_df, angle_sw=angleSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     218      516132 :                                          getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( angle, angle_df );
+     219             : 
+     220      516132 :   if( !doNotCalculateDerivatives() ) {
+     221          36 :     addAtomDerivatives( 1, 0, angle_sw*ohd_sw*(-ood_df)*ood + angle_sw*ood_sw*(-ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*(-ood_adf-ohd_adf), myatoms );
+     222          36 :     addAtomDerivatives( 1, 1, angle_sw*ohd_sw*(+ood_df)*ood + ood_sw*ohd_sw*angle_df*angle*ood_adf, myatoms );
+     223          36 :     addAtomDerivatives( 1, iat, angle_sw*ood_sw*(+ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*ohd_adf, myatoms );
+     224          72 :     myatoms.addBoxDerivatives( 1, angle_sw*ohd_sw*(-ood_df)*Tensor(ood,ood) + angle_sw*ood_sw*(-ohd_df)*Tensor(ohd,ohd)
+     225         108 :                                -ood_sw*ohd_sw*angle_df*angle*(Tensor(ood,ood_adf)+Tensor(ohd,ohd_adf)) );
+     226             :   }
+     227      516132 :   return ood_sw*ohd_sw*angle_sw;
+     228             : }
+     229             : 
+     230             : }
+     231             : }
+     232             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html b/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html new file mode 100644 index 0000000000..13dbd440e7 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe756createERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.func.html b/coverage/adjmat/MatrixColumnSums.cpp.func.html new file mode 100644 index 0000000000..ccdc089812 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe756createERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_128MatrixColumnSumsRegisterMe75D2Ev4168
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.gcov.html b/coverage/adjmat/MatrixColumnSums.cpp.gcov.html new file mode 100644 index 0000000000..2c45943657 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + 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-05-27 13:05: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       12514 : PLUMED_REGISTER_ACTION(MatrixColumnSums,"COLUMNSUMS")
+      76             : 
+      77           7 : void MatrixColumnSums::registerKeywords( Keywords& keys ) {
+      78           7 :   ActionWithInputMatrix::registerKeywords( keys );
+      79          21 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      80          28 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      81          28 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      82           7 : }
+      83             : 
+      84           5 : MatrixColumnSums::MatrixColumnSums(const ActionOptions& ao):
+      85             :   Action(ao),
+      86           5 :   ActionWithInputMatrix(ao)
+      87             : {
+      88           5 :   if( (mymatrix->getMatrixAction())->mybasemulticolvars.size()>0 ) error("matrix row sums should only be calculated when inputs are atoms");
+      89             :   // Setup the tasks
+      90           5 :   unsigned ncols = mymatrix->getNumberOfColumns();
+      91           5 :   ablocks.resize(1); ablocks[0].resize( ncols );
+      92         155 :   for(unsigned i=0; i<ncols; ++i) addTaskToList( i );
+      93             :   // Set the positions - this is only used when getting positions for central atoms
+      94           5 :   if( mymatrix->undirectedGraph() ) {
+      95         144 :     for(unsigned i=0; i<ncols; ++i) ablocks[0][i]=i;
+      96             :   } else {
+      97          11 :     for(unsigned i=0; i<ncols; ++i) ablocks[0][i]=mymatrix->getNumberOfRows() + i;
+      98             :   }
+      99           5 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     100           5 : }
+     101             : 
+     102         238 : double MatrixColumnSums::compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const {
+     103         238 :   double sum=0.0; std::vector<double> tvals( mymatrix->getNumberOfComponents() );
+     104         238 :   unsigned nrows = mymatrix->getNumberOfRows();
+     105        9200 :   for(unsigned i=0; i<nrows; ++i) {
+     106        8962 :     if( mymatrix->undirectedGraph() && tinded==i ) continue;
+     107        8774 :     sum+=retrieveConnectionValue( i, tinded, tvals );
+     108             :   }
+     109             : 
+     110         238 :   if( !doNotCalculateDerivatives() ) {
+     111         110 :     MultiValue myvals( mymatrix->getNumberOfComponents(), myatoms.getNumberOfDerivatives() );
+     112             :     MultiValue& myvout=myatoms.getUnderlyingMultiValue();
+     113         880 :     for(unsigned i=0; i<nrows; ++i) {
+     114         770 :       if( mymatrix->isSymmetric() && tinded==i ) continue ;
+     115         710 :       addConnectionDerivatives( i, tinded, myvals, myvout );
+     116             :     }
+     117         110 :   }
+     118         238 :   return sum;
+     119             : }
+     120             : 
+     121             : }
+     122             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html b/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html new file mode 100644 index 0000000000..4f681033a6 --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe756createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.func.html b/coverage/adjmat/MatrixRowSums.cpp.func.html new file mode 100644 index 0000000000..6658a85833 --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe756createERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125MatrixRowSumsRegisterMe75D2Ev4168
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.gcov.html b/coverage/adjmat/MatrixRowSums.cpp.gcov.html new file mode 100644 index 0000000000..96c6cd084b --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(MatrixRowSums,"ROWSUMS")
+      76             : 
+      77           6 : void MatrixRowSums::registerKeywords( Keywords& keys ) {
+      78           6 :   ActionWithInputMatrix::registerKeywords( keys );
+      79          18 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      80          24 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      81          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      82           6 : }
+      83             : 
+      84           4 : MatrixRowSums::MatrixRowSums(const ActionOptions& ao):
+      85             :   Action(ao),
+      86           4 :   ActionWithInputMatrix(ao)
+      87             : {
+      88           4 :   if( (mymatrix->getMatrixAction())->mybasemulticolvars.size()>0 ) warning("matrix row may be problematic when inputs are not atoms");
+      89             :   // Setup the tasks
+      90           4 :   unsigned nrows = mymatrix->getNumberOfRows();
+      91           4 :   ablocks.resize(1); ablocks[0].resize( nrows );
+      92         147 :   for(unsigned i=0; i<nrows; ++i) { ablocks[0][i]=i; addTaskToList( i ); }
+      93           4 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+      94           4 : }
+      95             : 
+      96         203 : double MatrixRowSums::compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const {
+      97         203 :   std::vector<double> tvals( mymatrix->getNumberOfComponents() );
+      98         203 :   getInputData( tinded, false, myatoms, tvals ); double fval=tvals[1];
+      99             : 
+     100         203 :   if( !doNotCalculateDerivatives() ) {
+     101          75 :     tvals.assign( tvals.size(), 0 ); tvals[1]=1.0;
+     102          75 :     mergeInputDerivatives( 1, 1, 2, tinded, tvals, getInputDerivatives( tinded, false, myatoms ), myatoms );
+     103             :   }
+     104         203 :   return fval;
+     105             : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.func-sort-c.html b/coverage/adjmat/OutputCluster.cpp.func-sort-c.html new file mode 100644 index 0000000000..85ec0edef6 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.func.html b/coverage/adjmat/OutputCluster.cpp.func.html new file mode 100644 index 0000000000..bfc3b083ec --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe896createERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_125OutputClusterRegisterMe89D2Ev4168
_ZN4PLMD6adjmat13OutputCluster11explore_dfsERKj0
_ZN4PLMD6adjmat13OutputCluster16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6adjmat13OutputCluster5applyEv8
_ZN4PLMD6adjmat13OutputCluster6updateEv8
_ZN4PLMD6adjmat13OutputCluster7exploreERKjS3_0
_ZN4PLMD6adjmat13OutputCluster9calculateEv8
_ZN4PLMD6adjmat13OutputClusterC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputClusterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.gcov.html b/coverage/adjmat/OutputCluster.cpp.gcov.html new file mode 100644 index 0000000000..a0aaec42bb --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.gcov.html @@ -0,0 +1,309 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(OutputCluster,"OUTPUT_CLUSTER")
+      90             : 
+      91          10 : void OutputCluster::registerKeywords( Keywords& keys ) {
+      92          10 :   Action::registerKeywords( keys );
+      93          10 :   ActionPilot::registerKeywords( keys );
+      94          20 :   keys.add("compulsory","CLUSTERS","the action that performed the clustering");
+      95          20 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on");
+      96          20 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the atoms in the cluster");
+      97          20 :   keys.add("compulsory","FILE","the name of the file on which to output the details of the cluster");
+      98          20 :   keys.add("compulsory","MAXDEPTH","6","maximum depth for searches over paths to reconstruct clusters for PBC");
+      99          20 :   keys.add("compulsory","MAXGOES","200","number of times to run searches to reconstruct clusters");
+     100          20 :   keys.addFlag("MAKE_WHOLE",false,"reconstruct the clusters and remove all periodic boundary conditions.");
+     101          10 : }
+     102             : 
+     103           8 : OutputCluster::OutputCluster(const ActionOptions& ao):
+     104             :   Action(ao),
+     105             :   ActionPilot(ao),
+     106           8 :   myclusters(NULL)
+     107             : {
+     108             :   // Setup output file
+     109          16 :   ofile.link(*this); std::string file; parse("FILE",file);
+     110           8 :   if( file.length()==0 ) error("output file name was not specified");
+     111             :   // Search for xyz extension
+     112           8 :   output_xyz=false;
+     113           8 :   if( file.find(".")!=std::string::npos ) {
+     114             :     std::size_t dot=file.find_first_of('.');
+     115          16 :     if( file.substr(dot+1)=="xyz" ) output_xyz=true;
+     116             :   }
+     117             : 
+     118           8 :   ofile.open(file); log.printf("  on file %s \n",file.c_str());
+     119          24 :   parseFlag("MAKE_WHOLE",makewhole); parse("MAXDEPTH",maxdepth); parse("MAXGOES",maxgoes);
+     120           8 :   if( makewhole && !output_xyz) error("MAKE_WHOLE flag is not compatible with output of non-xyz files");
+     121             : 
+     122             :   // Find what action we are taking the clusters from
+     123           8 :   std::vector<std::string> matname(1); parse("CLUSTERS",matname[0]);
+     124           8 :   myclusters = plumed.getActionSet().selectWithLabel<ClusteringBase*>( matname[0] );
+     125           8 :   if( !myclusters ) error( matname[0] + " does not calculate perform a clustering of the atomic positions");
+     126             :   // N.B. the +0.3 is a fudge factor.  Reconstrucing PBC doesnt work without this GAT
+     127           8 :   addDependency( myclusters ); double rcut=myclusters->getCutoffForConnection() + 0.3; rcut2=rcut*rcut;
+     128             : 
+     129             :   // Read in the cluster we are calculating
+     130           8 :   parse("CLUSTER",clustr);
+     131           8 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+     132           8 :   if( clustr>myclusters->getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+     133           8 :   log.printf("  outputting atoms in %u th largest cluster found by %s \n",clustr,matname[0].c_str() );
+     134          16 : }
+     135             : 
+     136           8 : void OutputCluster::update() {
+     137           8 :   myclusters->retrieveAtomsInCluster( clustr, myatoms );
+     138           8 :   if( output_xyz ) {
+     139           0 :     ofile.printf("%u \n",static_cast<unsigned>(myatoms.size()));
+     140           0 :     ofile.printf("atoms in %u th largest cluster \n",clustr );
+     141           0 :     if( makewhole ) {
+     142             :       // Retrieve the atom positions
+     143           0 :       atomsin.resize( myatoms.size() );
+     144           0 :       for(unsigned i=0; i<myatoms.size(); ++i) atomsin[i]=myclusters->getPositionOfAtomForLinkCells( myatoms[i] );
+     145             :       // Build a connectivity matrix neglecting the pbc
+     146           0 :       nneigh.resize( myatoms.size(), 0 ); adj_list.resize( myatoms.size(), myatoms.size() );
+     147           0 :       for(unsigned i=1; i<myatoms.size(); ++i) {
+     148           0 :         for(unsigned j=0; j<i; ++j) {
+     149           0 :           if( delta( atomsin[i], atomsin[j] ).modulo2()<=rcut2 ) { adj_list(i,nneigh[i])=j; adj_list(j,nneigh[j])=i; nneigh[i]++; nneigh[j]++; }
+     150             :         }
+     151             :       }
+     152             :       // Use DFS to find the largest cluster not broken by PBC
+     153           0 :       number_of_cluster=-1; visited.resize( myatoms.size(), false );
+     154           0 :       cluster_sizes.resize( myatoms.size() ); which_cluster.resize( myatoms.size() );
+     155           0 :       for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+     156             : 
+     157           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     158           0 :         if( !visited[i] ) { number_of_cluster++; visited[i]=explore_dfs(i); }
+     159             :       }
+     160           0 :       std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+     161             : 
+     162             :       // Now set visited so that only those atoms in largest cluster will be start points for PBCing
+     163             :       visited.assign( visited.size(), false );
+     164           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     165           0 :         if( which_cluster[i]==cluster_sizes[cluster_sizes.size()-1].second ) visited[i]=true;
+     166             :       }
+     167             : 
+     168             :       // Now retrieve the original connectivity matrix (including pbc)
+     169           0 :       nneigh.assign( nneigh.size(), 0 );
+     170           0 :       for(unsigned i=1; i<myatoms.size(); ++i) {
+     171           0 :         for(unsigned j=0; j<i; ++j) {
+     172           0 :           if( myclusters->areConnected( myatoms[i], myatoms[j] ) ) { adj_list(i,nneigh[i])=j; adj_list(j,nneigh[j])=i; nneigh[i]++; nneigh[j]++; }
+     173             :         }
+     174             :       }
+     175             : 
+     176             :       // Now find broken bonds and run iterative deepening depth first search to reconstruct
+     177           0 :       for(unsigned jj=0; jj<maxgoes; ++jj) {
+     178             : 
+     179           0 :         for(unsigned j=0; j<myatoms.size(); ++j) {
+     180           0 :           if( !visited[j] ) continue;
+     181             : 
+     182           0 :           for(unsigned k=0; k<nneigh[j]; ++k) {
+     183           0 :             if( delta( atomsin[j],atomsin[adj_list(j,k)] ).modulo2()>rcut2 ) {
+     184             :               visited[j]=true;
+     185           0 :               for(unsigned depth=0; depth<=maxdepth; ++depth) explore( j, depth );
+     186             :             }
+     187             :           }
+     188             :         }
+     189             :       }
+     190             :       // And print final positions
+     191           0 :       for(unsigned i=0; i<myatoms.size(); ++i) ofile.printf( "X %f %f %f \n", atomsin[i][0], atomsin[i][1], atomsin[i][2] );
+     192             :     } else {
+     193           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     194           0 :         Vector pos=myclusters->getPositionOfAtomForLinkCells( myatoms[i] );
+     195           0 :         ofile.printf( "X %f %f %f \n", pos[0], pos[1], pos[2] );
+     196             :       }
+     197             :     }
+     198             :   } else {
+     199           8 :     ofile.printf("CLUSTERING RESULTS AT TIME %f : NUMBER OF ATOMS IN %u TH LARGEST CLUSTER EQUALS %u \n",getTime(),clustr,static_cast<unsigned>(myatoms.size()) );
+     200           8 :     ofile.printf("INDICES OF ATOMS : ");
+     201         512 :     for(unsigned i=0; i<myatoms.size(); ++i) ofile.printf("%d ",(myclusters->getAbsoluteIndexOfCentralAtom(myatoms[i])).index());
+     202           8 :     ofile.printf("\n");
+     203             :   }
+     204           8 : }
+     205             : 
+     206           0 : void OutputCluster::explore( const unsigned& index, const unsigned& depth ) {
+     207           0 :   if( depth==0 ) return ;
+     208             : 
+     209           0 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     210           0 :     unsigned j=adj_list(index,i); visited[j]=true;
+     211           0 :     Vector svec=myclusters->pbcDistance( atomsin[index], atomsin[j] );
+     212           0 :     atomsin[j] = atomsin[index] + svec;
+     213           0 :     explore( j, depth-1 );
+     214             :   }
+     215             : }
+     216             : 
+     217           0 : bool OutputCluster::explore_dfs( const unsigned& index ) {
+     218           0 :   visited[index]=true;
+     219           0 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     220           0 :     unsigned j=adj_list(index,i);
+     221           0 :     if( !visited[j] ) visited[j]=explore_dfs(j);
+     222             :   }
+     223             : 
+     224             :   // Count the size of the cluster
+     225           0 :   cluster_sizes[number_of_cluster].first++;
+     226           0 :   which_cluster[index] = number_of_cluster;
+     227           0 :   return visited[index];
+     228             : }
+     229             : 
+     230             : }
+     231             : }
+     232             : 
+     233             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html b/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..eee0b5c937 --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:3535100.0 %
Date:2024-05-27 13:05: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_8KeywordsE3
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95D2Ev4168
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.func.html b/coverage/adjmat/SMACMatrix.cpp.func.html new file mode 100644 index 0000000000..31f1ecdfdf --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:3535100.0 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat10SMACMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat10SMACMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE1
_ZN4PLMD6adjmat10SMACMatrixC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat10SMACMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_122SMACMatrixRegisterMe95D2Ev4168
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.gcov.html b/coverage/adjmat/SMACMatrix.cpp.gcov.html new file mode 100644 index 0000000000..a27103d38d --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + 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:3535100.0 %
Date:2024-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(SMACMatrix,"SMAC_MATRIX")
+      96             : 
+      97           3 : void SMACMatrix::registerKeywords( Keywords& keys ) {
+      98           3 :   AlignedMatrixBase::registerKeywords( keys );
+      99           6 :   keys.add("numbered","KERNEL","The various kernels that are used to determine whether or not the molecules are aligned");
+     100           3 : }
+     101             : 
+     102           1 : SMACMatrix::SMACMatrix( const ActionOptions& ao ):
+     103             :   Action(ao),
+     104           1 :   AlignedMatrixBase(ao)
+     105             : {
+     106           1 :   unsigned nrows, ncols, ig; retrieveTypeDimensions( nrows, ncols, ig );
+     107           1 :   kernels.resize( nrows, ncols ); parseConnectionDescriptions("KERNEL",true,0);
+     108           1 : }
+     109             : 
+     110           1 : void SMACMatrix::readOrientationConnector( const unsigned& iv, const unsigned& jv, const std::vector<std::string>& desc ) {
+     111           3 :   for(int i=0; i<desc.size(); i++) {
+     112           2 :     KernelFunctions mykernel( desc[i] );
+     113           2 :     kernels(iv,jv).push_back( mykernel );
+     114           2 :     if( jv!=iv ) kernels(jv,iv).push_back( mykernel );
+     115             :   }
+     116           1 :   if( kernels(iv,jv).size()==0 ) error("no kernels defined");
+     117           1 : }
+     118             : 
+     119        5806 : double SMACMatrix::computeVectorFunction( const unsigned& iv, const unsigned& jv,
+     120             :     const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     121             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     122             : 
+     123        5806 :   unsigned nvectors = ( vec1.size() - 2 ) / 3; plumed_assert( (vec1.size()-2)%3==0 );
+     124        5806 :   std::vector<Vector> dv1(nvectors), dv2(nvectors), tdconn(nvectors); Torsion t; std::vector<Vector> v1(nvectors), v2(nvectors);
+     125             :   std::vector<std::unique_ptr<Value>> pos;
+     126       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.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func-sort-c.html b/coverage/adjmat/Sprint.cpp.func-sort-c.html new file mode 100644 index 0000000000..a1c3f8d2f3 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe1086createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func.html b/coverage/adjmat/Sprint.cpp.func.html new file mode 100644 index 0000000000..28e71aff11 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe1086createERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_119SprintRegisterMe108D2Ev4168
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.gcov.html b/coverage/adjmat/Sprint.cpp.gcov.html new file mode 100644 index 0000000000..e09539144d --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.gcov.html @@ -0,0 +1,317 @@ + + + + + + + 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-05-27 13:05: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 \cite Pietrucci2011 so two atoms are adjacent if they are within a cutoff:
+      48             : 
+      49             : \plumedfile
+      50             : DENSITY SPECIES=1-7 LABEL=d1
+      51             : CONTACT_MATRIX ATOMS=d1 SWITCH={RATIONAL R_0=0.1} LABEL=mat
+      52             : SPRINT MATRIX=mat LABEL=ss
+      53             : PRINT ARG=ss.* FILE=colvar
+      54             : \endplumedfile
+      55             : 
+      56             : This example input calculates the 14 SPRINT coordinates for a molecule composed of 7 hydrogen and
+      57             : 7 carbon atoms.  Once again two atoms are adjacent if they are within a cutoff:
+      58             : 
+      59             : \plumedfile
+      60             : DENSITY SPECIES=1-7 LABEL=c
+      61             : DENSITY SPECIES=8-14 LABEL=h
+      62             : 
+      63             : CONTACT_MATRIX ...
+      64             :   ATOMS=c,h
+      65             :   SWITCH11={RATIONAL R_0=2.6 NN=6 MM=12}
+      66             :   SWITCH12={RATIONAL R_0=2.2 NN=6 MM=12}
+      67             :   SWITCH22={RATIONAL R_0=2.2 NN=6 MM=12}
+      68             :   LABEL=mat
+      69             : ... CONTACT_MATRIX
+      70             : 
+      71             : SPRINT MATRIX=mat LABEL=ss
+      72             : 
+      73             : PRINT ARG=ss.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : 
+      80             : namespace PLMD {
+      81             : namespace adjmat {
+      82             : 
+      83             : class Sprint : public ActionWithInputMatrix {
+      84             : private:
+      85             : /// Square root of number of atoms
+      86             :   double sqrtn;
+      87             : /// Vector that stores eigenvalues
+      88             :   std::vector<double> eigvals;
+      89             : /// This is used to speed up the calculation of derivatives
+      90             :   DynamicList<unsigned> active_elements;
+      91             : /// Vector that stores max eigenvector
+      92             :   std::vector< std::pair<double,int> > maxeig;
+      93             : /// Adjacency matrix
+      94             :   Matrix<double> thematrix;
+      95             : /// Matrix that stores eigenvectors
+      96             :   Matrix<double> eigenvecs;
+      97             : public:
+      98             : /// Create manual
+      99             :   static void registerKeywords( Keywords& keys );
+     100             : /// Constructor
+     101             :   explicit Sprint(const ActionOptions&);
+     102             : /// Do the matrix calculation
+     103             :   void calculate() override;
+     104             : /// Sprint needs its only apply routine as it creates values
+     105             :   void apply() override;
+     106             : };
+     107             : 
+     108       12506 : PLUMED_REGISTER_ACTION(Sprint,"SPRINT")
+     109             : 
+     110           3 : void Sprint::registerKeywords( Keywords& keys ) {
+     111           3 :   ActionWithInputMatrix::registerKeywords( keys );
+     112           3 :   componentsAreNotOptional(keys);
+     113           6 :   keys.addOutputComponent("coord","default","all \\f$n\\f$ sprint coordinates are calculated and then stored in increasing order. "
+     114             :                           "the smallest sprint coordinate will be labeled <em>label</em>.coord-0, "
+     115             :                           "the second smallest will be labelled <em>label</em>.coord-1 and so on");
+     116           3 : }
+     117             : 
+     118           1 : Sprint::Sprint(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   ActionWithInputMatrix(ao),
+     121           1 :   eigvals( getNumberOfNodes() ),
+     122           1 :   maxeig( getNumberOfNodes() ),
+     123           1 :   thematrix( getNumberOfNodes(), getNumberOfNodes() ),
+     124           3 :   eigenvecs( getNumberOfNodes(), getNumberOfNodes() )
+     125             : {
+     126             :   // Check on setup
+     127             :   // if( getNumberOfVessels()!=1 ) error("there should be no vessel keywords");
+     128             :   // Check for bad colvar input ( we  are going to get rid of this because we are going to have input adjacency matrix in future )
+     129             :   // for(unsigned i=0;i<getNumberOfAtomGroups();++i){
+     130             :   //    /// Check me GAT
+     131             :   //    // if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     132             :   // }
+     133             : 
+     134           1 :   if( !getAdjacencyVessel()->isSymmetric() ) error("input contact matrix is not symmetric");
+     135           1 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     136             : 
+     137             :   // Create all the values
+     138           1 :   sqrtn = std::sqrt( static_cast<double>( getNumberOfNodes() ) );
+     139          15 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+     140          14 :     std::string num; Tools::convert(i,num);
+     141          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.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..f389a3e5a9 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe786createERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78D2Ev4168
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func.html b/coverage/adjmat/TopologyMatrix.cpp.func.html new file mode 100644 index 0000000000..dd2a4d7cc1 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe786createERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78C2Ev4168
_ZN4PLMD6adjmat12_GLOBAL__N_126TopologyMatrixRegisterMe78D2Ev4168
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.gcov.html b/coverage/adjmat/TopologyMatrix.cpp.gcov.html new file mode 100644 index 0000000000..2a607464bf --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.gcov.html @@ -0,0 +1,400 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(TopologyMatrix,"TOPOLOGY_MATRIX")
+      79             : 
+      80           8 : void TopologyMatrix::registerKeywords( Keywords& keys ) {
+      81           8 :   AdjacencyMatrixBase::registerKeywords( keys );
+      82          16 :   keys.add("atoms","NODES","The list of atoms for which you would like to calculate the contact matrix.  The atoms involved must be specified "
+      83             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      84             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      85             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      86             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      87          16 :   keys.add("atoms","ATOMS","");
+      88          16 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      89             :            "The following provides information on the \\ref switchingfunction that are available.");
+      90          16 :   keys.add("numbered","RADIUS","");
+      91          16 :   keys.add("numbered","CYLINDER_SWITCH","a switching function on the distance from the center of the cylinder");
+      92          16 :   keys.add("numbered","BIN_SIZE","the size to use for the bins");
+      93          16 :   keys.add("compulsory","DENSITY_THRESHOLD","");
+      94          16 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      95          16 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      96          16 :   keys.add("hidden","FAKE","");
+      97           8 : }
+      98             : 
+      99           6 : TopologyMatrix::TopologyMatrix( const ActionOptions& ao ):
+     100             :   Action(ao),
+     101             :   AdjacencyMatrixBase(ao),
+     102          12 :   maxbins(0)
+     103             : {
+     104          12 :   readMaxThreeSpeciesMatrix("NODES", "FAKE", "FAKE", "ATOMS", true );
+     105           6 :   unsigned nrows, ncols, ndonor_types; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+     106           6 :   switchingFunction.resize( nrows, ncols ); parseConnectionDescriptions("SWITCH",false,ndonor_types);
+     107           6 :   cylinder_sw.resize( nrows, ncols ); parseConnectionDescriptions("RADIUS",false,ndonor_types);
+     108           6 :   low_sf.resize( nrows, ncols ); parseConnectionDescriptions("CYLINDER_SWITCH",false,ndonor_types);
+     109           6 :   binw_mat.resize( nrows, ncols ); cell_volume.resize( nrows, ncols );
+     110           6 :   parseConnectionDescriptions("BIN_SIZE",false,ndonor_types);
+     111             :   // Read in stuff for grid
+     112          18 :   parse("SIGMA",sigma); parse("KERNEL",kerneltype);
+     113             :   // Read in threshold for density cutoff
+     114           6 :   std::string errors, thresh_sw_str; parse("DENSITY_THRESHOLD",thresh_sw_str);
+     115           6 :   threshold_switch.set(thresh_sw_str, errors );
+     116           6 :   if( errors.length()>0 ) error("errors in DENSITY_THRESHOLD switching function : " + errors );
+     117           6 :   log.printf("  threshold on density of atoms in cylinder equals %s\n",threshold_switch.description().c_str() );
+     118             : 
+     119          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     120          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     121           6 :       double r=cylinder_sw(i,j).get_d0() + cylinder_sw(i,j).get_r0();
+     122           6 :       cell_volume(i,j)=binw_mat(i,j)*pi*r*r;
+     123             :     }
+     124             :   }
+     125             : 
+     126             :   // Find the largest sf cutoff
+     127           6 :   lsfmax=low_sf(0,0).get_dmax();
+     128           6 :   double sfmax=switchingFunction(0,0).get_dmax();
+     129           6 :   double rfmax=cylinder_sw(0,0).get_dmax();
+     130          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     131          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     132           6 :       double tsf=switchingFunction(i,j).get_dmax();
+     133           6 :       if( tsf>sfmax ) sfmax=tsf;
+     134           6 :       double rsf=cylinder_sw(i,j).get_dmax();
+     135           6 :       if( rsf>rfmax ) rfmax=rsf;
+     136           6 :       double lsf=low_sf(i,j).get_dmax();
+     137           6 :       if( lsf>lsfmax ) lsfmax=lsf;
+     138             :     }
+     139             :   }
+     140             :   // Get the width of the bead
+     141           6 :   HistogramBead bead; bead.isNotPeriodic();
+     142           6 :   bead.setKernelType( kerneltype ); bead.set( 0.0, 1.0, sigma );
+     143           6 :   beadrad = bead.getCutoff();
+     144             : 
+     145             :   // Set the link cell cutoff
+     146           6 :   log.printf("  setting cutoff %f \n", sfmax );
+     147           6 :   setLinkCellCutoff( sfmax, std::numeric_limits<double>::max() );
+     148             : 
+     149             :   double maxsize=0;
+     150          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     151          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     152           6 :       if( binw_mat(i,j)>maxsize ) maxsize=binw_mat(i,j);
+     153             :     }
+     154             :   }
+     155             :   // Set the maximum number of bins that we will need to compute
+     156           6 :   maxbins = std::floor( sfmax / maxsize ) + 1;
+     157             :   // Need to resize functions again here to ensure that vector sizes
+     158             :   // are set correctly in AdjacencyMatrixVessel
+     159           6 :   resizeFunctions();
+     160           6 : }
+     161             : 
+     162         100 : unsigned TopologyMatrix::getNumberOfQuantities() const {
+     163         100 :   return maxbins+3;
+     164             : }
+     165             : 
+     166          24 : void TopologyMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     167          24 :   plumed_assert( id<4 );
+     168          24 :   if( id==0 ) {
+     169           6 :     std::string errors; switchingFunction(j,i).set(desc[0],errors);
+     170           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     171           6 :     if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+     172          12 :     log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+     173          18 :   } else if( id==1 ) {
+     174           6 :     std::string errors; cylinder_sw(j,i).set(desc[0],errors);
+     175           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     176           6 :     if( j!=i) cylinder_sw(i,j).set(desc[0],errors);
+     177          12 :     log.printf("  there must be not atoms within the cylinder connections atoms of multicolvar groups %u th and %u th.  This cylinder has radius %s \n",i+1,j+1,(cylinder_sw(i,j).description()).c_str() );
+     178          12 :   } else if( id==2 ) {
+     179           6 :     std::string errors; low_sf(j,i).set(desc[0],errors);
+     180           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     181           6 :     if( j!=i ) low_sf(i,j).set(desc[0],errors);
+     182          12 :     log.printf("  %u th and %u th multicolvar groups must be further apart than %s\n",i+1,j+1,(low_sf(j,i).description()).c_str() );
+     183           6 :   } else if( id==3 ) {
+     184           6 :     Tools::convert( desc[0], binw_mat(j,i) );
+     185           6 :     if( i!=j ) binw_mat(i,j)=binw_mat(j,i);
+     186           6 :     log.printf("  cylinder for %u th and %u th multicolvar groups is split into bins of length %f \n",i,j,binw_mat(i,j) );
+     187             :   }
+     188          24 : }
+     189             : 
+     190       31203 : double TopologyMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     191       31203 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     192       62406 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) return 1.0;
+     193             :   return 0.0;
+     194             : }
+     195             : 
+     196        9616 : double TopologyMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     197        9616 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
+     198             : 
+     199             :   // Initialise to zero density on all bins
+     200       48200 :   for(unsigned bin=0; bin<maxbins; ++bin) myatoms.setValue(bin+1,0);
+     201             :   // Calculate whether or not atoms 1 and 2 are within cutoff (can use delta here as pbc are done in atom setup)
+     202        9616 :   Vector d1 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double d1_len = d1.modulo();
+     203        9616 :   d1 = d1 / d1_len;  // Convert vector into director
+     204        9616 :   AtomNumber a1 = myatoms.getAbsoluteIndex( 0 );
+     205        9616 :   AtomNumber a2 = myatoms.getAbsoluteIndex( 1 );
+     206   117927415 :   for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     207   117917799 :     AtomNumber a3 = myatoms.getAbsoluteIndex( i );
+     208   117917799 :     if( a3!=a1 && a3!=a2 ) calculateForThreeAtoms( i, d1, d1_len, bead, myatoms );
+     209             :   }
+     210             :   // std::vector<double> binvals( 1+maxbins ); for(unsigned i=1;i<maxbins;++i) binvals[i]=myatoms.getValue(i);
+     211             :   // unsigned ii; double fdf;
+     212             :   //std::cout<<"HELLO DENSITY "<<myatoms.getIndex(0)<<" "<<myatoms.getIndex(1)<<" "<<transformStoredValues( binvals, ii, fdf )<<std::endl;
+     213             : 
+     214             :   // Now find the element for which the density is maximal
+     215             :   unsigned vout=2; double max=myatoms.getValue( 2 );
+     216       38584 :   for(unsigned i=3; i<myatoms.getUnderlyingMultiValue().getNumberOfValues()-1; ++i) {
+     217       28968 :     if( myatoms.getValue(i)>max ) { max=myatoms.getValue(i); vout=i; }
+     218             :   }
+     219             :   // Calculate value and derivative of switching function between atoms 1 and 2
+     220             :   double dfuncl, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ),
+     221        9616 :                                          getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( d1_len, dfuncl );
+     222             :   // Transform the density
+     223        9616 :   double df, tsw = threshold_switch.calculate( max, df );
+     224        9616 :   if( !doNotCalculateDerivatives() ) {
+     225             :     // Factor of d1_len is required here because d1 is normalized
+     226          60 :     d1 *= d1_len;
+     227          60 :     addAtomDerivatives( 2+maxbins, 0, -dfuncl*d1, myatoms );
+     228          60 :     addAtomDerivatives( 2+maxbins, 1, dfuncl*d1, myatoms );
+     229          60 :     myatoms.addBoxDerivatives( 2+maxbins, (-dfuncl)*Tensor(d1,d1) );
+     230             :     // Update active atoms so that next bit works
+     231          60 :     updateActiveAtoms( myatoms );
+     232             :     // Now finish caclulation of derivatives
+     233             :     MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     234       13029 :     for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
+     235       12969 :       unsigned ider=myvals.getActiveIndex(jd);
+     236       12969 :       myvals.addDerivative( 1, ider, sw*df*max*myvals.getDerivative( vout, ider ) + tsw*myvals.getDerivative( 2+maxbins, ider ) );
+     237             :     }
+     238             :   }
+     239        9616 :   return sw*tsw;
+     240             : }
+     241             : 
+     242   117917799 : void TopologyMatrix::calculateForThreeAtoms( const unsigned& iat, const Vector& d1, const double& d1_len,
+     243             :     HistogramBead& bead, multicolvar::AtomValuePack& myatoms ) const {
+     244             :   // Calculate if there are atoms in the cylinder (can use delta here as pbc are done in atom setup)
+     245   117917799 :   Vector d2 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) );
+     246             :   // Now calculate projection of d2 on d1
+     247   117917799 :   double proj=dotProduct(d2,d1);
+     248             :   // This tells us if we are outside the end of the cylinder
+     249   117917799 :   double excess = proj - d1_len;
+     250             :   // Return if we are outside of the cylinder as calculated based on excess
+     251   175974631 :   if( excess>low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax() ) return;
+     252             :   // Find the length of the cylinder
+     253    81802351 :   double binw = binw_mat( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
+     254    81802351 :   double lcylinder = (std::floor( d1_len / binw ) + 1)*binw;
+     255             :   // Return if the projection is outside the length of interest
+     256    81802351 :   if( proj<-bead.getCutoff() || proj>(lcylinder+bead.getCutoff()) ) return;
+     257             : 
+     258             :   // Calculate the excess swiching function
+     259    23745519 :   double edf, eval = low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( excess, edf );
+     260             :   // Calculate the projection on the perpendicular distance from the center of the tube
+     261    23745519 :   double cm = d2.modulo2() - proj*proj;
+     262             : 
+     263             :   // Now calculate the density in the cylinder
+     264    23745519 :   if( cm<cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) {
+     265             :     double dfuncr, val = cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ),
+     266      104467 :                                       getBaseColvarNumber( myatoms.getIndex(1) ) ).calculateSqr( cm, dfuncr );
+     267      104467 :     double cellv = cell_volume( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
+     268      104467 :     Vector dc1, dc2, dc3, dd1, dd2, dd3, de1, de2, de3;
+     269      104467 :     if( !doNotCalculateDerivatives() ) {
+     270        4023 :       Tensor d1_a1;
+     271             :       // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
+     272        4023 :       d1_a1(0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1_len );   // dx/dx
+     273        4023 :       d1_a1(0,1) = (  d1[0]*d1[1]/d1_len );                 // dx/dy
+     274        4023 :       d1_a1(0,2) = (  d1[0]*d1[2]/d1_len );                 // dx/dz
+     275        4023 :       d1_a1(1,0) = (  d1[1]*d1[0]/d1_len );                 // dy/dx
+     276        4023 :       d1_a1(1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1_len );   // dy/dy
+     277        4023 :       d1_a1(1,2) = (  d1[1]*d1[2]/d1_len );
+     278        4023 :       d1_a1(2,0) = (  d1[2]*d1[0]/d1_len );
+     279        4023 :       d1_a1(2,1) = (  d1[2]*d1[1]/d1_len );
+     280        4023 :       d1_a1(2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1_len );
+     281             : 
+     282             :       // Calculate derivatives of dot product
+     283        4023 :       dd1 = matmul(d2, d1_a1) - d1;
+     284        4023 :       dd2 = matmul(d2, -d1_a1);
+     285        4023 :       dd3 = d1;
+     286             : 
+     287             :       // Calculate derivatives of cross product
+     288        4023 :       dc1 = dfuncr*( -d2 - proj*dd1 );
+     289        4023 :       dc2 = dfuncr*( -proj*dd2 );
+     290        4023 :       dc3 = dfuncr*( d2 - proj*dd3 );
+     291             : 
+     292             :       // Calculate derivatives of excess
+     293        4023 :       de1 = edf*excess*( dd1 + d1 );
+     294        4023 :       de2 = edf*excess*( dd2 - d1 );
+     295        4023 :       de3 = edf*excess*dd3;
+     296             :     }
+     297             : 
+     298      104467 :     Vector pos1 = myatoms.getPosition(0) + d1_len*d1;
+     299      104467 :     Vector pos2 = myatoms.getPosition(0) + d2;
+     300      104467 :     Vector g1derivf,g2derivf,lderivf; Tensor vir;
+     301      530381 :     for(unsigned bin=0; bin<maxbins; ++bin) {
+     302      425914 :       bead.set( bin*binw, (bin+1)*binw, sigma );
+     303      425914 :       if( proj<(bin*binw-bead.getCutoff()) || proj>binw*(bin+1)+bead.getCutoff() ) continue;
+     304      132418 :       double der, contr=bead.calculateWithCutoff( proj, der ) / cellv; der /= cellv;
+     305      132418 :       myatoms.addValue( 2+bin, contr*val*eval );
+     306             : 
+     307      132418 :       if( !doNotCalculateDerivatives() ) {
+     308        5835 :         g1derivf=contr*eval*dc1 + val*eval*der*dd1 + contr*val*de1;
+     309        5835 :         addAtomDerivatives( 2+bin, 0, g1derivf, myatoms );
+     310        5835 :         g2derivf=contr*eval*dc2 + val*eval*der*dd2 + contr*val*de2;
+     311        5835 :         addAtomDerivatives( 2+bin, 1, g2derivf, myatoms );
+     312        5835 :         lderivf=contr*eval*dc3 + val*eval*der*dd3 + contr*val*de3;
+     313        5835 :         addAtomDerivatives( 2+bin, iat, lderivf, myatoms );
+     314             :         // Virial
+     315        5835 :         vir = -Tensor( myatoms.getPosition(0), g1derivf ) - Tensor( pos1, g2derivf ) - Tensor( pos2, lderivf );
+     316        5835 :         myatoms.addBoxDerivatives( 2+bin, vir );
+     317             :       }
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322             : }
+     323             : }
+     324             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index-sort-f.html b/coverage/adjmat/index-sort-f.html new file mode 100644 index 0000000000..d98ff2c98c --- /dev/null +++ b/coverage/adjmat/index-sort-f.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1038117188.6 %
Date:2024-05-27 13:05: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
Sprint.cpp +
82.4%82.4%
+
82.4 %61 / 7487.5 %7 / 8
ClusterDistribution.cpp +
87.8%87.8%
+
87.8 %43 / 4987.5 %7 / 8
ClusterProperties.cpp +
100.0%
+
100.0 %30 / 3087.5 %7 / 8
DFSClustering.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
SMACMatrix.cpp +
100.0%
+
100.0 %35 / 3587.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.16
+
+ + + diff --git a/coverage/adjmat/index-sort-l.html b/coverage/adjmat/index-sort-l.html new file mode 100644 index 0000000000..7dc973e6e1 --- /dev/null +++ b/coverage/adjmat/index-sort-l.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1038117188.6 %
Date:2024-05-27 13:05: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 %35 / 3587.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.16
+
+ + + diff --git a/coverage/adjmat/index.html b/coverage/adjmat/index.html new file mode 100644 index 0000000000..2ef16cff0e --- /dev/null +++ b/coverage/adjmat/index.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1038117188.6 %
Date:2024-05-27 13:05: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 %35 / 3587.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.16
+
+ + + diff --git a/coverage/amber.png b/coverage/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE149
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.func.html b/coverage/analysis/AnalysisBase.cpp.func.html new file mode 100644 index 0000000000..a4f97cf446 --- /dev/null +++ b/coverage/analysis/AnalysisBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE149
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.gcov.html b/coverage/analysis/AnalysisBase.cpp.gcov.html new file mode 100644 index 0000000000..b34fd96711 --- /dev/null +++ b/coverage/analysis/AnalysisBase.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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         149 : void AnalysisBase::registerKeywords( Keywords& keys ) {
+      31         149 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         149 :   ActionWithValue::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      33         149 :   ActionWithArguments::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      34         447 :   ActionWithVessel::registerKeywords( keys ); keys.remove("TOL"); keys.reset_style("TIMINGS","hidden"); keys.isAnalysis();
+      35         298 :   keys.add("atoms-2","USE_OUTPUT_DATA_FROM","use the output of the analysis performed by this object as input to your new analysis object");
+      36         149 : }
+      37             : 
+      38         109 : AnalysisBase::AnalysisBase(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionPilot(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionAtomistic(ao),
+      43             :   ActionWithArguments(ao),
+      44             :   ActionWithVessel(ao),
+      45         109 :   my_input_data(NULL)
+      46             : {
+      47             :   // We have an if statement here so that this doesn't break with READ_DISSIMILARITIES
+      48         218 :   if( keywords.exists("USE_OUTPUT_DATA_FROM") ) {
+      49          78 :     std::string datastr; parse("USE_OUTPUT_DATA_FROM",datastr);
+      50         156 :     if( keywords.style("USE_OUTPUT_DATA_FROM","atoms") && datastr.length()==0 ) error("input analysis action was not specified use USE_OUTPUT_DATA_FROM");
+      51          78 :     if( datastr.length()>0 ) {
+      52          77 :       my_input_data=plumed.getActionSet().selectWithLabel<AnalysisBase*>( datastr );
+      53          77 :       log.printf("  performing analysis on output from %s \n",datastr.c_str() );
+      54          77 :       if( !my_input_data ) error("could not find analysis action named " + datastr );
+      55          77 :       addDependency( my_input_data );
+      56             :     }
+      57             :   }
+      58         109 : }
+      59             : 
+      60          50 : std::vector<std::string> AnalysisBase::getArgumentNames() {
+      61          50 :   std::vector<Value*> arg_p( getArgumentList() );
+      62          50 :   std::vector<std::string> argn( arg_p.size() );
+      63         124 :   for(unsigned i=0; i<arg_p.size(); ++i) {
+      64          74 :     plumed_assert( i<argn.size() && i<arg_p.size() );
+      65          74 :     argn[i]=arg_p[i]->getName();
+      66             :   }
+      67          50 :   return argn;
+      68           0 : }
+      69             : 
+      70          39 : void AnalysisBase::update() {
+      71          39 :   if( getStep()==0 || ( getStride()>0 && !onStep() ) ) return;
+      72             :   // And do the analysis
+      73          30 :   performAnalysis();
+      74             : }
+      75             : 
+      76         107 : void AnalysisBase::runFinalJobs() {
+      77         107 :   if( getStride()>0 ) return;
+      78          69 :   performAnalysis();
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.func-sort-c.html b/coverage/analysis/AnalysisBase.h.func-sort-c.html new file mode 100644 index 0000000000..d3a993a6cf --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.func.html b/coverage/analysis/AnalysisBase.h.func.html new file mode 100644 index 0000000000..32babcd6e7 --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.func.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.gcov.html b/coverage/analysis/AnalysisBase.h.gcov.html new file mode 100644 index 0000000000..13be683457 --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.gcov.html @@ -0,0 +1,256 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func-sort-c.html b/coverage/analysis/Average.cpp.func-sort-c.html new file mode 100644 index 0000000000..578ac1b83d --- /dev/null +++ b/coverage/analysis/Average.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func.html b/coverage/analysis/Average.cpp.func.html new file mode 100644 index 0000000000..c3f01373e2 --- /dev/null +++ b/coverage/analysis/Average.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe1076createERKNS_13ActionOptionsE3
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_120AverageRegisterMe107D2Ev4168
_ZN4PLMD8analysis7Average10isPeriodicEv0
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis7Average11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis7Average17accumulateAverageERNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.gcov.html b/coverage/analysis/Average.cpp.gcov.html new file mode 100644 index 0000000000..a831adbb16 --- /dev/null +++ b/coverage/analysis/Average.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(Average,"AVERAGE")
+     108             : 
+     109           5 : void Average::registerKeywords( Keywords& keys ) {
+     110           5 :   vesselbase::ActionWithAveraging::registerKeywords( keys ); keys.use("ARG");
+     111          10 :   keys.remove("SERIAL"); keys.remove("LOWMEM");
+     112           5 : }
+     113             : 
+     114           3 : Average::Average( const ActionOptions& ao ):
+     115             :   Action(ao),
+     116           3 :   ActionWithAveraging(ao)
+     117             : {
+     118           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.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.func-sort-c.html b/coverage/analysis/AverageVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..bd34c478f4 --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.func.html b/coverage/analysis/AverageVessel.cpp.func.html new file mode 100644 index 0000000000..439e416f7d --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.gcov.html b/coverage/analysis/AverageVessel.cpp.gcov.html new file mode 100644 index 0000000000..0b7da76ae0 --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.func-sort-c.html b/coverage/analysis/AverageVessel.h.func-sort-c.html new file mode 100644 index 0000000000..6b64a5a9ed --- /dev/null +++ b/coverage/analysis/AverageVessel.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.func.html b/coverage/analysis/AverageVessel.h.func.html new file mode 100644 index 0000000000..df8f838e9b --- /dev/null +++ b/coverage/analysis/AverageVessel.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.gcov.html b/coverage/analysis/AverageVessel.h.gcov.html new file mode 100644 index 0000000000..1cfeec216d --- /dev/null +++ b/coverage/analysis/AverageVessel.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func-sort-c.html b/coverage/analysis/Committor.cpp.func-sort-c.html new file mode 100644 index 0000000000..50473654b2 --- /dev/null +++ b/coverage/analysis/Committor.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe776createERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func.html b/coverage/analysis/Committor.cpp.func.html new file mode 100644 index 0000000000..90b00e25a8 --- /dev/null +++ b/coverage/analysis/Committor.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe776createERKNS_13ActionOptionsE9
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_121CommittorRegisterMe77D2Ev4168
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.gcov.html b/coverage/analysis/Committor.cpp.gcov.html new file mode 100644 index 0000000000..c384555e85 --- /dev/null +++ b/coverage/analysis/Committor.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + 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-05-27 13:05: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       12522 : PLUMED_REGISTER_ACTION(Committor,"COMMITTOR")
+      78             : 
+      79          11 : void Committor::registerKeywords( Keywords& keys ) {
+      80          11 :   Action::registerKeywords(keys);
+      81          11 :   ActionPilot::registerKeywords(keys);
+      82          11 :   ActionWithArguments::registerKeywords(keys);
+      83          11 :   keys.use("ARG");
+      84          22 :   keys.add("numbered", "BASIN_LL","List of lower limits for basin #");
+      85          22 :   keys.add("numbered", "BASIN_UL","List of upper limits for basin #");
+      86          33 :   keys.reset_style("BASIN_LL","compulsory"); keys.reset_style("BASIN_UL","compulsory");
+      87          22 :   keys.add("compulsory","STRIDE","1","the frequency with which the CVs are analyzed");
+      88          22 :   keys.add("optional","FILE","the name of the file on which to output the reached basin");
+      89          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      90          22 :   keys.addFlag("NOSTOP",false,"if true do not stop the simulation when reaching a basin but just keep track of it");
+      91          11 : }
+      92             : 
+      93           9 : Committor::Committor(const ActionOptions&ao):
+      94             :   Action(ao),
+      95             :   ActionPilot(ao),
+      96             :   ActionWithArguments(ao),
+      97           9 :   fmt("%f"),
+      98             :   basin(0),
+      99          18 :   doNotStop(false)
+     100             : {
+     101           9 :   ofile.link(*this);
+     102          18 :   parse("FILE",file);
+     103           9 :   if(file.length()>0) {
+     104           2 :     ofile.open(file);
+     105           2 :     log.printf("  on file %s\n",file.c_str());
+     106             :   } else {
+     107           7 :     log.printf("  on plumed log file\n");
+     108           7 :     ofile.link(log);
+     109             :   }
+     110           9 :   parse("FMT",fmt);
+     111           9 :   fmt=" "+fmt;
+     112           9 :   log.printf("  with format %s\n",fmt.c_str());
+     113             : 
+     114          13 :   for(unsigned b=1;; ++b ) {
+     115             :     std::vector<double> tmpl, tmpu;
+     116          22 :     parseNumberedVector("BASIN_LL", b, tmpl );
+     117          44 :     parseNumberedVector("BASIN_UL", b, tmpu );
+     118          22 :     if( tmpl.empty() && tmpu.empty() ) break;
+     119          13 :     if( tmpl.size()!=getNumberOfArguments()) error("Wrong number of values for BASIN_LL: they should be equal to the number of arguments");
+     120          13 :     if( tmpu.size()!=getNumberOfArguments()) error("Wrong number of values for BASIN_UL: they should be equal to the number of arguments");
+     121          13 :     lowerlimits.push_back(tmpl);
+     122          13 :     upperlimits.push_back(tmpu);
+     123          13 :     nbasins=b;
+     124          13 :   }
+     125             : 
+     126           9 :   parseFlag("NOSTOP", doNotStop);
+     127             : 
+     128           9 :   checkRead();
+     129             : 
+     130             : 
+     131          22 :   for(unsigned b=0; b<nbasins; b++) {
+     132          13 :     log.printf("  BASIN %u definition:\n", b+1);
+     133          32 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     134          19 :       if(lowerlimits[b][i]>upperlimits[b][i]) error("COMMITTOR: UPPER bounds must always be greater than LOWER bounds");
+     135          19 :       log.printf(" %f - %f\n", lowerlimits[b][i], upperlimits[b][i]);
+     136             :     }
+     137          13 :     if(doNotStop) log.printf(" COMMITOR will keep track of the visited basins without stopping the simulations\n");
+     138             :   }
+     139             : 
+     140          20 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) ofile.setupPrintValue( getPntrToArgument(i) );
+     141           9 : }
+     142             : 
+     143          30 : void Committor::calculate() {
+     144             :   std::vector<unsigned> inbasin;
+     145          30 :   inbasin.assign (nbasins,1);
+     146             : 
+     147             :   // check if current configuration belongs to a basin
+     148         106 :   for(unsigned b=0; b<nbasins; ++b) {
+     149         221 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     150         145 :       if(getArgument(i)>lowerlimits[b][i]&&getArgument(i)<upperlimits[b][i]) {
+     151             :         inbasin[b]*=1;
+     152             :       } else {
+     153          80 :         inbasin[b]*=0;
+     154             :       }
+     155             :     }
+     156             :   }
+     157             : 
+     158             :   // check in which basin we are if any and if this is the same or a new one
+     159             :   bool inonebasin = false;
+     160          71 :   for(unsigned b=0; b<nbasins; ++b) {
+     161          61 :     if(inbasin[b]==1) {
+     162          20 :       if(basin!=(b+1)) {
+     163          15 :         basin = b+1;
+     164          15 :         ofile.fmtField(" %f");
+     165          15 :         ofile.printField("time",getTime());
+     166          38 :         for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     167          23 :           ofile.fmtField(fmt);
+     168          23 :           ofile.printField( getPntrToArgument(i), getArgument(i) );
+     169             :         }
+     170          15 :         ofile.printField("basin", static_cast<int> (b+1));
+     171          15 :         ofile.printField();
+     172             :       }
+     173             :       inonebasin = true;
+     174             :       break;
+     175             :     }
+     176             :   }
+     177          10 :   if(!inonebasin) basin = 0;
+     178             : 
+     179             :   // then check if the simulation should be stopped
+     180          30 :   if(inonebasin&&(!doNotStop)) {
+     181           8 :     std::string num; Tools::convert( basin, num );
+     182           8 :     std::string str = "COMMITTED TO BASIN " + num;
+     183           8 :     ofile.addConstantField(str);
+     184           8 :     ofile.printField();
+     185           8 :     ofile.flush();
+     186           8 :     plumed.stop();
+     187             :   }
+     188          30 : }
+     189             : 
+     190             : }
+     191             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html b/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html new file mode 100644 index 0000000000..6dd82761e4 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.func.html b/coverage/analysis/DataCollectionObject.cpp.func.html new file mode 100644 index 0000000000..176f29e0fd --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.gcov.html b/coverage/analysis/DataCollectionObject.cpp.gcov.html new file mode 100644 index 0000000000..217951a030 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.func-sort-c.html b/coverage/analysis/DataCollectionObject.h.func-sort-c.html new file mode 100644 index 0000000000..2827d5c595 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.func.html b/coverage/analysis/DataCollectionObject.h.func.html new file mode 100644 index 0000000000..83ffb6fab8 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.gcov.html b/coverage/analysis/DataCollectionObject.h.gcov.html new file mode 100644 index 0000000000..0586f02e57 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.gcov.html @@ -0,0 +1,155 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..10e3b30a94 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE15
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60D2Ev4168
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..1a43cfb896 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe606createERKNS_13ActionOptionsE13
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_140EuclideanDissimilarityMatrixRegisterMe60D2Ev4168
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC1ERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..4fd76bd297 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-05-27 13:05: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       12530 : PLUMED_REGISTER_ACTION(EuclideanDissimilarityMatrix,"EUCLIDEAN_DISSIMILARITIES")
+      61             : 
+      62          15 : void EuclideanDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      63          45 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+      64          30 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+      65          30 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+      66          15 : }
+      67             : 
+      68          13 : EuclideanDissimilarityMatrix::EuclideanDissimilarityMatrix( const ActionOptions& ao ):
+      69             :   Action(ao),
+      70          13 :   AnalysisBase(ao)
+      71             : {
+      72          26 :   parse("METRIC",mtype); std::vector<AtomNumber> atoms;
+      73          13 :   if( my_input_data->getNumberOfAtoms()>0 ) {
+      74           6 :     parseAtomList("ATOMS",atoms);
+      75           3 :     if( atoms.size()!=0 ) {
+      76           0 :       mypdb.setAtomNumbers( atoms );
+      77           0 :       for(unsigned i=0; i<atoms.size(); ++i) {
+      78             :         bool found=false;
+      79           0 :         for(unsigned j=0; j<my_input_data->getAtomIndexes().size(); ++j) {
+      80           0 :           if( my_input_data->getAtomIndexes()[j]==atoms[i] ) { found=true; break; }
+      81             :         }
+      82           0 :         if( !found ) {
+      83           0 :           std::string num; Tools::convert( atoms[i].serial(), num );
+      84           0 :           error("atom number " + num + " is not stored in any action that has been input");
+      85             :         }
+      86             :       }
+      87           0 :       mypdb.addBlockEnd( atoms.size() );
+      88           3 :     } else if( getNumberOfArguments()==0 ) {
+      89           1 :       mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      90           1 :       mypdb.addBlockEnd( my_input_data->getAtomIndexes().size() );
+      91           1 :       if( mtype=="EUCLIDEAN" ) mtype="OPTIMAL";
+      92             :     }
+      93             :   }
+      94          13 :   log.printf("  measuring distances using %s metric \n",mtype.c_str() );
+      95          13 :   if( my_input_data->getArgumentNames().size()>0 ) {
+      96          12 :     if( getNumberOfArguments()==0 && atoms.size()==0 ) {
+      97          10 :       std::vector<std::string> argnames( my_input_data->getArgumentNames() );
+      98          10 :       mypdb.setArgumentNames( argnames ); requestArguments( my_input_data->getArgumentList() );
+      99          10 :     } else {
+     100           2 :       std::vector<Value*> myargs( getArguments() );
+     101           2 :       std::vector<std::string> inargnames( my_input_data->getArgumentNames() );
+     102           2 :       std::vector<std::string> argnames( myargs.size() );
+     103           6 :       for(unsigned i=0; i<myargs.size(); ++i) {
+     104           4 :         argnames[i]=myargs[i]->getName();
+     105             :         bool found=false;
+     106           6 :         for(unsigned j=0; j<inargnames.size(); ++j) {
+     107           6 :           if( argnames[i]==inargnames[j] ) { found=true; break; }
+     108             :         }
+     109           4 :         if( !found ) error("input named " + my_input_data->getLabel() + " does not store/calculate quantity named " + argnames[i] );
+     110             :       }
+     111           2 :       mypdb.setArgumentNames( argnames ); requestArguments( myargs );
+     112           2 :     }
+     113             :   }
+     114          13 : }
+     115             : 
+     116          20 : void EuclideanDissimilarityMatrix::performAnalysis() {
+     117             :   // Resize dissimilarities matrix and set all elements to zero
+     118          20 :   if( !usingLowMem() ) {
+     119          20 :     dissimilarities.resize( getNumberOfDataPoints(), getNumberOfDataPoints() ); dissimilarities=0;
+     120             :   }
+     121          20 : }
+     122             : 
+     123         413 : std::string EuclideanDissimilarityMatrix::getDissimilarityInstruction() const {
+     124         413 :   return "TYPE=" + mtype;
+     125             : }
+     126             : 
+     127      611659 : double EuclideanDissimilarityMatrix::getDissimilarity( const unsigned& iframe, const unsigned& jframe ) {
+     128             :   plumed_dbg_assert( iframe<getNumberOfDataPoints() && jframe<getNumberOfDataPoints() );
+     129      611659 :   if( !usingLowMem() ) {
+     130      611659 :     if( dissimilarities(iframe,jframe)>0. ) { return dissimilarities(iframe,jframe); }
+     131             :   }
+     132      256165 :   if( iframe!=jframe ) {
+     133             :     double dd;
+     134      255613 :     getStoredData( iframe, true ).transferDataToPDB( mypdb );
+     135      255613 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     136      255613 :     getStoredData( jframe, true ).transferDataToPDB( mypdb );
+     137      255613 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     138      255613 :     if( !usingLowMem() ) dd=dissimilarities(iframe,jframe) = dissimilarities(jframe,iframe) = distance( getPbc(), getArguments(), myref1.get(), myref2.get(), true );
+     139           0 :     else dd=distance( getPbc(), getArguments(), myref1.get(), myref2.get(), true );
+     140             :     return dd;
+     141      255613 :   }
+     142             :   return 0.0;
+     143             : }
+     144             : 
+     145             : }
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html new file mode 100644 index 0000000000..59fea92f1e --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func.html b/coverage/analysis/FarthestPointSampling.cpp.func.html new file mode 100644 index 0000000000..a98be8f5ea --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe476createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_133FarthestPointSamplingRegisterMe47D2Ev4168
_ZN4PLMD8analysis21FarthestPointSampling15selectLandmarksEv1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.gcov.html b/coverage/analysis/FarthestPointSampling.cpp.gcov.html new file mode 100644 index 0000000000..86e6e216a0 --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(FarthestPointSampling,"LANDMARK_SELECT_FPS")
+      48             : 
+      49           3 : void FarthestPointSampling::registerKeywords( Keywords& keys ) {
+      50           3 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           6 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           3 : }
+      53             : 
+      54           1 : FarthestPointSampling::FarthestPointSampling( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           1 :   LandmarkSelectionBase(ao)
+      57             : {
+      58           1 :   if( !dissimilaritiesWereSet() ) error("dissimilarities have not been calcualted in input action");
+      59           1 :   parse("SEED",seed);
+      60           1 : }
+      61             : 
+      62           1 : void FarthestPointSampling::selectLandmarks() {
+      63           1 :   std::vector<unsigned> landmarks( getNumberOfDataPoints() );
+      64             : 
+      65             :   // Select first point at random
+      66           1 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      67           1 :   landmarks[0] = std::floor( my_input_data->getNumberOfDataPoints()*rand );
+      68           1 :   selectFrame( landmarks[0] );
+      69             : 
+      70             :   // Now find distance to all other points (N.B. We can use squared distances here for speed)
+      71           1 :   Matrix<double> distances( getNumberOfDataPoints(), my_input_data->getNumberOfDataPoints() );
+      72          14 :   for(unsigned i=0; i<my_input_data->getNumberOfDataPoints(); ++i) distances(0,i) = my_input_data->getDissimilarity( landmarks[0], i );
+      73             : 
+      74             :   // Now find all other landmarks
+      75           3 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      76             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      77             :     double maxd=0;
+      78          28 :     for(unsigned j=0; j<my_input_data->getNumberOfDataPoints(); ++j) {
+      79          26 :       double mind=distances(0,j);
+      80          39 :       for(unsigned k=1; k<i; ++k) {
+      81          13 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+      82             :       }
+      83          26 :       if( mind>maxd ) { maxd=mind; landmarks[i]=j; }
+      84             :     }
+      85           2 :     selectFrame( landmarks[i] );
+      86          28 :     for(unsigned k=0; k<my_input_data->getNumberOfDataPoints(); ++k) distances(i,k) = my_input_data->getDissimilarity( landmarks[i], k );
+      87             :   }
+      88           1 : }
+      89             : 
+      90             : }
+      91             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func-sort-c.html b/coverage/analysis/Histogram.cpp.func-sort-c.html new file mode 100644 index 0000000000..348c6b6a20 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE36
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223D2Ev4168
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func.html b/coverage/analysis/Histogram.cpp.func.html new file mode 100644 index 0000000000..d2deffae4e --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe2236createERKNS_13ActionOptionsE34
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_122HistogramRegisterMe223D2Ev4168
_ZN4PLMD8analysis9Histogram10isPeriodicEv0
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD8analysis9Histogram17performOperationsERKb5
_ZN4PLMD8analysis9Histogram17turnOnDerivativesEv8
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.gcov.html b/coverage/analysis/Histogram.cpp.gcov.html new file mode 100644 index 0000000000..10a09dbf67 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.gcov.html @@ -0,0 +1,610 @@ + + + + + + + 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-05-27 13:05: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       12572 : PLUMED_REGISTER_ACTION(Histogram,"HISTOGRAM")
+     224             : 
+     225          36 : void Histogram::registerKeywords( Keywords& keys ) {
+     226          72 :   gridtools::ActionWithGrid::registerKeywords( keys ); keys.use("ARG"); keys.remove("NORMALIZATION");
+     227          72 :   keys.add("compulsory","NORMALIZATION","ndata","This controls how the data is normalized it can be set equal to true, false or ndata.  See above for an explanation");
+     228          72 :   keys.add("optional","DATA","input data from action with vessel and compute histogram");
+     229          72 :   keys.add("optional","VECTORS","input three dimensional vectors for computing histogram");
+     230          72 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+     231          72 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+     232          72 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     233          72 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     234          72 :   keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+     235          36 : }
+     236             : 
+     237          34 : Histogram::Histogram(const ActionOptions&ao):
+     238             :   Action(ao),
+     239             :   ActionWithGrid(ao),
+     240          34 :   ww(0.0),
+     241          34 :   in_apply(false),
+     242          34 :   mvectors(false)
+     243             : {
+     244             :   // Read in arguments
+     245          34 :   if( getNumberOfArguments()==0 ) {
+     246          16 :     std::string vlab; parse("VECTORS",vlab);
+     247           8 :     if( vlab.length()>0 ) {
+     248           2 :       ActionWithVessel* myv = plumed.getActionSet().selectWithLabel<ActionWithVessel*>( vlab );
+     249           2 :       if( !myv ) error("action labelled " + vlab + " does not exist or is not an ActionWithVessel");
+     250           2 :       myvessels.push_back( myv ); stashes.push_back( myv->buildDataStashes( NULL ) );
+     251           2 :       addDependency( myv ); mvectors=true;
+     252           2 :       if( myv->getNumberOfQuantities()!=5 ) error("can only compute histograms for three dimensional vectors");
+     253           2 :       log.printf("  for vector quantities calculated by %s \n", vlab.c_str() );
+     254             :     } else {
+     255          12 :       std::vector<std::string> mlab; parseVector("DATA",mlab);
+     256           6 :       if( mlab.size()>0 ) {
+     257          16 :         for(unsigned i=0; i<mlab.size(); ++i) {
+     258          10 :           ActionWithVessel* myv = plumed.getActionSet().selectWithLabel<ActionWithVessel*>( mlab[i] );
+     259          10 :           if( !myv ) error("action labelled " + mlab[i] + " does not exist or is not an ActionWithVessel");
+     260          10 :           myvessels.push_back( myv ); stashes.push_back( myv->buildDataStashes( NULL ) );
+     261             :           // log.printf("  for all base quantities calculated by %s \n",myvessel->getLabel().c_str() );
+     262             :           // Add the dependency
+     263          10 :           addDependency( myv );
+     264             :         }
+     265           6 :         unsigned nvals = myvessels[0]->getFullNumberOfTasks();
+     266          10 :         for(unsigned i=1; i<mlab.size(); ++i) {
+     267           4 :           if( nvals!=myvessels[i]->getFullNumberOfTasks() ) error("mismatched number of quantities calculated by actions input to histogram");
+     268             :         }
+     269           6 :         log.printf("  for all base quantities calculated by %s ", myvessels[0]->getLabel().c_str() );
+     270          10 :         for(unsigned i=1; i<mlab.size(); ++i) log.printf(", %s \n", myvessels[i]->getLabel().c_str() );
+     271           6 :         log.printf("\n");
+     272             :       } else {
+     273           0 :         error("input data is missing use ARG/VECTORS/DATA");
+     274             :       }
+     275           6 :     }
+     276             :   }
+     277             : 
+     278             :   // Read stuff for grid
+     279             :   unsigned narg = getNumberOfArguments();
+     280          34 :   if( myvessels.size()>0 ) narg=myvessels.size();
+     281             :   // Input of name and labels
+     282          34 :   std::string vstring="COMPONENTS=" + getLabel();
+     283          34 :   if( mvectors ) {
+     284             :     vstring += " COORDINATES=x,y,z PBC=F,F,F";
+     285          32 :   } else if( myvessels.size()>0 ) {
+     286           6 :     vstring += " COORDINATES=" + myvessels[0]->getLabel();
+     287          10 :     for(unsigned i=1; i<myvessels.size(); ++i) vstring +="," + myvessels[i]->getLabel();
+     288             :     // Input for PBC
+     289           6 :     if( myvessels[0]->isPeriodic() ) vstring+=" PBC=T";
+     290             :     else vstring+=" PBC=F";
+     291          10 :     for(unsigned i=1; i<myvessels.size(); ++i) {
+     292           4 :       if( myvessels[i]->isPeriodic() ) vstring+=",T";
+     293             :       else vstring+=",F";
+     294             :     }
+     295             :   } else {
+     296          26 :     vstring += " COORDINATES=" + getPntrToArgument(0)->getName();
+     297          35 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) vstring += "," + getPntrToArgument(i)->getName();
+     298             :     // Input for PBC
+     299          26 :     if( getPntrToArgument(0)->isPeriodic() ) vstring+=" PBC=T";
+     300             :     else vstring+=" PBC=F";
+     301          35 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     302           9 :       if( getPntrToArgument(i)->isPeriodic() ) vstring+=",T";
+     303             :       else vstring+=",F";
+     304             :     }
+     305             :   }
+     306             :   // And create the grid
+     307          34 :   auto grid=createGrid( "histogram", vstring );
+     308             :   // notice that createGrid also sets mygrid=grid.get()
+     309          68 :   if( mygrid->getType()=="flat" ) {
+     310          32 :     if( mvectors ) error("computing histogram for three dimensional vectors but grid is not of fibonacci type - use CONCENTRATION");
+     311          32 :     std::vector<std::string> gmin( narg ), gmax( narg );
+     312          96 :     parseVector("GRID_MIN",gmin); parseVector("GRID_MAX",gmax);
+     313          64 :     std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+     314          64 :     std::vector<double> gspacing; parseVector("GRID_SPACING",gspacing);
+     315          32 :     if( nbin.size()!=narg && gspacing.size()!=narg ) {
+     316           0 :       error("GRID_BIN or GRID_SPACING must be set");
+     317             :     }
+     318          32 :     mygrid->setBounds( gmin, gmax, nbin, gspacing );
+     319          32 :   } else {
+     320           4 :     std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+     321           2 :     if( nbin.size()!=1 ) error("should only be one index for number of bins with spherical grid");
+     322           4 :     if( mygrid->getType()=="fibonacci" ) mygrid->setupFibonacciGrid( nbin[0] );
+     323             :   }
+     324          34 :   myhist = dynamic_cast<gridtools::HistogramOnGrid*>( mygrid );
+     325          34 :   plumed_assert( myhist );
+     326          34 :   if( myvessels.size()>0 ) {
+     327             :     // Create a task list
+     328          72 :     for(unsigned i=0; i<myvessels[0]->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     329           8 :     setAveragingAction( std::move(grid), true );
+     330             :   } else if( storeThenAverage() ) {
+     331           7 :     setAveragingAction( std::move(grid), true );
+     332             :   } else {
+     333             :     // Create a task list
+     334        9256 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+     335          19 :     myhist->addOneKernelEachTimeOnly();
+     336          19 :     setAveragingAction( std::move(grid), myhist->noDiscreteKernels() );
+     337             :   }
+     338          34 :   checkRead();
+     339          68 : }
+     340             : 
+     341           8 : void Histogram::turnOnDerivatives() {
+     342           8 :   ActionWithGrid::turnOnDerivatives();
+     343             :   std::vector<AtomNumber> all_atoms, tmp_atoms;
+     344          20 :   for(unsigned i=0; i<myvessels.size(); ++i) {
+     345          12 :     multicolvar::MultiColvarBase* mbase=dynamic_cast<multicolvar::MultiColvarBase*>( myvessels[i] );
+     346          12 :     if( !mbase ) error("do not know how to get histogram derivatives for actions of type " + myvessels[i]->getName() );
+     347          12 :     tmp_atoms = mbase->getAbsoluteIndexes();
+     348         482 :     for(unsigned j=0; j<tmp_atoms.size(); ++j) all_atoms.push_back( tmp_atoms[j] );
+     349             :     // Make a tempory multi value so we can avoid vector resizing
+     350          12 :     stashes[i]->resizeTemporyMultiValues( 1 );
+     351             :   }
+     352           8 :   ActionAtomistic::requestAtoms( all_atoms );
+     353           8 :   finalForces.resize( 3*all_atoms.size() + 9 );
+     354           8 :   forcesToApply.resize( 3*all_atoms.size() + 9*myvessels.size() );
+     355             :   // And make sure we still have the dependencies which are cleared by requestAtoms
+     356          20 :   for(unsigned i=0; i<myvessels.size(); ++i) addDependency( myvessels[i] );
+     357             :   // And resize the histogram so that we have a place to store the forces
+     358           8 :   in_apply=true; mygrid->resize(); in_apply=false;
+     359           8 : }
+     360             : 
+     361         728 : unsigned Histogram::getNumberOfDerivatives() {
+     362         728 :   if( in_apply ) {
+     363             :     unsigned nder=0;
+     364         540 :     for(unsigned i=0; i<myvessels.size(); ++i) nder += myvessels[i]->getNumberOfDerivatives();
+     365             :     return nder;
+     366             :   }
+     367         506 :   return getNumberOfArguments();
+     368             : }
+     369             : 
+     370         462 : unsigned Histogram::getNumberOfQuantities() const {
+     371         462 :   if( mvectors ) return myvessels[0]->getNumberOfQuantities();
+     372         416 :   else if( myvessels.size()>0 ) return myvessels.size()+2;
+     373         294 :   return ActionWithAveraging::getNumberOfQuantities();
+     374             : }
+     375             : 
+     376         115 : void Histogram::prepareForAveraging() {
+     377         115 :   if( myvessels.size()>0 ) {
+     378          36 :     deactivateAllTasks(); double norm=0;
+     379         332 :     for(unsigned i=0; i<stashes[0]->getNumberOfStoredValues(); ++i) {
+     380         296 :       std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     381         296 :       stashes[0]->retrieveSequentialValue( i, false, cvals );
+     382         296 :       unsigned itask=myvessels[0]->getActiveTask(i); double tnorm = cvals[0];
+     383         444 :       for(unsigned j=1; j<myvessels.size(); ++j) {
+     384         148 :         if( myvessels[j]->getActiveTask(i)!=itask ) error("mismatched task identities in histogram suggests histogram is meaningless");
+     385         148 :         if( cvals.size()!=myvessels[j]->getNumberOfQuantities() ) cvals.resize( myvessels[j]->getNumberOfQuantities() );
+     386         148 :         stashes[j]->retrieveSequentialValue( i, false, cvals ); tnorm *= cvals[0];
+     387             :       }
+     388         296 :       norm += tnorm; taskFlags[i]=1;
+     389             :     }
+     390          36 :     lockContributors();
+     391             :     // Sort out normalization of histogram
+     392          36 :     if( !noNormalization() ) ww = cweight / norm;
+     393           5 :     else ww = cweight;
+     394             :   } else if( !storeThenAverage() ) {
+     395             :     // Now fetch the kernel and the active points
+     396          72 :     std::vector<double> point( getNumberOfArguments() );
+     397         180 :     for(unsigned i=0; i<point.size(); ++i) point[i]=getArgument(i);
+     398          72 :     unsigned num_neigh; std::vector<unsigned> neighbors(1);
+     399         144 :     kernel=myhist->getKernelAndNeighbors( point, num_neigh, neighbors );
+     400             : 
+     401          72 :     if( num_neigh>1 ) {
+     402             :       // Activate relevant tasks
+     403          67 :       deactivateAllTasks();
+     404       14975 :       for(unsigned i=0; i<num_neigh; ++i) taskFlags[neighbors[i]]=1;
+     405          67 :       lockContributors();
+     406             :     } else {
+     407             :       // This is used when we are not doing kernel density evaluation
+     408           5 :       mygrid->addToGridElement( neighbors[0], 0, cweight );
+     409             :     }
+     410             :   }
+     411         115 : }
+     412             : 
+     413           5 : void Histogram::performOperations( const bool& from_update ) { if( myvessels.size()==0 ) plumed_dbg_assert( !myhist->noDiscreteKernels() ); }
+     414             : 
+     415         135 : void Histogram::finishAveraging() {
+     416         135 :   if( myvessels.size()==0 ) kernel.reset();
+     417         135 : }
+     418             : 
+     419       15404 : void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
+     420       15404 :   if( mvectors ) {
+     421         140 :     std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     422         140 :     stashes[0]->retrieveSequentialValue( current, true, cvals );
+     423         560 :     for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.setValue( i-1, cvals[i] );
+     424         140 :     myvals.setValue( 0, cvals[0] ); myvals.setValue( myvessels[0]->getNumberOfQuantities() - 1, ww );
+     425         140 :     if( in_apply ) {
+     426          50 :       MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     427          99 :       if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     428          49 :           tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     429           1 :         tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     430          50 :       stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), true, tmpval );
+     431         350 :       for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     432         300 :         unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 0, jder, tmpval.getDerivative(0, jder) );
+     433        1200 :         for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.addDerivative( i-1, jder, tmpval.getDerivative(i, jder) );
+     434             :       }
+     435             :       myvals.updateDynamicList();
+     436             :     }
+     437       15264 :   } else if( myvessels.size()>0 ) {
+     438         356 :     std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     439         356 :     stashes[0]->retrieveSequentialValue( current, false, cvals );
+     440         356 :     unsigned derbase=0; double totweight=cvals[0], tnorm = cvals[0]; myvals.setValue( 1, cvals[1] );
+     441             :     // Get the derivatives as well if we are in apply
+     442         356 :     if( in_apply ) {
+     443             :       // This bit gets the total weight
+     444         150 :       double weight0 = cvals[0];  // Store the current weight
+     445         250 :       for(unsigned j=1; j<myvessels.size(); ++j) {
+     446         100 :         stashes[j]->retrieveSequentialValue( current, false, cvals ); totweight *= cvals[0];
+     447             :       }
+     448             :       // And this bit the derivatives
+     449         150 :       MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     450         297 :       if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     451         147 :           tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     452           3 :         tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     453         150 :       stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), false, tmpval );
+     454       31590 :       for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     455       31440 :         unsigned jder=tmpval.getActiveIndex(j);
+     456       31440 :         myvals.addDerivative( 1, jder, tmpval.getDerivative(1,jder) );
+     457       31440 :         myvals.addDerivative( 0, jder, (totweight/weight0)*tmpval.getDerivative(0,jder) );
+     458             :       }
+     459         150 :       derbase = myvessels[0]->getNumberOfDerivatives();
+     460             :     }
+     461         604 :     for(unsigned i=1; i<myvessels.size(); ++i) {
+     462         248 :       if( cvals.size()!=myvessels[i]->getNumberOfQuantities() ) cvals.resize( myvessels[i]->getNumberOfQuantities() );
+     463         248 :       stashes[i]->retrieveSequentialValue( current, false, cvals );
+     464         248 :       tnorm *= cvals[0]; myvals.setValue( 1+i, cvals[1] );
+     465             :       // Get the derivatives as well if we are in apply
+     466         248 :       if( in_apply ) {
+     467         100 :         MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     468         200 :         if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     469         100 :             tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     470           0 :           tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     471         100 :         stashes[i]->retrieveDerivatives( stashes[i]->getTrueIndex(current), false, tmpval );
+     472        1090 :         for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     473             :           unsigned jder=tmpval.getActiveIndex(j);
+     474         990 :           myvals.addDerivative( 1+i, derbase+jder, tmpval.getDerivative(1,jder) );
+     475         990 :           myvals.addDerivative( 0, derbase+jder, (totweight/cvals[0])*tmpval.getDerivative(0,jder) );
+     476             :         }
+     477         100 :         derbase += myvessels[i]->getNumberOfDerivatives();
+     478             :       }
+     479             :     }
+     480         356 :     myvals.setValue( 0, tnorm ); myvals.setValue( 1+myvessels.size(), ww );
+     481         356 :     if( in_apply ) myvals.updateDynamicList();
+     482             :   } else {
+     483       14908 :     plumed_assert( !in_apply );
+     484       14908 :     std::vector<std::unique_ptr<Value>> vv( myhist->getVectorOfValues() );
+     485       14908 :     std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() );
+     486             :     // Retrieve the location of the grid point at which we are evaluating the kernel
+     487       14908 :     mygrid->getGridPointCoordinates( current, val );
+     488       14908 :     if( kernel ) {
+     489       54492 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] );
+     490             :       // Evaluate the histogram at the relevant grid point and set the values
+     491       29816 :       double vvh = kernel->evaluate( Tools::unique2raw(vv), der,true); myvals.setValue( 1, vvh );
+     492             :     } else {
+     493           0 :       plumed_merror("normalisation of vectors does not work with arguments and spherical grids");
+     494             :       // Evalulate dot product
+     495             :       double dot=0; for(unsigned j=0; j<getNumberOfArguments(); ++j) { dot+=val[j]*getArgument(j); der[j]=val[j]; }
+     496             :       // Von misses distribution for concentration parameter
+     497             :       double newval = (myhist->von_misses_norm)*std::exp( (myhist->von_misses_concentration)*dot ); myvals.setValue( 1, newval );
+     498             :       // And final derivatives
+     499             :       for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval;
+     500             :     }
+     501             :     // Set the derivatives and delete the vector of values
+     502       54492 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); }
+     503       14908 :   }
+     504       15404 : }
+     505             : 
+     506         133 : void Histogram::apply() {
+     507         133 :   if( !myhist->wasForced() ) return ;
+     508          20 :   in_apply=true;
+     509             :   // Run the loop to calculate the forces
+     510          20 :   runAllTasks(); finishAveraging();
+     511             :   // We now need to retrieve the buffer and set the forces on the atoms
+     512          20 :   myhist->applyForce( forcesToApply );
+     513             :   // Now make the forces make sense for the virial
+     514          20 :   unsigned fbase=0, tbase=0, vbase = getNumberOfDerivatives() - myvessels.size()*9;
+     515         200 :   for(unsigned i=vbase; i<vbase+9; ++i) finalForces[i]=0.0;
+     516          50 :   for(unsigned i=0; i<myvessels.size(); ++i) {
+     517        3555 :     for(unsigned j=0; j<myvessels[i]->getNumberOfDerivatives()-9; ++j) {
+     518        3525 :       finalForces[fbase + j] = forcesToApply[tbase + j];
+     519             :     }
+     520             :     unsigned k=0;
+     521         300 :     for(unsigned j=myvessels[i]->getNumberOfDerivatives()-9; j<myvessels[i]->getNumberOfDerivatives(); ++j) {
+     522         270 :       finalForces[vbase + k] += forcesToApply[tbase + j]; k++;
+     523             :     }
+     524          30 :     fbase += myvessels[i]->getNumberOfDerivatives() - 9;
+     525          30 :     tbase += myvessels[i]->getNumberOfDerivatives();
+     526             :   }
+     527             :   // And set the final forces on the atoms
+     528          20 :   setForcesOnAtoms( finalForces );
+     529             :   // Reset everything for next regular loop
+     530          20 :   in_apply=false;
+     531             : }
+     532             : 
+     533             : }
+     534             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html b/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..784bbb751d --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.func.html b/coverage/analysis/LandmarkSelectionBase.cpp.func.html new file mode 100644 index 0000000000..2996341c88 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html b/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html new file mode 100644 index 0000000000..32680e4e07 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + 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-05-27 13:05: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          20 : void LandmarkSelectionBase::registerKeywords( Keywords& keys ) {
+      28          20 :   AnalysisBase::registerKeywords( keys );
+      29          40 :   keys.add("compulsory","NLANDMARKS","the number of landmarks that you would like to select");
+      30          40 :   keys.addFlag("NOVORONOI",false,"do not do a Voronoi analysis of the data to determine weights of final points");
+      31          40 :   keys.addFlag("IGNORE_WEIGHTS",false,"ignore the weights in the underlying analysis object");
+      32          20 : }
+      33             : 
+      34          10 : LandmarkSelectionBase::LandmarkSelectionBase( const ActionOptions& ao ):
+      35             :   Action(ao),
+      36             :   AnalysisBase(ao),
+      37          10 :   nlandmarks(0)
+      38             : {
+      39          29 :   if( keywords.exists("NLANDMARKS") ) parse("NLANDMARKS",nlandmarks);
+      40          10 :   log.printf("  selecting %u landmark points \n",nlandmarks);
+      41          10 :   lweights.resize( nlandmarks );
+      42             : 
+      43          10 :   parseFlag("NOVORONOI",novoronoi);
+      44          18 :   if( !novoronoi && !dissimilaritiesWereSet() ) error("cannot calculate voronoi weights without dissimilarity mesaure");
+      45             : 
+      46          10 :   if( !novoronoi ) log.printf("  ascribing weights to landmarks using voronoi analysis\n");
+      47           2 :   else log.printf("  ascribing weights of original points to landmark\n");
+      48          10 : }
+      49             : 
+      50         291 : void LandmarkSelectionBase::selectFrame( const unsigned& iframe ) {
+      51         291 :   landmark_indices.push_back( iframe );
+      52         291 : }
+      53             : 
+      54          12 : void LandmarkSelectionBase::performAnalysis() {
+      55          12 :   landmark_indices.resize(0); selectLandmarks();
+      56             :   plumed_dbg_assert( nlandmarks==getNumberOfDataPoints() );
+      57          12 :   if( lweights.size()!=nlandmarks ) lweights.resize( nlandmarks );
+      58             : 
+      59          12 :   if( !novoronoi ) {
+      60           8 :     lweights.assign(lweights.size(),0.0);
+      61           8 :     std::vector<unsigned> tmpass( my_input_data->getNumberOfDataPoints() );
+      62           8 :     voronoiAnalysis( landmark_indices, lweights, tmpass );
+      63             :   } else {
+      64          18 :     for(unsigned i=0; i<nlandmarks; ++i) lweights[i]=my_input_data->getWeight( landmark_indices[i] );
+      65             :   }
+      66          12 : }
+      67             : 
+      68           8 : void LandmarkSelectionBase::voronoiAnalysis( const std::vector<unsigned>& myindices, std::vector<double>& lweights, std::vector<unsigned>& assignments ) const {
+      69             :   plumed_dbg_assert( myindices.size()==lweights.size() && assignments.size()==my_input_data->getNumberOfDataPoints() );
+      70           8 :   lweights.assign( lweights.size(), 0 );
+      71           8 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      72         567 :   for(unsigned i=rank; i<my_input_data->getNumberOfDataPoints(); i+=size) {
+      73         559 :     assignments[i]=0;
+      74         559 :     double mindist=my_input_data->getDissimilarity( i, myindices[0] );
+      75      125239 :     for(unsigned j=1; j<nlandmarks; ++j) {
+      76      124680 :       double dist=my_input_data->getDissimilarity( i, myindices[j] );
+      77      124680 :       if( dist<mindist ) { mindist=dist; assignments[i]=j; }
+      78             :     }
+      79         559 :     lweights[ assignments[i] ] += my_input_data->getWeight(i);
+      80             :   }
+      81           8 :   comm.Sum( &lweights[0], lweights.size() );
+      82           8 :   comm.Sum( &assignments[0], assignments.size() );
+      83           8 : }
+      84             : 
+      85             : }
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html b/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html new file mode 100644 index 0000000000..a58e3a5103 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.func.html b/coverage/analysis/LandmarkSelectionBase.h.func.html new file mode 100644 index 0000000000..36626689f4 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.gcov.html b/coverage/analysis/LandmarkSelectionBase.h.gcov.html new file mode 100644 index 0000000000..3754d2783e --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.gcov.html @@ -0,0 +1,169 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html b/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html new file mode 100644 index 0000000000..5166bdd72b --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.func.html b/coverage/analysis/LandmarkStaged.cpp.func.html new file mode 100644 index 0000000000..99f1efe2ab --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe506createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_126LandmarkStagedRegisterMe50D2Ev4168
_ZN4PLMD8analysis14LandmarkStaged15selectLandmarksEv0
_ZN4PLMD8analysis14LandmarkStaged16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis14LandmarkStagedC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStagedC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.gcov.html b/coverage/analysis/LandmarkStaged.cpp.gcov.html new file mode 100644 index 0000000000..a1f0a1e7e5 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(LandmarkStaged,"LANDMARK_SELECT_STAGED")
+      51             : 
+      52           2 : void LandmarkStaged::registerKeywords( Keywords& keys ) {
+      53           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      54           4 :   keys.add("compulsory","GAMMA","the gamma parameter to be used in weights");
+      55           4 :   keys.add("compulsory","SEED","1234","a random number seed");
+      56           2 : }
+      57             : 
+      58           0 : LandmarkStaged::LandmarkStaged( const ActionOptions& ao ):
+      59             :   Action(ao),
+      60           0 :   LandmarkSelectionBase(ao)
+      61             : {
+      62           0 :   parse("SEED",seed); parse("GAMMA",gamma);
+      63           0 :   log.printf("  probability of selecting voronoi polyhedra equal to exp(-weight/%f) \n", gamma );
+      64           0 : }
+      65             : 
+      66           0 : void LandmarkStaged::selectLandmarks() {
+      67           0 :   unsigned int n = getNumberOfDataPoints(); // The number of landmarks to pick
+      68           0 :   unsigned int N = my_input_data->getNumberOfDataPoints();  // The total number of frames we can choose from
+      69           0 :   unsigned int m = static_cast<int>( std::sqrt(n*N) );
+      70           0 :   std::vector<unsigned> fpslandmarks(m);
+      71             :   // Select first point at random
+      72           0 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      73           0 :   fpslandmarks[0] = std::floor( N*rand );
+      74             : 
+      75             :   // using FPS we want to find m landmarks where m = sqrt(nN)
+      76             :   // Now find distance to all other points
+      77             :   Matrix<double> distances( m, N );
+      78           0 :   for(unsigned int i=0; i<N; ++i) {
+      79           0 :     distances(0,i) = my_input_data->getDissimilarity( fpslandmarks[0], i );
+      80             :   }
+      81             : 
+      82             :   // Now find all other landmarks
+      83           0 :   for(unsigned i=1; i<m; ++i) {
+      84             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      85             :     double maxd=0;
+      86           0 :     for(unsigned j=0; j<N; ++j) {
+      87           0 :       double mind=distances(0,j);
+      88           0 :       for(unsigned k=1; k<i; ++k) {
+      89           0 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+      90             :       }
+      91           0 :       if( mind>maxd ) { maxd=mind; fpslandmarks[i]=j; }
+      92             :     }
+      93           0 :     for(unsigned k=0; k<N; ++k) distances(i,k) = my_input_data->getDissimilarity( fpslandmarks[i], k );
+      94             :   }
+      95             : 
+      96             :   // Initial FPS selection of m landmarks completed
+      97             :   // Now find voronoi weights of these m points
+      98           0 :   std::vector<unsigned> poly_assign( N );
+      99           0 :   std::vector<double> weights( m, 0 );
+     100           0 :   voronoiAnalysis( fpslandmarks, weights, poly_assign );
+     101             : 
+     102             :   //Calculate total weight of voronoi polyhedras
+     103           0 :   double vweight=0; for(unsigned i=0; i<m; i++) vweight += std::exp( -weights[i] / gamma );
+     104             : 
+     105           0 :   std::vector<bool> selected(N, false); unsigned ncount=0;
+     106           0 :   while ( ncount<n) {
+     107             : //  generate random number and check which point it belongs to. select only it was not selected before
+     108           0 :     double rand = vweight*random.RandU01();
+     109             :     double running_vweight=0;
+     110           0 :     for(unsigned jpoly=0; jpoly<m; ++jpoly) {
+     111           0 :       running_vweight+=std::exp( -weights[jpoly] / gamma );
+     112           0 :       if( running_vweight>=rand ) {
+     113             :         double tweight=0;
+     114           0 :         for(unsigned i=0; i<poly_assign.size(); ++i) {
+     115           0 :           if( poly_assign[i]==jpoly ) tweight += getWeight( i );
+     116             :         }
+     117           0 :         double rand_poly = tweight*random.RandU01();
+     118             :         double running_tweight=0;
+     119           0 :         for(unsigned i=0; i<N; ++i) {
+     120           0 :           if( poly_assign[i]==jpoly ) {
+     121           0 :             running_tweight += getWeight( i );
+     122           0 :             if( running_tweight>=rand_poly && !selected[i] ) {
+     123           0 :               selectFrame(i); selected[i]=true; ncount++; break;
+     124           0 :             } else if( running_tweight>=rand_poly ) {
+     125             :               break;
+     126             :             }
+     127             :           }
+     128             :         }
+     129             :       }
+     130             :     }
+     131             :   }
+     132           0 : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html b/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html new file mode 100644 index 0000000000..a71e8fca79 --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE22
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.func.html b/coverage/analysis/OutputColvarFile.cpp.func.html new file mode 100644 index 0000000000..5b78d2b34c --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe606createERKNS_13ActionOptionsE20
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_128OutputColvarFileRegisterMe60D2Ev4168
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
_ZN4PLMD8analysis16OutputColvarFile16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD8analysis16OutputColvarFileC1ERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis16OutputColvarFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.gcov.html b/coverage/analysis/OutputColvarFile.cpp.gcov.html new file mode 100644 index 0000000000..3c0748baf0 --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + 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-05-27 13:05: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       12544 : PLUMED_REGISTER_ACTION(OutputColvarFile,"OUTPUT_ANALYSIS_DATA_TO_COLVAR")
+      61             : 
+      62          22 : void OutputColvarFile::registerKeywords( Keywords& keys ) {
+      63          22 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG");
+      64          44 :   keys.add("compulsory","FILE","the name of the file to output to");
+      65          44 :   keys.add("compulsory","REPLICA","0","the replicas for which you would like to output this information");
+      66          44 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      67          44 :   keys.add("optional","FMT","the format to output the data using");
+      68          22 : }
+      69             : 
+      70          20 : OutputColvarFile::OutputColvarFile( const ActionOptions& ao ):
+      71             :   Action(ao),
+      72             :   AnalysisBase(ao),
+      73          40 :   fmt("%f"),
+      74          20 :   output_for_all_replicas(false)
+      75             : {
+      76          60 :   parse("FILE",filename); parse("FMT",fmt);
+      77          40 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      78          20 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      79          20 :   if( getArguments().size()==0 ) {
+      80          12 :     std::vector<std::string> tmp_vals( my_input_data->getArgumentNames() );
+      81          30 :     req_vals.resize( tmp_vals.size() ); for(unsigned i=0; i<tmp_vals.size(); ++i) req_vals[i]=tmp_vals[i];
+      82          12 :   } else {
+      83          32 :     req_vals.resize( getArguments().size() ); for(unsigned i=0; i<req_vals.size(); ++i) req_vals[i]=getPntrToArgument(i)->getName();
+      84             :   }
+      85          20 :   if( req_vals.size()==0 ) {
+      86           6 :     log.printf("  outputting weights from input action \n");
+      87             :   } else {
+      88          14 :     log.printf("  outputting %s", req_vals[0].c_str() );
+      89          22 :     for(unsigned i=1; i<req_vals.size(); ++i) log.printf(",", req_vals[i].c_str() );
+      90          14 :     log.printf("\n");
+      91             :   }
+      92          40 :   std::string rep_data; parse("REPLICA",rep_data);
+      93          20 :   if( rep_data=="all" ) output_for_all_replicas=true;
+      94          20 :   else { preps.resize(1); Tools::convert( rep_data, preps[0] ); }
+      95          20 :   if( output_for_all_replicas ) log.printf("  outputting files for all replicas \n");
+      96             :   else {
+      97          20 :     log.printf("  outputting data for replicas ");
+      98          40 :     for(unsigned i=0; i<preps.size(); ++i) log.printf("%d ", preps[i] );
+      99             :   }
+     100          20 : }
+     101             : 
+     102          24 : void OutputColvarFile::performAnalysis() {
+     103          24 :   if( !output_for_all_replicas ) {
+     104          24 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+     105          29 :     for(unsigned i=0; i<preps.size(); ++i) {
+     106          24 :       if( myrep==preps[i] ) { found=true; break; }
+     107             :     }
+     108          24 :     if( !found ) return;
+     109             :   }
+     110             :   // Output the embedding as long lists of data
+     111          19 :   OFile gfile; gfile.link(*this);
+     112          19 :   gfile.setBackupString("analysis");
+     113          19 :   gfile.fmtField(fmt+" ");
+     114          19 :   gfile.open( filename );
+     115             : 
+     116             :   // Print embedding coordinates
+     117        2599 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+     118        2580 :     const DataCollectionObject& mydata=getStoredData(i, false);
+     119        6989 :     for(unsigned j=0; j<req_vals.size(); ++j) gfile.printField( req_vals[j], mydata.getArgumentValue(req_vals[j]) );
+     120        5160 :     gfile.printField( "weight", getWeight(i) ); gfile.printField();
+     121             :   }
+     122          19 :   gfile.close();
+     123          19 : }
+     124             : 
+     125             : }
+     126             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html b/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html new file mode 100644 index 0000000000..97a72fc8d7 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.func.html b/coverage/analysis/OutputPDBFile.cpp.func.html new file mode 100644 index 0000000000..ea844466c7 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe566createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_125OutputPDBFileRegisterMe56D2Ev4168
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis13OutputPDBFileC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis13OutputPDBFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.gcov.html b/coverage/analysis/OutputPDBFile.cpp.gcov.html new file mode 100644 index 0000000000..0bee3014a4 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + LCOV - plumed test coverage - analysis/OutputPDBFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputPDBFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293096.7 %
Date:2024-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(OutputPDBFile,"OUTPUT_ANALYSIS_DATA_TO_PDB")
+      57             : 
+      58           8 : void OutputPDBFile::registerKeywords( Keywords& keys ) {
+      59           8 :   AnalysisBase::registerKeywords( keys );
+      60          16 :   keys.add("compulsory","FILE","the name of the file to output to");
+      61          16 :   keys.add("optional","FMT","the format to use in the output file");
+      62          16 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      63           8 : }
+      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.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..645ba89fb8 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..2ccfecf089 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe506createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_136PrintDissimilarityMatrixRegisterMe50D2Ev4168
_ZN4PLMD8analysis24PrintDissimilarityMatrix15performAnalysisEv9
_ZN4PLMD8analysis24PrintDissimilarityMatrix16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis24PrintDissimilarityMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis24PrintDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..d90b826a47 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(PrintDissimilarityMatrix,"PRINT_DISSIMILARITY_MATRIX")
+      51             : 
+      52          10 : void PrintDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      53          10 :   AnalysisBase::registerKeywords( keys );
+      54          20 :   keys.add("compulsory","FILE","name of file on which to output the data");
+      55          20 :   keys.add("optional","FMT","the format to use for the output of numbers");
+      56          20 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      57          10 : }
+      58             : 
+      59           8 : PrintDissimilarityMatrix::PrintDissimilarityMatrix( const ActionOptions& ao ):
+      60             :   Action(ao),
+      61             :   AnalysisBase(ao),
+      62           8 :   fmt("%f")
+      63             : {
+      64           8 :   if( !dissimilaritiesWereSet() ) error("dissimilarities have not been set in base classes");
+      65             : 
+      66          24 :   parse("FILE",fname); parse("FMT",fmt);
+      67          16 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(fname); }
+      68           8 :   log.printf("  printing to file named %s with formt %s \n",fname.c_str(), fmt.c_str() );
+      69           8 : }
+      70             : 
+      71           9 : void PrintDissimilarityMatrix::performAnalysis() {
+      72           9 :   std::string ofmt=" "+fmt;
+      73          18 :   OFile ofile; ofile.setBackupString("analysis"); ofile.open(fname);
+      74          69 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+      75         574 :     for(unsigned j=0; j<getNumberOfDataPoints(); ++j) ofile.printf(ofmt.c_str(), sqrt( my_input_data->getDissimilarity( i,j ) ) );
+      76          60 :     ofile.printf("\n");
+      77             :   }
+      78           9 :   ofile.close();
+      79          18 : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html b/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html new file mode 100644 index 0000000000..b3908f507b --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE32
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39D2Ev4168
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.func.html b/coverage/analysis/ReadAnalysisFrames.cpp.func.html new file mode 100644 index 0000000000..8de0060698 --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe396createERKNS_13ActionOptionsE30
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_130ReadAnalysisFramesRegisterMe39D2Ev4168
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis18ReadAnalysisFrames16calculateWeightsEv26
_ZN4PLMD8analysis18ReadAnalysisFrames16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
_ZN4PLMD8analysis18ReadAnalysisFramesC1ERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFramesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis18ReadAnalysisFrames14getAtomIndexesEv12
_ZNK4PLMD8analysis18ReadAnalysisFrames27getDissimilarityInstructionB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html b/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html new file mode 100644 index 0000000000..e8b4998dcb --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-05-27 13:05: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       12564 : PLUMED_REGISTER_ACTION(ReadAnalysisFrames,"COLLECT_FRAMES")
+      40             : 
+      41          32 : void ReadAnalysisFrames::registerKeywords( Keywords& keys ) {
+      42          32 :   AnalysisBase::registerKeywords( keys );
+      43          96 :   keys.remove("SERIAL"); keys.remove("USE_OUTPUT_DATA_FROM"); keys.use("ARG");
+      44          64 :   keys.add("atoms-1","ATOMS","the atoms whose positions we are tracking for the purpose of analyzing the data");
+      45          64 :   keys.add("atoms-1","STRIDE","the frequency with which data should be stored for analysis.  By default data is collected on every step");
+      46          64 :   keys.add("compulsory","CLEAR","0","the frequency with which data should all be deleted and restarted");
+      47          64 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      48          32 :   ActionWithValue::useCustomisableComponents( keys );
+      49          32 : }
+      50             : 
+      51          30 : ReadAnalysisFrames::ReadAnalysisFrames( const ActionOptions& ao ):
+      52             :   Action(ao),
+      53             :   AnalysisBase(ao),
+      54          30 :   clearonnextstep(false),
+      55          30 :   wham_pointer(NULL),
+      56          30 :   weights_calculated(false)
+      57             : {
+      58          30 :   parse("CLEAR",clearstride);
+      59          30 :   if( clearstride!=0 ) log.printf("  clearing stored data every %u steps\n",clearstride);
+      60             :   // Get the names of the argumes
+      61          30 :   argument_names.resize( getNumberOfArguments() );
+      62          64 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i]=getPntrToArgument(i)->getName();
+      63             :   // Find the atom numbers to read in
+      64          60 :   parseAtomList("ATOMS",atom_numbers);
+      65          30 :   if( atom_numbers.size()>0 ) {
+      66           5 :     log.printf("  monitoring positions of atoms ");
+      67          79 :     for(unsigned i=0; i<atom_numbers.size(); ++i) log.printf("%d ",atom_numbers[i].serial() );
+      68           5 :     log.printf("\n"); requestAtoms(atom_numbers);
+      69             :   }
+      70             : 
+      71             :   // Get stuff for any reweighting that should go on
+      72          60 :   std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr);
+      73          30 :   if( wwstr.size()>0 ) log.printf("  reweighting using weights from ");
+      74          30 :   std::vector<Value*> arg( ActionWithArguments::getArguments() );
+      75          42 :   for(unsigned i=0; i<wwstr.size(); ++i) {
+      76          12 :     ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]);
+      77          12 :     if( !val ) error("could not find value named");
+      78          12 :     weight_vals.push_back( val->copyOutput(val->getLabel()) );
+      79          12 :     arg.push_back( val->copyOutput(val->getLabel()) );
+      80          12 :     log.printf("%s ",wwstr[i].c_str() );
+      81             :   }
+      82          30 :   if( wwstr.size()>0 ) {
+      83          12 :     log.printf("\n");
+      84          12 :     wham_pointer = dynamic_cast<bias::ReweightBase*>( weight_vals[0]->getPntrToAction() );
+      85          12 :     if( !wham_pointer ) wham_pointer = NULL;
+      86          12 :     else if( !wham_pointer->buildsWeightStore() ) wham_pointer = NULL;
+      87          12 :     if( wham_pointer && weight_vals.size()!=1 ) error("can only extract weights from one wham object");
+      88          18 :   } else log.printf("  weights are all equal to one\n");
+      89          30 :   requestArguments( arg );
+      90             : 
+      91             :   // Now add fake components to the underlying ActionWithValue for the arguments
+      92          64 :   for(unsigned i=0; i<argument_names.size(); ++i) { addComponent( argument_names[i] ); componentIsNotPeriodic( argument_names[i] ); }
+      93          30 : }
+      94             : 
+      95          62 : std::vector<Value*> ReadAnalysisFrames::getArgumentList() {
+      96          62 :   std::vector<Value*> arg_vals( ActionWithArguments::getArguments() );
+      97          68 :   for(unsigned i=0; i<weight_vals.size(); ++i) arg_vals.erase(arg_vals.end()-1);
+      98          62 :   return arg_vals;
+      99             : }
+     100             : 
+     101           5 : std::string ReadAnalysisFrames::getDissimilarityInstruction() const {
+     102           5 :   return "TYPE=UNKNOWN";
+     103             : }
+     104             : 
+     105          12 : const std::vector<AtomNumber>& ReadAnalysisFrames::getAtomIndexes() const {
+     106          12 :   return getAbsoluteIndexes();
+     107             : }
+     108             : 
+     109          26 : void ReadAnalysisFrames::calculateWeights() {
+     110          26 :   weights_calculated=true;
+     111          26 :   weights.resize( logweights.size() );
+     112          26 :   if( weight_vals.empty() ) {
+     113        3261 :     for(unsigned i=0; i<logweights.size(); ++i) weights[i]=1.0;
+     114             :   } else {
+     115           7 :     if( wham_pointer ) {
+     116           7 :       wham_pointer->calculateWeights( logweights.size() );
+     117        2464 :       for(unsigned i=0; i<logweights.size(); ++i) weights[i]=wham_pointer->getWeight(i);
+     118             :     } else {
+     119             :       // Find the maximum weight
+     120           0 :       double maxweight=logweights[0];
+     121           0 :       for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+     122           0 :         if(logweights[i]>maxweight) maxweight=logweights[i];
+     123             :       }
+     124             :       // Calculate weights (no memory) -- business here with maxweight is to prevent overflows
+     125           0 :       for(unsigned i=0; i<logweights.size(); ++i) weights[i]=std::exp( logweights[i]-maxweight );
+     126             :     }
+     127             :   }
+     128          26 : }
+     129             : 
+     130        7500 : void ReadAnalysisFrames::update() {
+     131        7500 :   if( getStep()==0 ) return;
+     132             :   // Delete everything we stored now that it has been analyzed
+     133        7472 :   if( clearonnextstep ) {
+     134           5 :     my_data_stash.clear(); my_data_stash.resize(0);
+     135          10 :     logweights.clear(); logweights.resize(0);
+     136           5 :     if( wham_pointer ) wham_pointer->clearData();
+     137           5 :     clearonnextstep=false;
+     138             :   }
+     139             : 
+     140             :   // Get the weight and store it in the weights array
+     141       11684 :   double ww=0; for(unsigned i=0; i<weight_vals.size(); ++i) ww+=weight_vals[i]->get();
+     142        7472 :   weights_calculated=false; logweights.push_back(ww);
+     143             : 
+     144             :   // Now create the data collection object and push it back to be stored
+     145        7472 :   unsigned index = my_data_stash.size(); my_data_stash.push_back( DataCollectionObject() );
+     146        7472 :   my_data_stash[index].setAtomNumbersAndArgumentNames( getLabel(), atom_numbers, argument_names );
+     147        7472 :   my_data_stash[index].setAtomPositions( getPositions() );
+     148       16079 :   for(unsigned i=0; i<argument_names.size(); ++i) my_data_stash[index].setArgument( argument_names[i], getArgument(i) );
+     149             : 
+     150        7472 :   if( clearstride>0 ) {
+     151         475 :     if( getStep()%clearstride==0 ) clearonnextstep=true;
+     152             :   }
+     153             : }
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html b/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html new file mode 100644 index 0000000000..401dfd8dee --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.func.html b/coverage/analysis/ReadAnalysisFrames.h.func.html new file mode 100644 index 0000000000..a07e5fc59f --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.gcov.html b/coverage/analysis/ReadAnalysisFrames.h.gcov.html new file mode 100644 index 0000000000..827ec0f599 --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.gcov.html @@ -0,0 +1,182 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..f4318bcdd7 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html new file mode 100644 index 0000000000..116385b43a --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05:14Functions:121675.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe766createERKNS_13ActionOptionsE2
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_135ReadDissimilarityMatrixRegisterMe76D2Ev4168
_ZN4PLMD8analysis23ReadDissimilarityMatrix12runFinalJobsEv2
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix15performAnalysisEv0
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
_ZN4PLMD8analysis23ReadDissimilarityMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZN4PLMD8analysis23ReadDissimilarityMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZNK4PLMD8analysis23ReadDissimilarityMatrix23getDataPointIndexInBaseERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 0000000000..eb621a9643 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ReadDissimilarityMatrix,"READ_DISSIMILARITY_MATRIX")
+      77             : 
+      78           4 : void ReadDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      79           4 :   AnalysisBase::registerKeywords( keys );
+      80           8 :   keys.add("compulsory","FILE","an input file containing the matrix of dissimilarities");
+      81           8 :   keys.add("optional","WFILE","input file containing weights of points");
+      82           8 :   keys.reset_style("USE_OUTPUT_DATA_FROM","optional");
+      83           4 : }
+      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.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html b/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html new file mode 100644 index 0000000000..1d3658fb7c --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.func.html b/coverage/analysis/ReselectLandmarks.cpp.func.html new file mode 100644 index 0000000000..92e85df7f7 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_129ReselectLandmarksRegisterMe49D2Ev4168
_ZN4PLMD8analysis17ReselectLandmarks15selectLandmarksEv1
_ZN4PLMD8analysis17ReselectLandmarks16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis17ReselectLandmarksC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarksC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.gcov.html b/coverage/analysis/ReselectLandmarks.cpp.gcov.html new file mode 100644 index 0000000000..76c8444486 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(ReselectLandmarks,"RESELECT_LANDMARKS")
+      50             : 
+      51           3 : void ReselectLandmarks::registerKeywords( Keywords& keys ) {
+      52           3 :   LandmarkSelectionBase::registerKeywords(keys);
+      53           3 :   keys.remove("NLANDMARKS");
+      54           6 :   keys.add("compulsory","LANDMARKS","the action that selects the landmarks that you want to reselect using this action");
+      55           3 : }
+      56             : 
+      57           1 : ReselectLandmarks::ReselectLandmarks( const ActionOptions& ao ):
+      58             :   Action(ao),
+      59           1 :   LandmarkSelectionBase(ao)
+      60             : {
+      61           1 :   std::string datastr; parse("LANDMARKS",datastr);
+      62           1 :   mylandmarks = plumed.getActionSet().selectWithLabel<LandmarkSelectionBase*>( datastr );
+      63           1 :   if( !mylandmarks ) error("input to LANDMARKS is not a landmark selection action");
+      64           1 :   nlandmarks = mylandmarks->nlandmarks;
+      65             : 
+      66           1 :   if( (mylandmarks->my_input_data)->getNumberOfDataPoints()!=my_input_data->getNumberOfDataPoints() ) error("mismatch between amount of landmark class and base class");
+      67           1 : }
+      68             : 
+      69           1 : void ReselectLandmarks::selectLandmarks() {
+      70           3 :   for(unsigned i=0; i<mylandmarks->getNumberOfDataPoints(); ++i) selectFrame( mylandmarks->getDataPointIndexInBase(i) );
+      71           1 : }
+      72             : 
+      73             : }
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html b/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html new file mode 100644 index 0000000000..efb0f87c51 --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.func.html b/coverage/analysis/SelectRandomFrames.cpp.func.html new file mode 100644 index 0000000000..e3e6dd8337 --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe476createERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_130SelectRandomFramesRegisterMe47D2Ev4168
_ZN4PLMD8analysis18SelectRandomFrames15selectLandmarksEv0
_ZN4PLMD8analysis18SelectRandomFrames16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis18SelectRandomFramesC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFramesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.gcov.html b/coverage/analysis/SelectRandomFrames.cpp.gcov.html new file mode 100644 index 0000000000..0501da99fd --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(SelectRandomFrames,"LANDMARK_SELECT_RANDOM")
+      48             : 
+      49           2 : void SelectRandomFrames::registerKeywords( Keywords& keys ) {
+      50           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           4 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           2 : }
+      53             : 
+      54           0 : SelectRandomFrames::SelectRandomFrames( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           0 :   LandmarkSelectionBase(ao)
+      57             : {
+      58           0 :   parse("SEED",seed);
+      59           0 : }
+      60             : 
+      61           0 : void SelectRandomFrames::selectLandmarks() {
+      62           0 :   Random r; r.setSeed(-seed);
+      63           0 :   unsigned nframe=my_input_data->getNumberOfDataPoints();
+      64           0 :   unsigned nland=getNumberOfDataPoints();
+      65             : 
+      66           0 :   std::vector<bool> selected( nframe, false );
+      67             : 
+      68             :   unsigned fcount=0;
+      69           0 :   while (fcount<nland) {
+      70           0 :     unsigned iframe = std::floor( r.U01()*nframe );
+      71           0 :     if (!selected[iframe]) {
+      72             :       selected[iframe]=true;
+      73           0 :       selectFrame( iframe );
+      74           0 :       ++fcount;
+      75             :     }
+      76             :   }
+      77           0 : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.func-sort-c.html b/coverage/analysis/SelectWithStride.cpp.func-sort-c.html new file mode 100644 index 0000000000..19ee6e8414 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe446createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.func.html b/coverage/analysis/SelectWithStride.cpp.func.html new file mode 100644 index 0000000000..df18eb5cb8 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe446createERKNS_13ActionOptionsE8
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_128SelectWithStrideRegisterMe44D2Ev4168
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.gcov.html b/coverage/analysis/SelectWithStride.cpp.gcov.html new file mode 100644 index 0000000000..20e9de3ff5 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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 kth 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       12520 : PLUMED_REGISTER_ACTION(SelectWithStride,"LANDMARK_SELECT_STRIDE")
+      45             : 
+      46          10 : void SelectWithStride::registerKeywords( Keywords& keys ) {
+      47          10 :   LandmarkSelectionBase::registerKeywords( keys );
+      48          10 : }
+      49             : 
+      50           8 : SelectWithStride::SelectWithStride( const ActionOptions& ao ):
+      51             :   Action(ao),
+      52           8 :   LandmarkSelectionBase(ao)
+      53             : {
+      54           8 : }
+      55             : 
+      56          10 : void SelectWithStride::selectLandmarks() {
+      57          10 :   unsigned stride = std::floor( my_input_data->getNumberOfDataPoints() / getNumberOfDataPoints() ), max=stride*getNumberOfDataPoints();
+      58         296 :   for(unsigned i=0; i<max; i+=stride) selectFrame( i );
+      59          10 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func-sort-c.html b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html new file mode 100644 index 0000000000..767b7e5983 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe816createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func.html b/coverage/analysis/WhamHistogram.cpp.func.html new file mode 100644 index 0000000000..3fa28b392f --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe816createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_125WhamHistogramRegisterMe81D2Ev4168
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.gcov.html b/coverage/analysis/WhamHistogram.cpp.gcov.html new file mode 100644 index 0000000000..52d8773295 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(WhamHistogram,"WHAM_HISTOGRAM")
+      82             : 
+      83           8 : void WhamHistogram::registerKeywords( Keywords& keys ) {
+      84           8 :   ActionShortcut::registerKeywords( keys );
+      85          16 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+      86          16 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      87          16 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      88          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be stored to perform WHAM");
+      89          16 :   keys.add("compulsory","GRID_MIN","the minimum to use for the grid");
+      90          16 :   keys.add("compulsory","GRID_MAX","the maximum to use for the grid");
+      91          16 :   keys.add("compulsory","GRID_BIN","the number of bins to use for the grid");
+      92          16 :   keys.add("optional","BANDWIDTH","the bandwidth for kernel density estimation");
+      93           8 : }
+      94             : 
+      95             : 
+      96           6 : WhamHistogram::WhamHistogram( const ActionOptions& ao ) :
+      97             :   Action(ao),
+      98           6 :   ActionShortcut(ao)
+      99             : {
+     100             :   // Input for REWEIGHT_WHAM
+     101           6 :   std::string rew_line = getShortcutLabel() + "_weights: REWEIGHT_WHAM";
+     102          18 :   std::string bias; parse("BIAS",bias); rew_line += " ARG=" + bias;
+     103          12 :   std::string temp; parse("TEMP",temp); rew_line += " TEMP=" + temp;
+     104           6 :   readInputLine( rew_line );
+     105             :   // Input for COLLECT_FRAMES
+     106          12 :   std::string col_line = getShortcutLabel() + "_collect: COLLECT_FRAMES LOGWEIGHTS=" + getShortcutLabel() + "_weights";
+     107          18 :   std::string stride; parse("STRIDE",stride); col_line += " STRIDE=" + stride;
+     108          12 :   std::string arg; parse("ARG",arg); col_line += " ARG=" + arg;
+     109           6 :   readInputLine( col_line );
+     110             :   // Input for HISTOGRAM
+     111          12 :   std::string histo_line = getShortcutLabel() + ": HISTOGRAM ARG=" + getShortcutLabel() + "_collect.*";
+     112          18 :   std::string min; parse("GRID_MIN",min); histo_line += " GRID_MIN=" + min;
+     113          18 :   std::string max; parse("GRID_MAX",max); histo_line += " GRID_MAX=" + max;
+     114          12 :   std::string bin; parse("GRID_BIN",bin); histo_line += " GRID_BIN=" + bin;
+     115          12 :   std::string bw=""; parse("BANDWIDTH",bw);
+     116           6 :   if( bw!="" ) histo_line += " BANDWIDTH=" + bw;
+     117             :   else histo_line += " KERNEL=DISCRETE";
+     118           6 :   readInputLine( histo_line );
+     119           6 : }
+     120             : 
+     121             : }
+     122             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.func-sort-c.html b/coverage/analysis/WhamWeights.cpp.func-sort-c.html new file mode 100644 index 0000000000..352aacec6c --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe756createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.func.html b/coverage/analysis/WhamWeights.cpp.func.html new file mode 100644 index 0000000000..220ccb2720 --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe756createERKNS_13ActionOptionsE6
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75C2Ev4168
_ZN4PLMD8analysis12_GLOBAL__N_123WhamWeightsRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.gcov.html b/coverage/analysis/WhamWeights.cpp.gcov.html new file mode 100644 index 0000000000..2cb361e15f --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(WhamWeights,"WHAM_WEIGHTS")
+      76             : 
+      77           8 : void WhamWeights::registerKeywords( Keywords& keys ) {
+      78           8 :   ActionShortcut::registerKeywords( keys ); keys.remove("LABEL");
+      79          16 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      80          16 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      81          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the bias should be stored to perform WHAM");
+      82          16 :   keys.add("compulsory","FILE","the file on which to output the WHAM weights");
+      83          16 :   keys.add("optional","FMT","the format to use for the real numbers in the output file");
+      84           8 : }
+      85             : 
+      86           6 : WhamWeights::WhamWeights( const ActionOptions& ao ) :
+      87             :   Action(ao),
+      88           6 :   ActionShortcut(ao)
+      89             : {
+      90             :   // Input for REWEIGHT_WHAM
+      91           6 :   std::string rew_line = getShortcutLabel() + "_weights: REWEIGHT_WHAM";
+      92          18 :   std::string bias; parse("BIAS",bias); rew_line += " ARG=" + bias;
+      93          12 :   std::string temp; parse("TEMP",temp); rew_line += " TEMP=" + temp;
+      94           6 :   readInputLine( rew_line );
+      95             :   // Input for COLLECT_FRAMES
+      96          12 :   std::string col_line = getShortcutLabel() + "_collect: COLLECT_FRAMES LOGWEIGHTS=" + getShortcutLabel() + "_weights";
+      97          12 :   std::string stride; parse("STRIDE",stride); col_line += " STRIDE=" + stride;
+      98           6 :   readInputLine( col_line );
+      99             :   // Input for line to output data
+     100          12 :   std::string out_line="OUTPUT_ANALYSIS_DATA_TO_COLVAR USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_collect";
+     101          12 :   std::string file; parse("FILE",file); out_line += " FILE=" + file;
+     102          12 :   std::string fmt="%f"; parse("FMT",fmt); out_line += " FMT=" + fmt;
+     103           6 :   readInputLine( out_line );
+     104           6 : }
+     105             : 
+     106             : }
+     107             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index-sort-f.html b/coverage/analysis/index-sort-f.html new file mode 100644 index 0000000000..d59a6e0806 --- /dev/null +++ b/coverage/analysis/index-sort-f.html @@ -0,0 +1,333 @@ + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:85997188.5 %
Date:2024-05-27 13:05: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
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
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
WhamHistogram.cpp +
100.0%
+
100.0 %30 / 3083.3 %5 / 6
WhamWeights.cpp +
100.0%
+
100.0 %23 / 2383.3 %5 / 6
AnalysisBase.cpp +
96.9%96.9%
+
96.9 %31 / 3283.3 %5 / 6
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.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
SelectWithStride.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReselectLandmarks.cpp +
100.0%
+
100.0 %17 / 1785.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.16
+
+ + + diff --git a/coverage/analysis/index-sort-l.html b/coverage/analysis/index-sort-l.html new file mode 100644 index 0000000000..c908e130de --- /dev/null +++ b/coverage/analysis/index-sort-l.html @@ -0,0 +1,333 @@ + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:85997188.5 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/analysis/index.html b/coverage/analysis/index.html new file mode 100644 index 0000000000..8c29f3b8a9 --- /dev/null +++ b/coverage/analysis/index.html @@ -0,0 +1,333 @@ + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:85997188.5 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func-sort-c.html b/coverage/annfunc/ANN.cpp.func-sort-c.html new file mode 100644 index 0000000000..bf9845953a --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe1106createERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110C2Ev4168
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func.html b/coverage/annfunc/ANN.cpp.func.html new file mode 100644 index 0000000000..d2e7ef9cbf --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe1106createERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110C2Ev4168
_ZN4PLMD8function7annfunc12_GLOBAL__N_116ANNRegisterMe110D2Ev4168
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.gcov.html b/coverage/annfunc/ANN.cpp.gcov.html new file mode 100644 index 0000000000..51162a63f8 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.gcov.html @@ -0,0 +1,473 @@ + + + + + + + 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-05-27 13:05: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       12514 : PLUMED_REGISTER_ACTION(ANN,"ANN")
+     111             : 
+     112           7 : void ANN::registerKeywords( Keywords& keys ) {
+     113           7 :   Function::registerKeywords(keys);
+     114          14 :   keys.use("ARG"); keys.use("PERIODIC");
+     115          14 :   keys.add("compulsory", "NUM_LAYERS", "number of layers of the neural network");
+     116          14 :   keys.add("compulsory", "NUM_NODES", "numbers of nodes in each layer of the neural network");
+     117          14 :   keys.add("compulsory", "ACTIVATIONS", "activation functions for the neural network");
+     118          14 :   keys.add("numbered", "WEIGHTS", "flattened weight arrays connecting adjacent layers, "
+     119             :            "WEIGHTS0 represents flattened weight array connecting layer 0 and layer 1, "
+     120             :            "WEIGHTS1 represents flattened weight array connecting layer 1 and layer 2, ...");
+     121          14 :   keys.add("numbered", "BIASES", "bias array for each layer of the neural network, "
+     122             :            "BIASES0 represents bias array for layer 1, BIASES1 represents bias array for layer 2, ...");
+     123             :   // since v2.2 plumed requires all components be registered
+     124          14 :   keys.addOutputComponent("node", "default", "components of ANN outputs");
+     125           7 : }
+     126             : 
+     127           5 : ANN::ANN(const ActionOptions&ao):
+     128             :   Action(ao),
+     129           5 :   Function(ao)
+     130             : {
+     131           5 :   parse("NUM_LAYERS", num_layers);
+     132           5 :   num_nodes = vector<int>(num_layers);
+     133          10 :   activations = vector<string>(num_layers - 1);
+     134          10 :   output_of_each_layer = vector<vector<double> >(num_layers);
+     135          10 :   input_of_each_layer = vector<vector<double> >(num_layers);
+     136           5 :   coeff = vector<double** >(num_layers - 1);
+     137           5 :   parseVector("NUM_NODES", num_nodes);
+     138           5 :   parseVector("ACTIVATIONS", activations);
+     139           5 :   log.printf("\nactivations = ");
+     140          15 :   for (auto ss: activations) {
+     141          10 :     log.printf("%s, ", ss.c_str());
+     142             :   }
+     143           5 :   log.printf("\nnum_nodes = ");
+     144          20 :   for (auto ss: num_nodes) {
+     145          15 :     log.printf("%d, ", ss);
+     146             :   }
+     147             :   vector<double> temp_single_coeff, temp_single_bias;
+     148          10 :   for (int ii = 0; ; ii ++) {
+     149             :     // parse coeff
+     150          30 :     if( !parseNumberedVector("WEIGHTS", ii, temp_single_coeff) ) {
+     151           5 :       temp_single_coeff=weights[ii-1];
+     152             :       break;
+     153             :     }
+     154          10 :     weights.push_back(temp_single_coeff);
+     155          10 :     log.printf("size of temp_single_coeff = %lu\n", temp_single_coeff.size());
+     156          10 :     log.printf("size of weights = %lu\n", weights.size());
+     157             :     // parse bias
+     158          20 :     if( !parseNumberedVector("BIASES", ii, temp_single_bias) ) {
+     159           0 :       temp_single_bias=biases[ii-1];
+     160             :     }
+     161          10 :     biases.push_back(temp_single_bias);
+     162          10 :     log.printf("size of temp_single_bias = %lu\n", temp_single_bias.size());
+     163          10 :     log.printf("size of biases = %lu\n", biases.size());
+     164             :   }
+     165             : 
+     166           5 :   if(getNumberOfArguments() != num_nodes[0]) {
+     167           0 :     error("Number of arguments is wrong");
+     168             :   }
+     169             : 
+     170           5 :   auto temp_coeff = weights;
+     171          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     172             :     int num_of_rows, num_of_cols; // num of rows/cols for the coeff matrix of this connection
+     173          10 :     num_of_rows = num_nodes[ii + 1];
+     174          10 :     num_of_cols = num_nodes[ii];
+     175             :     assert (num_of_rows * num_of_cols == temp_coeff[ii].size()); // check whether the size matches
+     176             :     // create a 2d array to hold coefficients
+     177          10 :     coeff[ii] = new double*[num_of_rows];
+     178          32 :     for (int kk = 0; kk < num_of_rows; kk ++) {
+     179          22 :       coeff[ii][kk] = new double[num_of_cols];
+     180             :     }
+     181          61 :     for (int jj = 0; jj < temp_coeff[ii].size(); jj ++) {
+     182          51 :       coeff[ii][jj / num_of_cols][jj % num_of_cols] = temp_coeff[ii][jj];
+     183             :     }
+     184             :   }
+     185             :   // check coeff
+     186          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     187          10 :     log.printf("coeff %d = \n", ii);
+     188          32 :     for (int jj = 0; jj < num_nodes[ii + 1]; jj ++) {
+     189          73 :       for (int kk = 0; kk < num_nodes[ii]; kk ++) {
+     190          51 :         log.printf("%f ", coeff[ii][jj][kk]);
+     191             :       }
+     192          22 :       log.printf("\n");
+     193             :     }
+     194             :   }
+     195             :   // check bias
+     196          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     197          10 :     log.printf("bias %d = \n", ii);
+     198          32 :     for (int jj = 0; jj < num_nodes[ii + 1]; jj ++) {
+     199          22 :       log.printf("%f ", biases[ii][jj]);
+     200             :     }
+     201          10 :     log.printf("\n");
+     202             :   }
+     203           5 :   log.printf("initialization ended\n");
+     204             :   // create components
+     205          12 :   for (int ii = 0; ii < num_nodes[num_layers - 1]; ii ++) {
+     206           7 :     string name_of_this_component = "node-" + to_string(ii);
+     207           7 :     addComponentWithDerivatives(name_of_this_component);
+     208           7 :     componentIsNotPeriodic(name_of_this_component);
+     209             :   }
+     210           5 :   checkRead();
+     211          10 : }
+     212             : 
+     213        1638 : void ANN::calculate_output_of_each_layer(const vector<double>& input) {
+     214             :   // first layer
+     215        1638 :   output_of_each_layer[0] = input;
+     216             :   // following layers
+     217        4914 :   for(int ii = 1; ii < num_nodes.size(); ii ++) {
+     218        3276 :     output_of_each_layer[ii].resize(num_nodes[ii]);
+     219        3276 :     input_of_each_layer[ii].resize(num_nodes[ii]);
+     220             :     // first calculate input
+     221       10374 :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     222        7098 :       input_of_each_layer[ii][jj] = biases[ii - 1][jj];  // add bias term
+     223       23478 :       for (int kk = 0; kk < num_nodes[ii - 1]; kk ++) {
+     224       16380 :         input_of_each_layer[ii][jj] += coeff[ii - 1][jj][kk] * output_of_each_layer[ii - 1][kk];
+     225             :       }
+     226             :     }
+     227             :     // then get output
+     228        3276 :     if (activations[ii - 1] == string("Linear")) {
+     229        1092 :       for(int jj = 0; jj < num_nodes[ii]; jj ++) {
+     230         546 :         output_of_each_layer[ii][jj] = input_of_each_layer[ii][jj];
+     231             :       }
+     232             :     }
+     233        2730 :     else if (activations[ii - 1] == string("Tanh")) {
+     234        7644 :       for(int jj = 0; jj < num_nodes[ii]; jj ++) {
+     235        5460 :         output_of_each_layer[ii][jj] = tanh(input_of_each_layer[ii][jj]);
+     236             :       }
+     237             :     }
+     238         546 :     else if (activations[ii - 1] == string("Circular")) {
+     239             :       assert (num_nodes[ii] % 2 == 0);
+     240        1092 :       for(int jj = 0; jj < num_nodes[ii] / 2; jj ++) {
+     241         546 :         double radius = sqrt(input_of_each_layer[ii][2 * jj] * input_of_each_layer[ii][2 * jj]
+     242         546 :                              +input_of_each_layer[ii][2 * jj + 1] * input_of_each_layer[ii][2 * jj + 1]);
+     243         546 :         output_of_each_layer[ii][2 * jj] = input_of_each_layer[ii][2 * jj] / radius;
+     244         546 :         output_of_each_layer[ii][2 * jj + 1] = input_of_each_layer[ii][2 * jj + 1] / radius;
+     245             : 
+     246             :       }
+     247             :     }
+     248             :     else {
+     249             :       printf("layer type not found!\n\n");
+     250           0 :       return;
+     251             :     }
+     252             :   }
+     253             : #ifdef DEBUG_2
+     254             :   // print out the result for debugging
+     255             :   printf("output_of_each_layer = \n");
+     256             :   // for (int ii = num_layers - 1; ii < num_layers; ii ++) {
+     257             :   for (int ii = 0; ii < num_layers; ii ++) {
+     258             :     printf("layer[%d]: ", ii);
+     259             :     if (ii != 0) {
+     260             :       cout << activations[ii - 1] << "\t";
+     261             :     }
+     262             :     else {
+     263             :       cout << "input \t" ;
+     264             :     }
+     265             :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     266             :       printf("%lf\t", output_of_each_layer[ii][jj]);
+     267             :     }
+     268             :     printf("\n");
+     269             :   }
+     270             :   printf("\n");
+     271             : #endif
+     272             :   return;
+     273             : }
+     274             : 
+     275        2184 : void ANN::back_prop(vector<vector<double> >& derivatives_of_each_layer, int index_of_output_component) {
+     276        2184 :   derivatives_of_each_layer = output_of_each_layer;  // the data structure and size should be the same, so I simply deep copy it
+     277             :   // first calculate derivatives for bottleneck layer
+     278        5460 :   for (int ii = 0; ii < num_nodes[num_nodes.size() - 1]; ii ++ ) {
+     279        3276 :     if (ii == index_of_output_component) {
+     280        2184 :       derivatives_of_each_layer[num_nodes.size() - 1][ii] = 1;
+     281             :     }
+     282             :     else {
+     283        1092 :       derivatives_of_each_layer[num_nodes.size() - 1][ii] = 0;
+     284             :     }
+     285             :   }
+     286             :   // the use back propagation to calculate derivatives for previous layers
+     287        6552 :   for (int jj = num_nodes.size() - 2; jj >= 0; jj --) {
+     288        4368 :     if (activations[jj] == string("Circular")) {
+     289             :       vector<double> temp_derivative_of_input_for_this_layer;
+     290        1092 :       temp_derivative_of_input_for_this_layer.resize(num_nodes[jj + 1]);
+     291             : #ifdef DEBUG
+     292             :       assert (num_nodes[jj + 1] % 2 == 0);
+     293             : #endif
+     294             :       // first calculate the derivative of input from derivative of output of this circular layer
+     295        2184 :       for(int ii = 0; ii < num_nodes[jj + 1] / 2; ii ++) {
+     296             :         // printf("size of input_of_each_layer[%d] = %d\n",jj,  input_of_each_layer[jj].size());
+     297        1092 :         double x_p = input_of_each_layer[jj + 1][2 * ii];
+     298        1092 :         double x_q = input_of_each_layer[jj + 1][2 * ii + 1];
+     299        1092 :         double radius = sqrt(x_p * x_p + x_q * x_q);
+     300        1092 :         temp_derivative_of_input_for_this_layer[2 * ii] = x_q / (radius * radius * radius)
+     301        1092 :             * (x_q * derivatives_of_each_layer[jj + 1][2 * ii]
+     302        1092 :                - x_p * derivatives_of_each_layer[jj + 1][2 * ii + 1]);
+     303        1092 :         temp_derivative_of_input_for_this_layer[2 * ii + 1] = x_p / (radius * radius * radius)
+     304        1092 :             * (x_p * derivatives_of_each_layer[jj + 1][2 * ii + 1]
+     305        1092 :                - x_q * derivatives_of_each_layer[jj + 1][2 * ii]);
+     306             :       }
+     307             : #ifdef DEBUG
+     308             :       for (int mm = 0; mm < num_nodes[jj + 1]; mm ++) {
+     309             :         printf("temp_derivative_of_input_for_this_layer[%d] = %lf\n", mm, temp_derivative_of_input_for_this_layer[mm]);
+     310             :         printf("derivatives_of_each_layer[%d + 1][%d] = %lf\n", jj, mm, derivatives_of_each_layer[jj + 1][mm]);
+     311             :       }
+     312             : #endif
+     313             :       // the calculate the derivative of output of layer jj, from derivative of input of layer (jj + 1)
+     314        4368 :       for (int mm = 0; mm < num_nodes[jj]; mm ++) {
+     315        3276 :         derivatives_of_each_layer[jj][mm] = 0;
+     316        9828 :         for (int kk = 0; kk < num_nodes[jj + 1]; kk ++) {
+     317        6552 :           derivatives_of_each_layer[jj][mm] += coeff[jj][kk][mm] \
+     318        6552 :                                                * temp_derivative_of_input_for_this_layer[kk];
+     319             : #ifdef DEBUG
+     320             :           printf("derivatives_of_each_layer[%d][%d] = %lf\n", jj, mm, derivatives_of_each_layer[jj][mm]);
+     321             :           printf("coeff[%d][%d][%d] = %lf\n", jj, kk, mm, coeff[jj][kk][mm]);
+     322             : #endif
+     323             :         }
+     324             :       }
+     325             :       // TODO: should be fine, pass all tests, although there seems to be some problems here previously
+     326             :     }
+     327             :     else {
+     328       10920 :       for (int mm = 0; mm < num_nodes[jj]; mm ++) {
+     329        7644 :         derivatives_of_each_layer[jj][mm] = 0;
+     330       24024 :         for (int kk = 0; kk < num_nodes[jj + 1]; kk ++) {
+     331       16380 :           if (activations[jj] == string("Tanh")) {
+     332             :             // printf("tanh\n");
+     333       14742 :             derivatives_of_each_layer[jj][mm] += derivatives_of_each_layer[jj + 1][kk] \
+     334       14742 :                                                  * coeff[jj][kk][mm] \
+     335       14742 :                                                  * (1 - output_of_each_layer[jj + 1][kk] * output_of_each_layer[jj + 1][kk]);
+     336             :           }
+     337        1638 :           else if (activations[jj] == string("Linear")) {
+     338             :             // printf("linear\n");
+     339        1638 :             derivatives_of_each_layer[jj][mm] += derivatives_of_each_layer[jj + 1][kk] \
+     340        1638 :                                                  * coeff[jj][kk][mm] \
+     341        1638 :                                                  * 1;
+     342             :           }
+     343             :           else {
+     344             :             printf("layer type not found!\n\n");
+     345           0 :             return;
+     346             :           }
+     347             :         }
+     348             :       }
+     349             :     }
+     350             :   }
+     351             : #ifdef DEBUG
+     352             :   // print out the result for debugging
+     353             :   printf("derivatives_of_each_layer = \n");
+     354             :   for (int ii = 0; ii < num_layers; ii ++) {
+     355             :     printf("layer[%d]: ", ii);
+     356             :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     357             :       printf("%lf\t", derivatives_of_each_layer[ii][jj]);
+     358             :     }
+     359             :     printf("\n");
+     360             :   }
+     361             :   printf("\n");
+     362             : #endif
+     363             :   return;
+     364             : }
+     365             : 
+     366        1638 : void ANN::calculate() {
+     367             : 
+     368        1638 :   vector<double> input_layer_data(num_nodes[0]);
+     369        4914 :   for (int ii = 0; ii < num_nodes[0]; ii ++) {
+     370        3276 :     input_layer_data[ii] = getArgument(ii);
+     371             :   }
+     372             : 
+     373        1638 :   calculate_output_of_each_layer(input_layer_data);
+     374             :   vector<vector<double> > derivatives_of_each_layer;
+     375             : 
+     376        3822 :   for (int ii = 0; ii < num_nodes[num_layers - 1]; ii ++) {
+     377        2184 :     back_prop(derivatives_of_each_layer, ii);
+     378        2184 :     string name_of_this_component = "node-" + to_string(ii);
+     379        2184 :     Value* value_new=getPntrToComponent(name_of_this_component);
+     380        2184 :     value_new -> set(output_of_each_layer[num_layers - 1][ii]);
+     381        6552 :     for (int jj = 0; jj < num_nodes[0]; jj ++) {
+     382        4368 :       value_new -> setDerivative(jj, derivatives_of_each_layer[0][jj]);  // TODO: setDerivative or addDerivative?
+     383             :     }
+     384             : #ifdef DEBUG_3
+     385             :     printf("derivatives = ");
+     386             :     for (int jj = 0; jj < num_nodes[0]; jj ++) {
+     387             :       printf("%f ", value_new -> getDerivative(jj));
+     388             :     }
+     389             :     printf("\n");
+     390             : #endif
+     391             :   }
+     392             : 
+     393        3276 : }
+     394             : 
+     395             : }
+     396             : }
+     397             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/index-sort-f.html b/coverage/annfunc/index-sort-f.html new file mode 100644 index 0000000000..d8d139e3dd --- /dev/null +++ b/coverage/annfunc/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/annfunc/index-sort-l.html b/coverage/annfunc/index-sort-l.html new file mode 100644 index 0000000000..2fabda5f9a --- /dev/null +++ b/coverage/annfunc/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/annfunc/index.html b/coverage/annfunc/index.html new file mode 100644 index 0000000000..11741e9f82 --- /dev/null +++ b/coverage/annfunc/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.func-sort-c.html b/coverage/bias/ABMD.cpp.func-sort-c.html new file mode 100644 index 0000000000..df28049911 --- /dev/null +++ b/coverage/bias/ABMD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias4ABMD9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.func.html b/coverage/bias/ABMD.cpp.func.html new file mode 100644 index 0000000000..e0d663b1b1 --- /dev/null +++ b/coverage/bias/ABMD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe956createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_116ABMDRegisterMe95D2Ev4168
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias4ABMD9calculateEv5
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.gcov.html b/coverage/bias/ABMD.cpp.gcov.html new file mode 100644 index 0000000000..57cca6a138 --- /dev/null +++ b/coverage/bias/ABMD.cpp.gcov.html @@ -0,0 +1,262 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(ABMD,"ABMD")
+      96             : 
+      97           3 : void ABMD::registerKeywords(Keywords& keys) {
+      98           3 :   Bias::registerKeywords(keys);
+      99           3 :   keys.use("ARG");
+     100           6 :   keys.add("compulsory","TO","The array of target values");
+     101           6 :   keys.add("compulsory","KAPPA","The array of force constants.");
+     102           6 :   keys.add("optional","MIN","Array of starting values for the bias (set rho_m(t), otherwise it is set using the current value of ARG)");
+     103           6 :   keys.add("optional","NOISE","Array of white noise intensities (add a temperature to the ABMD)");
+     104           6 :   keys.add("optional","SEED","Array of seeds for the white noise (add a temperature to the ABMD)");
+     105           6 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     106           6 :   keys.addOutputComponent("_min","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     107             :                           " These quantities will be named with the arguments of the bias followed by "
+     108             :                           "the character string _min. These quantities tell the user the minimum value assumed by rho_m(t).");
+     109           3 : }
+     110             : 
+     111           1 : ABMD::ABMD(const ActionOptions&ao):
+     112             :   PLUMED_BIAS_INIT(ao),
+     113           2 :   to(getNumberOfArguments(),0.0),
+     114           1 :   min(getNumberOfArguments(),-1.0),
+     115           1 :   kappa(getNumberOfArguments(),0.0),
+     116           1 :   temp(getNumberOfArguments(),0.0),
+     117           1 :   seed(getNumberOfArguments(),std::time(0)),
+     118           2 :   random(getNumberOfArguments())
+     119             : {
+     120             :   // Note : parseVector will check that number of arguments is correct
+     121           1 :   parseVector("KAPPA",kappa);
+     122           2 :   parseVector("MIN",min);
+     123           1 :   if(min.size()==0) min.assign(getNumberOfArguments(),-1.0);
+     124           1 :   if(min.size()!=getNumberOfArguments()) error("MIN array should have the same size as ARG array");
+     125           1 :   parseVector("NOISE",temp);
+     126           1 :   parseVector("SEED",seed);
+     127           1 :   parseVector("TO",to);
+     128           1 :   checkRead();
+     129             : 
+     130           1 :   log.printf("  min");
+     131           2 :   for(unsigned i=0; i<min.size(); i++) log.printf(" %f",min[i]);
+     132           1 :   log.printf("\n");
+     133           1 :   log.printf("  to");
+     134           2 :   for(unsigned i=0; i<to.size(); i++) log.printf(" %f",to[i]);
+     135           1 :   log.printf("\n");
+     136           1 :   log.printf("  with force constant");
+     137           2 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     138           1 :   log.printf("\n");
+     139             : 
+     140           2 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     141           1 :     std::string str_min=getPntrToArgument(i)->getName()+"_min";
+     142           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.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.func-sort-c.html b/coverage/bias/Bias.cpp.func-sort-c.html new file mode 100644 index 0000000000..a96637eb41 --- /dev/null +++ b/coverage/bias/Bias.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE682
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE733
_ZN4PLMD4bias4Bias5applyEv78588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.func.html b/coverage/bias/Bias.cpp.func.html new file mode 100644 index 0000000000..c62c477be9 --- /dev/null +++ b/coverage/bias/Bias.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE733
_ZN4PLMD4bias4Bias5applyEv78588
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE682
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.gcov.html b/coverage/bias/Bias.cpp.gcov.html new file mode 100644 index 0000000000..72aea841a2 --- /dev/null +++ b/coverage/bias/Bias.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-05-27 13:05: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         682 : Bias::Bias(const ActionOptions&ao):
+      29             :   Action(ao),
+      30             :   ActionPilot(ao),
+      31             :   ActionWithValue(ao),
+      32             :   ActionWithArguments(ao),
+      33         682 :   outputForces(getNumberOfArguments(),0.0)
+      34             : {
+      35         679 :   addComponentWithDerivatives("bias");
+      36         679 :   componentIsNotPeriodic("bias");
+      37         679 :   valueBias=getPntrToComponent("bias");
+      38             : 
+      39         679 :   if(getStride()>1) {
+      40           3 :     log<<"  multiple time step "<<getStride()<<" ";
+      41           6 :     log<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+      42             :   }
+      43        4496 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      44        3817 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      45             :   }
+      46             : 
+      47         679 :   ActionWithValue::turnOnDerivatives();
+      48         682 : }
+      49             : 
+      50         733 : void Bias::registerKeywords( Keywords& keys ) {
+      51         733 :   Action::registerKeywords(keys);
+      52         733 :   ActionPilot::registerKeywords(keys);
+      53         733 :   ActionWithValue::registerKeywords(keys);
+      54         733 :   ActionWithArguments::registerKeywords(keys);
+      55        1466 :   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         733 :   componentsAreNotOptional(keys);
+      57        1466 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      58         733 : }
+      59             : 
+      60       78588 : void Bias::apply() {
+      61       78588 :   const unsigned noa=getNumberOfArguments();
+      62       78588 :   const unsigned ncp=getNumberOfComponents();
+      63             : 
+      64       78588 :   if(onStep()) {
+      65       78588 :     double gstr = static_cast<double>(getStride());
+      66      224527 :     for(unsigned i=0; i<noa; ++i) {
+      67      145939 :       getPntrToArgument(i)->addForce(gstr*outputForces[i]);
+      68             :     }
+      69             :   }
+      70             : 
+      71             :   // additional forces on the bias component
+      72       78588 :   std::vector<double> f(noa,0.0);
+      73       78588 :   std::vector<double> forces(noa);
+      74             : 
+      75             :   bool at_least_one_forced=false;
+      76      398305 :   for(unsigned i=0; i<ncp; ++i) {
+      77      319717 :     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       78588 :   if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE");
+      84             : 
+      85       79429 :   if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) {
+      86         559 :       getPntrToArgument(i)->addForce(f[i]);
+      87             :     }
+      88             : 
+      89       78588 : }
+      90             : 
+      91             : }
+      92             : }
+      93             : 
+      94             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func-sort-c.html b/coverage/bias/Bias.h.func-sort-c.html new file mode 100644 index 0000000000..748557d1e2 --- /dev/null +++ b/coverage/bias/Bias.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func.html b/coverage/bias/Bias.h.func.html new file mode 100644 index 0000000000..50b5b233fd --- /dev/null +++ b/coverage/bias/Bias.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.gcov.html b/coverage/bias/Bias.h.gcov.html new file mode 100644 index 0000000000..1cebefb1ab --- /dev/null +++ b/coverage/bias/Bias.h.gcov.html @@ -0,0 +1,157 @@ + + + + + + + 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-05-27 13:05: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      141271 :   outputForces[i]=f;
+      64      142382 :   valueBias->addDerivative(i,-f);
+      65             : }
+      66             : 
+      67             : inline
+      68             : void Bias::setBias(double bias) {
+      69       78335 :   valueBias->set(bias);
+      70       38433 : }
+      71             : 
+      72             : inline
+      73         795 : unsigned Bias::getNumberOfDerivatives() {
+      74         795 :   return getNumberOfArguments();
+      75             : }
+      76             : 
+      77             : }
+      78             : }
+      79             : 
+      80             : #endif
+      81             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func-sort-c.html b/coverage/bias/BiasValue.cpp.func-sort-c.html new file mode 100644 index 0000000000..b637c19291 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe826createERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD4bias9BiasValue9calculateEv472
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func.html b/coverage/bias/BiasValue.cpp.func.html new file mode 100644 index 0000000000..94b3729ac2 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe826createERKNS_13ActionOptionsE32
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121BiasValueRegisterMe82D2Ev4168
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE34
_ZN4PLMD4bias9BiasValue9calculateEv472
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE32
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.gcov.html b/coverage/bias/BiasValue.cpp.gcov.html new file mode 100644 index 0000000000..64bc86f384 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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-05-27 13:05: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       12568 : PLUMED_REGISTER_ACTION(BiasValue,"BIASVALUE")
+      83             : 
+      84          34 : void BiasValue::registerKeywords(Keywords& keys) {
+      85          34 :   Bias::registerKeywords(keys);
+      86          34 :   keys.use("ARG");
+      87             :   // Should be _bias below
+      88          68 :   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          34 : }
+      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.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html new file mode 100644 index 0000000000..430912b583 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias18ExtendedLagrangianC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe1296createERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangianC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangian16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias18ExtendedLagrangian6updateEv24
_ZN4PLMD4bias18ExtendedLagrangian9calculateEv24
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.func.html b/coverage/bias/ExtendedLagrangian.cpp.func.html new file mode 100644 index 0000000000..91827f2c7b --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe1296createERKNS_13ActionOptionsE2
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_131ExtendedLagrangianRegisterMe129D2Ev4168
_ZN4PLMD4bias18ExtendedLagrangian16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias18ExtendedLagrangian6updateEv24
_ZN4PLMD4bias18ExtendedLagrangian9calculateEv24
_ZN4PLMD4bias18ExtendedLagrangianC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangianC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.gcov.html b/coverage/bias/ExtendedLagrangian.cpp.gcov.html new file mode 100644 index 0000000000..ddb0980271 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.gcov.html @@ -0,0 +1,343 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ExtendedLagrangian,"EXTENDED_LAGRANGIAN")
+     130             : 
+     131           4 : void ExtendedLagrangian::registerKeywords(Keywords& keys) {
+     132           4 :   Bias::registerKeywords(keys);
+     133           4 :   keys.use("ARG");
+     134           8 :   keys.add("compulsory","KAPPA","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+     135           8 :   keys.add("compulsory","TAU","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+     136           8 :   keys.add("compulsory","FRICTION","0.0","add a friction to the variable");
+     137           8 :   keys.add("optional","TEMP","the system temperature - needed when FRICTION is present. If not provided will be taken from MD code (if available)");
+     138           4 :   componentsAreNotOptional(keys);
+     139           8 :   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           8 :   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           4 : }
+     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           4 :     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.16
+
+ + + diff --git a/coverage/bias/External.cpp.func-sort-c.html b/coverage/bias/External.cpp.func-sort-c.html new file mode 100644 index 0000000000..58bb7c369f --- /dev/null +++ b/coverage/bias/External.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe1216createERKNS_13ActionOptionsE2
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias8External9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/External.cpp.func.html b/coverage/bias/External.cpp.func.html new file mode 100644 index 0000000000..f11a00dc7b --- /dev/null +++ b/coverage/bias/External.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe1216createERKNS_13ActionOptionsE2
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121ExternalRegisterMe121D2Ev4168
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias8External9calculateEv5
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/External.cpp.gcov.html b/coverage/bias/External.cpp.gcov.html new file mode 100644 index 0000000000..e85d1b0370 --- /dev/null +++ b/coverage/bias/External.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_ACTION(External,"EXTERNAL")
+     122             : 
+     123           4 : void External::registerKeywords(Keywords& keys) {
+     124           4 :   Bias::registerKeywords(keys);
+     125           4 :   keys.use("ARG");
+     126           8 :   keys.add("compulsory","FILE","the name of the file containing the external potential.");
+     127           8 :   keys.addFlag("NOSPLINE",false,"specifies that no spline interpolation is to be used when calculating the energy and forces due to the external potential");
+     128           8 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     129           8 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     130           4 : }
+     131             : 
+     132           2 : External::External(const ActionOptions& ao):
+     133           2 :   PLUMED_BIAS_INIT(ao)
+     134             : {
+     135             :   std::string filename;
+     136           4 :   parse("FILE",filename);
+     137           2 :   if( filename.length()==0 ) error("No external potential file was specified");
+     138           2 :   bool sparsegrid=false;
+     139           2 :   parseFlag("SPARSE",sparsegrid);
+     140           2 :   bool nospline=false;
+     141           2 :   parseFlag("NOSPLINE",nospline);
+     142           2 :   bool spline=!nospline;
+     143           3 :   parse("SCALE",scale_);
+     144             : 
+     145           2 :   checkRead();
+     146             : 
+     147           2 :   log.printf("  External potential from file %s\n",filename.c_str());
+     148           2 :   log.printf("  Multiplied by %lf\n",scale_);
+     149           2 :   if(spline) {log.printf("  External potential uses spline interpolation\n");}
+     150           2 :   if(sparsegrid) {log.printf("  External potential uses sparse grid\n");}
+     151             : 
+     152             : // read grid
+     153           2 :   IFile gridfile; gridfile.open(filename);
+     154           1 :   std::string funcl=getLabel() + ".bias";
+     155           2 :   BiasGrid_=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     156           1 :   if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+     157           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     158           4 :     if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+     159             :   }
+     160           6 : }
+     161             : 
+     162           5 : void External::calculate()
+     163             : {
+     164           5 :   unsigned ncv=getNumberOfArguments();
+     165           5 :   std::vector<double> cv(ncv), der(ncv);
+     166             : 
+     167          15 :   for(unsigned i=0; i<ncv; ++i) {cv[i]=getArgument(i);}
+     168             : 
+     169           5 :   double ene=scale_*BiasGrid_->getValueAndDerivatives(cv,der);
+     170             : 
+     171             :   setBias(ene);
+     172             : 
+     173          15 :   for(unsigned i=0; i<ncv; ++i) {
+     174          10 :     const double f=-scale_*der[i];
+     175          10 :     setOutputForce(i,f);
+     176             :   }
+     177           5 : }
+     178             : 
+     179             : }
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.func-sort-c.html b/coverage/bias/LWalls.cpp.func-sort-c.html new file mode 100644 index 0000000000..377df5965b --- /dev/null +++ b/coverage/bias/LWalls.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias6LWalls9calculateEv5
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.func.html b/coverage/bias/LWalls.cpp.func.html new file mode 100644 index 0000000000..ca5ef25e19 --- /dev/null +++ b/coverage/bias/LWalls.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_118LWallsRegisterMe76D2Ev4168
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias6LWalls9calculateEv5
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.gcov.html b/coverage/bias/LWalls.cpp.gcov.html new file mode 100644 index 0000000000..5b374a74d3 --- /dev/null +++ b/coverage/bias/LWalls.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(LWalls,"LOWER_WALLS")
+      77             : 
+      78           3 : void LWalls::registerKeywords(Keywords& keys) {
+      79           3 :   Bias::registerKeywords(keys);
+      80           3 :   keys.use("ARG");
+      81           6 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      82           6 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      83           6 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      84           6 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      85           6 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      86           6 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      87           3 : }
+      88             : 
+      89           1 : LWalls::LWalls(const ActionOptions&ao):
+      90             :   PLUMED_BIAS_INIT(ao),
+      91           2 :   at(getNumberOfArguments(),0),
+      92           1 :   kappa(getNumberOfArguments(),0.0),
+      93           1 :   exp(getNumberOfArguments(),2.0),
+      94           1 :   eps(getNumberOfArguments(),1.0),
+      95           2 :   offset(getNumberOfArguments(),0.0)
+      96             : {
+      97             :   // Note sizes of these vectors are automatically checked by parseVector :-)
+      98           1 :   parseVector("OFFSET",offset);
+      99           1 :   parseVector("EPS",eps);
+     100           1 :   parseVector("EXP",exp);
+     101           1 :   parseVector("KAPPA",kappa);
+     102           1 :   parseVector("AT",at);
+     103           1 :   checkRead();
+     104             : 
+     105           1 :   log.printf("  at");
+     106           2 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     107           1 :   log.printf("\n");
+     108           1 :   log.printf("  with an offset");
+     109           2 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     110           1 :   log.printf("\n");
+     111           1 :   log.printf("  with force constant");
+     112           2 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     113           1 :   log.printf("\n");
+     114           1 :   log.printf("  and exponent");
+     115           2 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     116           1 :   log.printf("\n");
+     117           1 :   log.printf("  rescaled");
+     118           2 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     119           1 :   log.printf("\n");
+     120             : 
+     121           2 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     122           1 : }
+     123             : 
+     124           5 : void LWalls::calculate() {
+     125             :   double ene = 0.0;
+     126             :   double totf2 = 0.0;
+     127          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     128             :     double f = 0.0;
+     129           5 :     const double cv=difference(i,at[i],getArgument(i));
+     130           5 :     const double off=offset[i];
+     131           5 :     const double epsilon=eps[i];
+     132           5 :     const double lscale = (cv-off)/epsilon;
+     133           5 :     if( lscale < 0.) {
+     134           5 :       const double k=kappa[i];
+     135           5 :       const double exponent=exp[i];
+     136           5 :       double power = std::pow( lscale, exponent );
+     137           5 :       f = -( k / epsilon ) * exponent * power / lscale;
+     138           5 :       ene += k * power;
+     139           5 :       totf2 += f * f;
+     140             :     }
+     141             :     setOutputForce(i,f);
+     142             :   }
+     143             :   setBias(ene);
+     144           5 :   getPntrToComponent("force2")->set(totf2);
+     145           5 : }
+     146             : 
+     147             : }
+     148             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.func-sort-c.html b/coverage/bias/MaxEnt.cpp.func-sort-c.html new file mode 100644 index 0000000000..598aa66082 --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6MaxEntC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6MaxEnt15ReadLagrangiansERNS_5IFileE37
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe1636createERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEntC1ERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEnt16registerKeywordsERNS_8KeywordsE52
_ZN4PLMD4bias6MaxEnt13update_lambdaEv550
_ZN4PLMD4bias6MaxEnt16WriteLagrangiansERSt6vectorIdSaIdEERNS_5OFileE550
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe163C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_119MaxEntRegisterMe163D2Ev4168
_ZN4PLMD4bias6MaxEnt6updateEv5050
_ZN4PLMD4bias6MaxEnt9calculateEv5050
_ZN4PLMD4bias6MaxEnt13compute_errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd5302
_ZN4PLMD4bias6MaxEnt23check_lambda_boundariesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd5302
_ZN4PLMD4bias6MaxEnt14convert_lambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd119118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.func.html b/coverage/bias/MaxEnt.cpp.func.html new file mode 100644 index 0000000000..f4265999c9 --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe5226createERKNS_13ActionOptionsE157
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe522C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_118MetaDRegisterMe522D2Ev4168
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5589
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8542
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD13writeGaussianERKNS1_8GaussianERNS_5OFileE2922
_ZN4PLMD4bias5MetaD14TemperingSpecsC2EbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ddd156
_ZN4PLMD4bias5MetaD16evaluateGaussianERKSt6vectorIdSaIdEERKNS1_8GaussianE192
_ZN4PLMD4bias5MetaD16noStretchWarningEv12
_ZN4PLMD4bias5MetaD16registerKeywordsERNS_8KeywordsE159
_ZN4PLMD4bias5MetaD17logTemperingSpecsERKNS1_14TemperingSpecsE3
_ZN4PLMD4bias5MetaD18getGaussianSupportERKNS1_8GaussianE640
_ZN4PLMD4bias5MetaD18readTemperingSpecsERNS1_14TemperingSpecsE151
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8395
_ZN4PLMD4bias5MetaD24computeReweightingFactorEv102
_ZN4PLMD4bias5MetaD24getGaussianNormalizationERKNS1_8GaussianE0
_ZN4PLMD4bias5MetaD24getTransitionBarrierBiasEv273
_ZN4PLMD4bias5MetaD25registerTemperingKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RNS_8KeywordsE159
_ZN4PLMD4bias5MetaD29updateFrequencyAdaptiveStrideEv154
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2408601
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE285
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5589
_ZN4PLMD4bias5MetaD9calculateEv8435
_ZN4PLMD4bias5MetaD9getHeightERKSt6vectorIdSaIdEE2736
_ZN4PLMD4bias5MetaDC1ERKNS_13ActionOptionsE157
_ZN4PLMD4bias5MetaDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8435
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MetaD.cpp.gcov.html b/coverage/bias/MetaD.cpp.gcov.html new file mode 100644 index 0000000000..08c9cabf85 --- /dev/null +++ b/coverage/bias/MetaD.cpp.gcov.html @@ -0,0 +1,2395 @@ + + + + + + + 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:955108388.2 %
Date:2024-05-27 13:05: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        5589 :     Gaussian(const bool m, const double h, const std::vector<double>& c, const std::vector<double>& s):
+     384        5589 :       multivariate(m),height(h),center(c),sigma(s),invsigma(s) {
+     385             :       // to avoid troubles from zero element in flexible hills
+     386       16304 :       for(unsigned i=0; i<invsigma.size(); ++i) {
+     387       10715 :         if(std::abs(invsigma[i])>1.e-20) invsigma[i]=1.0/invsigma[i] ;
+     388           0 :         else invsigma[i]=0.0;
+     389             :       }
+     390        5589 :     }
+     391             :   };
+     392           8 :   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         156 :     inline TemperingSpecs(bool is_active, const std::string &name_stem, const std::string &name, double biasf, double threshold, double alpha) :
+     400         156 :       is_active(is_active), name_stem(name_stem), name(name), biasf(biasf), threshold(threshold), alpha(alpha)
+     401         156 :     {}
+     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       12809 : PLUMED_REGISTER_ACTION(MetaD,"METAD")
+     523             : 
+     524         159 : void MetaD::registerKeywords(Keywords& keys) {
+     525         159 :   Bias::registerKeywords(keys);
+     526         318 :   keys.addOutputComponent("rbias","CALC_RCT","the instantaneous value of the bias normalized using the c(t) reweighting factor [rbias=bias-rct]."
+     527             :                           "This component can be used to obtain a reweighted histogram.");
+     528         318 :   keys.addOutputComponent("rct","CALC_RCT","the reweighting factor \\f$c(t)\\f$.");
+     529         318 :   keys.addOutputComponent("work","CALC_WORK","accumulator for work");
+     530         318 :   keys.addOutputComponent("acc","ACCELERATION","the metadynamics acceleration factor");
+     531         318 :   keys.addOutputComponent("maxbias", "CALC_MAX_BIAS", "the maximum of the metadynamics V(s, t)");
+     532         318 :   keys.addOutputComponent("transbias", "CALC_TRANSITION_BIAS", "the metadynamics transition bias V*(t)");
+     533         318 :   keys.addOutputComponent("pace","FREQUENCY_ADAPTIVE","the hill addition frequency when employing frequency adaptive metadynamics");
+     534         318 :   keys.addOutputComponent("nlker","NLIST","number of hills in the neighbor list");
+     535         318 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     536         159 :   keys.use("ARG");
+     537         318 :   keys.add("compulsory","SIGMA","the widths of the Gaussian hills");
+     538         318 :   keys.add("compulsory","PACE","the frequency for hill addition");
+     539         318 :   keys.add("compulsory","FILE","HILLS","a file in which the list of added hills is stored");
+     540         318 :   keys.add("optional","HEIGHT","the heights of the Gaussian hills. Compulsory unless TAU and either BIASFACTOR or DAMPFACTOR are given");
+     541         318 :   keys.add("optional","FMT","specify format for HILLS files (useful for decrease the number of digits in regtests)");
+     542         318 :   keys.add("optional","BIASFACTOR","use well tempered metadynamics and use this bias factor.  Please note you must also specify temp");
+     543         318 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     544         318 :   keys.add("optional","RECT","list of bias factors for all the replicas");
+     545         318 :   keys.add("optional","DAMPFACTOR","damp hills with exp(-max(V)/(kT*DAMPFACTOR)");
+     546         318 :   for (size_t i = 0; i < n_tempering_options_; i++) {
+     547         159 :     registerTemperingKeywords(tempering_names_[i][0], tempering_names_[i][1], keys);
+     548             :   }
+     549         318 :   keys.add("optional","TARGET","target to a predefined distribution");
+     550         318 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are doing well-tempered metadynamics");
+     551         318 :   keys.add("optional","TAU","in well tempered metadynamics, sets height to (k_B Delta T*pace*timestep)/tau");
+     552         318 :   keys.addFlag("CALC_RCT",false,"calculate the c(t) 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         318 :   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         318 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     557         318 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     558         318 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     559         318 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     560         318 :   keys.addFlag("GRID_SPARSE",false,"use a sparse grid to store hills");
+     561         318 :   keys.addFlag("GRID_NOSPLINE",false,"don't use spline interpolation with grids");
+     562         318 :   keys.add("optional","GRID_WSTRIDE","write the grid to a file every N steps");
+     563         318 :   keys.add("optional","GRID_WFILE","the file on which to write the grid");
+     564         318 :   keys.add("optional","GRID_RFILE","a grid file from which the bias should be read at the initial step of the simulation");
+     565         318 :   keys.addFlag("STORE_GRIDS",false,"store all the grid files the calculation generates. They will be deleted if this keyword is not present");
+     566         318 :   keys.addFlag("NLIST",false,"Use neighbor list for kernels summation, faster but experimental");
+     567         318 :   keys.add("optional", "NLIST_PARAMETERS","(default=6.,0.5) the two cutoff parameters for the Gaussians neighbor list");
+     568         318 :   keys.add("optional","ADAPTIVE","use a geometric (=GEOM) or diffusion (=DIFF) based hills width scheme. Sigma is one number that has distance units or time step dimensions");
+     569         318 :   keys.add("optional","SIGMA_MAX","the upper bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     570         318 :   keys.add("optional","SIGMA_MIN","the lower bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     571         318 :   keys.add("optional","WALKERS_ID", "walker id");
+     572         318 :   keys.add("optional","WALKERS_N", "number of walkers");
+     573         318 :   keys.add("optional","WALKERS_DIR", "shared directory with the hills files from all the walkers");
+     574         318 :   keys.add("optional","WALKERS_RSTRIDE","stride for reading hills files");
+     575         318 :   keys.addFlag("WALKERS_MPI",false,"Switch on MPI version of multiple walkers - not compatible with WALKERS_* options other than WALKERS_DIR");
+     576         318 :   keys.add("optional","INTERVAL","one dimensional lower and upper limits, outside the limits the system will not feel the biasing force.");
+     577         318 :   keys.addFlag("FLYING_GAUSSIAN",false,"Switch on flying Gaussian method, must be used with WALKERS_MPI");
+     578         318 :   keys.addFlag("ACCELERATION",false,"Set to TRUE if you want to compute the metadynamics acceleration factor.");
+     579         318 :   keys.add("optional","ACCELERATION_RFILE","a data file from which the acceleration should be read at the initial step of the simulation");
+     580         318 :   keys.addFlag("CALC_MAX_BIAS", false, "Set to TRUE if you want to compute the maximum of the metadynamics V(s, t)");
+     581         318 :   keys.addFlag("CALC_TRANSITION_BIAS", false, "Set to TRUE if you want to compute a metadynamics transition bias V*(t)");
+     582         318 :   keys.add("numbered", "TRANSITIONWELL", "This keyword appears multiple times as TRANSITIONWELL followed by an integer. Each specifies the coordinates for one well as in transition-tempered metadynamics. At least one must be provided.");
+     583         318 :   keys.addFlag("FREQUENCY_ADAPTIVE",false,"Set to TRUE if you want to enable frequency adaptive metadynamics such that the frequency for hill addition to change dynamically based on the acceleration factor.");
+     584         318 :   keys.add("optional","FA_UPDATE_FREQUENCY","the frequency for updating the hill addition pace in frequency adaptive metadynamics, by default this is equal to the value given in PACE");
+     585         318 :   keys.add("optional","FA_MAX_PACE","the maximum hill addition frequency allowed in frequency adaptive metadynamics. By default there is no maximum value.");
+     586         318 :   keys.add("optional","FA_MIN_ACCELERATION","only update the hill addition pace in frequency adaptive metadynamics after reaching the minimum acceleration factor given here. By default it is 1.0.");
+     587         159 :   keys.use("RESTART");
+     588         159 :   keys.use("UPDATE_FROM");
+     589         159 :   keys.use("UPDATE_UNTIL");
+     590         159 : }
+     591             : 
+     592             : const std::string MetaD::tempering_names_[1][2] = {{"TT", "transition tempered"}};
+     593             : 
+     594         159 : void MetaD::registerTemperingKeywords(const std::string &name_stem, const std::string &name, Keywords &keys) {
+     595         318 :   keys.add("optional", name_stem + "BIASFACTOR", "use " + name + " metadynamics with this bias factor.  Please note you must also specify temp");
+     596         318 :   keys.add("optional", name_stem + "BIASTHRESHOLD", "use " + name + " metadynamics with this bias threshold.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     597         318 :   keys.add("optional", name_stem + "ALPHA", "use " + name + " metadynamics with this hill size decay exponent parameter.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     598         159 : }
+     599             : 
+     600         157 : MetaD::MetaD(const ActionOptions& ao):
+     601             :   PLUMED_BIAS_INIT(ao),
+     602         156 :   kbt_(0.0),
+     603         156 :   stride_(0),
+     604         156 :   calc_work_(false),
+     605         156 :   welltemp_(false),
+     606         156 :   biasf_(-1.0),
+     607         156 :   isFirstStep_(true),
+     608         156 :   height0_(std::numeric_limits<double>::max()),
+     609         156 :   adaptive_(FlexibleBin::none),
+     610         156 :   grid_(false),
+     611         156 :   wgridstride_(0),
+     612         156 :   mw_n_(1), mw_dir_(""), mw_id_(0), mw_rstride_(1),
+     613         156 :   walkers_mpi_(false), mpi_nw_(0),
+     614         156 :   flying_(false),
+     615         156 :   acceleration_(false), acc_(0.0), acc_restart_mean_(0.0),
+     616         156 :   calc_max_bias_(false), max_bias_(0.0),
+     617         156 :   calc_transition_bias_(false), transition_bias_(0.0),
+     618         156 :   dampfactor_(0.0),
+     619         312 :   tt_specs_(false, "TT", "Transition Tempered", -1.0, 0.0, 1.0),
+     620         156 :   current_stride_(0),
+     621         156 :   freq_adaptive_(false),
+     622         156 :   fa_update_frequency_(0),
+     623         156 :   fa_max_stride_(0),
+     624         156 :   fa_min_acceleration_(1.0),
+     625         156 :   uppI_(-1), lowI_(-1), doInt_(false),
+     626         156 :   calc_rct_(false),
+     627         156 :   reweight_factor_(0.0),
+     628         156 :   rct_ustride_(1),
+     629         156 :   work_(0),
+     630         156 :   nlist_(false),
+     631         156 :   nlist_update_(false),
+     632         469 :   nlist_steps_(0)
+     633             : {
+     634         156 :   if(!dp2cutoffNoStretch()) {
+     635         156 :     stretchA=dp2cutoffA;
+     636         156 :     stretchB=dp2cutoffB;
+     637             :   }
+     638             :   // parse the flexible hills
+     639             :   std::string adaptiveoption;
+     640             :   adaptiveoption="NONE";
+     641         312 :   parse("ADAPTIVE",adaptiveoption);
+     642         156 :   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         134 :   } 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         131 :   } else if(adaptiveoption=="NONE") {
+     649         130 :     adaptive_=FlexibleBin::none;
+     650             :   } else {
+     651           1 :     error("I do not know this type of adaptive scheme");
+     652             :   }
+     653             : 
+     654         155 :   parse("FMT",fmt_);
+     655             : 
+     656             :   // parse the sigma
+     657         155 :   parseVector("SIGMA",sigma0_);
+     658         155 :   if(adaptive_==FlexibleBin::none) {
+     659             :     // if you use normal sigma you need one sigma per argument
+     660         130 :     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         152 :   parse("HEIGHT",height0_);
+     694         152 :   parse("PACE",stride_);
+     695         151 :   if(stride_<=0) error("frequency for hill addition is nonsensical");
+     696         151 :   current_stride_ = stride_;
+     697         159 :   std::string hillsfname="HILLS";
+     698         151 :   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         151 :   parseFlag("CALC_MAX_BIAS", calc_max_bias_);
+     704         305 :   parseFlag("CALC_TRANSITION_BIAS", calc_transition_bias_);
+     705             : 
+     706             :   std::vector<double> rect_biasf_;
+     707         302 :   parseVector("RECT",rect_biasf_);
+     708         151 :   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         266 :     parse("BIASFACTOR",biasf_);
+     716             :   }
+     717         151 :   if( biasf_<1.0  && biasf_!=-1.0) error("well tempered bias factor is nonsensical");
+     718         151 :   parse("DAMPFACTOR",dampfactor_);
+     719         151 :   double temp=0.0;
+     720         151 :   parse("TEMP",temp);
+     721         151 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     722          95 :   else kbt_=plumed.getAtoms().getKbT();
+     723         151 :   if(biasf_>=1.0) {
+     724          38 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP");
+     725          38 :     welltemp_=true;
+     726             :   }
+     727         151 :   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         151 :   parseFlag("CALC_WORK",calc_work_);
+     732             : 
+     733             :   // Set transition tempering parameters.
+     734             :   // Transition wells are read later via calc_transition_bias_.
+     735         151 :   readTemperingSpecs(tt_specs_);
+     736         151 :   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         151 :   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         302 :   parse("TARGET",targetfilename_);
+     752         151 :   if(targetfilename_.length()>0 && kbt_==0.0)  error("with TARGET temperature must be specified");
+     753         151 :   double tau=0.0;
+     754         151 :   parse("TAU",tau);
+     755         151 :   if(tau==0.0) {
+     756         129 :     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         129 :     if(welltemp_) tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_;
+     759         110 :     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         153 :   std::vector<std::string> gmin(getNumberOfArguments());
+     772         300 :   parseVector("GRID_MIN",gmin);
+     773         150 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     774         150 :   std::vector<std::string> gmax(getNumberOfArguments());
+     775         300 :   parseVector("GRID_MAX",gmax);
+     776         150 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     777         150 :   std::vector<unsigned> gbin(getNumberOfArguments());
+     778             :   std::vector<double>   gspacing;
+     779         300 :   parseVector("GRID_BIN",gbin);
+     780         150 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     781         300 :   parseVector("GRID_SPACING",gspacing);
+     782         150 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     783         150 :   if(gmin.size()!=gmax.size()) error("GRID_MAX and GRID_MIN should be either present or absent");
+     784         150 :   if(gspacing.size()!=0 && gmin.size()==0) error("If GRID_SPACING is present also GRID_MIN and GRID_MAX should be present");
+     785         150 :   if(gbin.size()!=0     && gmin.size()==0) error("If GRID_BIN is present also GRID_MIN and GRID_MAX should be present");
+     786         150 :   if(gmin.size()!=0) {
+     787          61 :     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          55 :     } else if(gspacing.size()!=0 && gbin.size()==0) {
+     801           2 :       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          61 :     if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     807          73 :     if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     808             :         double a,b;
+     809          13 :         Tools::convert(gmin[i],a);
+     810          12 :         Tools::convert(gmax[i],b);
+     811          12 :         unsigned n=std::ceil(((b-a)/gspacing[i]));
+     812          12 :         if(gbin[i]<n) gbin[i]=n;
+     813             :       }
+     814             :   }
+     815         149 :   if(gbin.size()>0) grid_=true;
+     816             : 
+     817         149 :   bool sparsegrid=false;
+     818         149 :   parseFlag("GRID_SPARSE",sparsegrid);
+     819         149 :   bool nospline=false;
+     820         149 :   parseFlag("GRID_NOSPLINE",nospline);
+     821         149 :   bool spline=!nospline;
+     822         300 :   parse("GRID_WSTRIDE",wgridstride_);
+     823             :   std::string gridfilename_;
+     824         149 :   parse("GRID_WFILE",gridfilename_);
+     825         149 :   parseFlag("STORE_GRIDS",storeOldGrids_);
+     826         149 :   if(grid_ && gridfilename_.length()>0) {
+     827          19 :     if(wgridstride_==0 ) error("frequency with which to output grid not specified use GRID_WSTRIDE");
+     828             :   }
+     829         149 :   if(grid_ && wgridstride_>0) {
+     830          20 :     if(gridfilename_.length()==0) error("grid filename not specified use GRID_WFILE");
+     831             :   }
+     832             : 
+     833             :   std::string gridreadfilename_;
+     834         149 :   parse("GRID_RFILE",gridreadfilename_);
+     835             : 
+     836         149 :   if(!grid_&&gridfilename_.length()> 0) error("To write a grid you need first to define it!");
+     837         149 :   if(!grid_&&gridreadfilename_.length()>0) error("To read a grid you need first to define it!");
+     838             : 
+     839             :   /*setup neighbor list stuff*/
+     840         298 :   parseFlag("NLIST", nlist_);
+     841         149 :   nlist_center_.resize(getNumberOfArguments());
+     842         149 :   nlist_dev2_.resize(getNumberOfArguments());
+     843         150 :   if(nlist_&&grid_) error("NLIST and GRID cannot be combined!");
+     844             :   std::vector<double> nlist_param;
+     845         298 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     846         149 :   if(nlist_param.size()==0)
+     847             :   {
+     848         149 :     nlist_param_[0]=6.0;//*DP2CUTOFF -> max distance of neighbors
+     849         149 :     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         149 :   parseFlag("CALC_RCT",calc_rct_);
+     864         149 :   if (calc_rct_) plumed_massert(grid_,"CALC_RCT is supported only if bias is on a grid");
+     865         149 :   parse("RCT_USTRIDE",rct_ustride_);
+     866             : 
+     867         149 :   if(dampfactor_>0.0) {
+     868           2 :     if(!grid_) error("With DAMPFACTOR you should use grids");
+     869             :   }
+     870             : 
+     871             :   // Multiple walkers
+     872         149 :   parse("WALKERS_N",mw_n_);
+     873         149 :   parse("WALKERS_ID",mw_id_);
+     874         149 :   if(mw_n_<=mw_id_) error("walker ID should be a numerical value less than the total number of walkers");
+     875         149 :   parse("WALKERS_DIR",mw_dir_);
+     876         149 :   parse("WALKERS_RSTRIDE",mw_rstride_);
+     877             : 
+     878             :   // MPI version
+     879         149 :   parseFlag("WALKERS_MPI",walkers_mpi_);
+     880             : 
+     881             :   //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     882         149 :   if(walkers_mpi_) {
+     883          39 :     plumed_assert(Communicator::plumedHasMPI()) << "Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation";
+     884          40 :     plumed_assert(Communicator::initialized()) << "Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.";
+     885             :   }
+     886             : 
+     887             :   // Flying Gaussian
+     888         148 :   parseFlag("FLYING_GAUSSIAN", flying_);
+     889             : 
+     890             :   // Inteval keyword
+     891         149 :   std::vector<double> tmpI(2);
+     892         296 :   parseVector("INTERVAL",tmpI);
+     893         148 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     894         148 :   else if(tmpI.size()==2) {
+     895           2 :     lowI_=tmpI.at(0);
+     896           2 :     uppI_=tmpI.at(1);
+     897           2 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     898           2 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     899           2 :     if(getPntrToArgument(0)->isPeriodic()) error("INTERVAL cannot be used with periodic variables!");
+     900           2 :     doInt_=true;
+     901             :   }
+     902             : 
+     903         296 :   parseFlag("ACCELERATION",acceleration_);
+     904             :   // Check for a restart acceleration if acceleration is active.
+     905             :   std::string acc_rfilename;
+     906         148 :   if(acceleration_) {
+     907           8 :     parse("ACCELERATION_RFILE", acc_rfilename);
+     908             :   }
+     909             : 
+     910         148 :   freq_adaptive_=false;
+     911         148 :   parseFlag("FREQUENCY_ADAPTIVE",freq_adaptive_);
+     912             :   //
+     913         148 :   fa_update_frequency_=0;
+     914         148 :   parse("FA_UPDATE_FREQUENCY",fa_update_frequency_);
+     915         148 :   if(fa_update_frequency_!=0 && !freq_adaptive_) {
+     916           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");
+     917             :   }
+     918         148 :   if(fa_update_frequency_==0 && freq_adaptive_) {
+     919           0 :     fa_update_frequency_=stride_;
+     920             :   }
+     921             :   //
+     922         148 :   fa_max_stride_=0;
+     923         148 :   parse("FA_MAX_PACE",fa_max_stride_);
+     924         148 :   if(fa_max_stride_!=0 && !freq_adaptive_) {
+     925           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");
+     926             :   }
+     927             :   //
+     928         148 :   fa_min_acceleration_=1.0;
+     929         148 :   parse("FA_MIN_ACCELERATION",fa_min_acceleration_);
+     930         148 :   if(fa_min_acceleration_!=1.0 && !freq_adaptive_) {
+     931           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");
+     932             :   }
+     933             : 
+     934         148 :   checkRead();
+     935             : 
+     936         148 :   log.printf("  Gaussian width ");
+     937         148 :   if (adaptive_==FlexibleBin::diffusion)log.printf(" (Note: The units of sigma are in timesteps) ");
+     938         148 :   if (adaptive_==FlexibleBin::geometry)log.printf(" (Note: The units of sigma are in dist units) ");
+     939         396 :   for(unsigned i=0; i<sigma0_.size(); ++i) log.printf(" %f",sigma0_[i]);
+     940         148 :   log.printf("  Gaussian height %f\n",height0_);
+     941         148 :   log.printf("  Gaussian deposition pace %d\n",stride_);
+     942         148 :   log.printf("  Gaussian file %s\n",hillsfname.c_str());
+     943         148 :   if(welltemp_) {
+     944          38 :     log.printf("  Well-Tempered Bias Factor %f\n",biasf_);
+     945          38 :     log.printf("  Hills relaxation time (tau) %f\n",tau);
+     946          38 :     log.printf("  KbT %f\n",kbt_);
+     947             :   }
+     948             : 
+     949             :   // Transition tempered metadynamics options
+     950         148 :   if (tt_specs_.is_active) {
+     951           3 :     logTemperingSpecs(tt_specs_);
+     952             :     // Check that the appropriate transition bias quantity is calculated.
+     953             :     // (Should never trip, given that the flag is automatically set.)
+     954           3 :     if (!calc_transition_bias_) {
+     955           0 :       error(" transition tempering requires calculation of a transition bias");
+     956             :     }
+     957             :   }
+     958             : 
+     959             :   // Overall tempering sanity check (this gets tricky when multiple are active).
+     960             :   // When multiple temperings are active, it's fine to have one tempering attempt
+     961             :   // to increase hill size with increasing bias, so long as the others can shrink
+     962             :   // the hills faster than it increases their size in the long-time limit.
+     963             :   // This set of checks ensures that the hill sizes eventually decay to zero as c(t)
+     964             :   // diverges to infinity.
+     965             :   // The alpha parameter allows hills to decay as 1/t^alpha instead of 1/t,
+     966             :   // a slower decay, so as t -> infinity, only the temperings with the largest
+     967             :   // alphas govern the final asymptotic decay. (Alpha helps prevent false convergence.)
+     968         148 :   if (welltemp_ || dampfactor_ > 0.0 || tt_specs_.is_active) {
+     969             :     // Determine the number of active temperings.
+     970             :     int n_active = 0;
+     971          43 :     if (welltemp_) n_active++;
+     972          43 :     if (dampfactor_ > 0.0) n_active++;
+     973          43 :     if (tt_specs_.is_active) n_active++;
+     974             :     // Find the greatest alpha.
+     975          43 :     double greatest_alpha = 0.0;
+     976          43 :     if (welltemp_) greatest_alpha = std::max(greatest_alpha, 1.0);
+     977          45 :     if (dampfactor_ > 0.0) greatest_alpha = std::max(greatest_alpha, 1.0);
+     978          46 :     if (tt_specs_.is_active) greatest_alpha = std::max(greatest_alpha, tt_specs_.alpha);
+     979             :     // Find the least alpha.
+     980          43 :     double least_alpha = 1.0;
+     981             :     if (welltemp_) least_alpha = std::min(least_alpha, 1.0);
+     982          43 :     if (dampfactor_ > 0.0) least_alpha = std::min(least_alpha, 1.0);
+     983          44 :     if (tt_specs_.is_active) least_alpha = std::min(least_alpha, tt_specs_.alpha);
+     984             :     // Find the inverse harmonic average of the delta T parameters for all
+     985             :     // of the temperings with the greatest alpha values.
+     986             :     double total_governing_deltaT_inv = 0.0;
+     987          43 :     if (welltemp_ && 1.0 == greatest_alpha && biasf_ != 1.0) total_governing_deltaT_inv += 1.0 / (biasf_ - 1.0);
+     988          43 :     if (dampfactor_ > 0.0 && 1.0 == greatest_alpha) total_governing_deltaT_inv += 1.0 / (dampfactor_);
+     989          43 :     if (tt_specs_.is_active && tt_specs_.alpha == greatest_alpha) total_governing_deltaT_inv += 1.0 / (tt_specs_.biasf - 1.0);
+     990             :     // Give a newbie-friendly error message for people using one tempering if
+     991             :     // only one is active.
+     992          43 :     if (n_active == 1 && total_governing_deltaT_inv < 0.0) {
+     993           0 :       error("for stable tempering, the bias factor must be greater than one");
+     994             :       // Give a slightly more complex error message to users stacking multiple
+     995             :       // tempering options at a time, but all with uniform alpha values.
+     996          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha == least_alpha) {
+     997           0 :       error("for stable tempering, the sum of the inverse Delta T parameters must be greater than zero!");
+     998             :       // Give the most technical error message to users stacking multiple tempering
+     999             :       // options with different alpha parameters.
+    1000          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha != least_alpha) {
+    1001           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!");
+    1002             :     }
+    1003             :   }
+    1004             : 
+    1005         148 :   if(doInt_) log.printf("  Upper and Lower limits boundaries for the bias are activated at %f - %f\n", lowI_, uppI_);
+    1006             : 
+    1007         148 :   if(grid_) {
+    1008          60 :     log.printf("  Grid min");
+    1009         161 :     for(unsigned i=0; i<gmin.size(); ++i) log.printf(" %s",gmin[i].c_str() );
+    1010          60 :     log.printf("\n");
+    1011          60 :     log.printf("  Grid max");
+    1012         161 :     for(unsigned i=0; i<gmax.size(); ++i) log.printf(" %s",gmax[i].c_str() );
+    1013          60 :     log.printf("\n");
+    1014          60 :     log.printf("  Grid bin");
+    1015         161 :     for(unsigned i=0; i<gbin.size(); ++i) log.printf(" %u",gbin[i]);
+    1016          60 :     log.printf("\n");
+    1017          60 :     if(spline) {log.printf("  Grid uses spline interpolation\n");}
+    1018          60 :     if(sparsegrid) {log.printf("  Grid uses sparse grid\n");}
+    1019          60 :     if(wgridstride_>0) {log.printf("  Grid is written on file %s with stride %d\n",gridfilename_.c_str(),wgridstride_);}
+    1020             :   }
+    1021             : 
+    1022         148 :   if(mw_n_>1) {
+    1023           6 :     if(walkers_mpi_) error("MPI version of multiple walkers is not compatible with filesystem version of multiple walkers");
+    1024           6 :     log.printf("  %d multiple walkers active\n",mw_n_);
+    1025           6 :     log.printf("  walker id %d\n",mw_id_);
+    1026           6 :     log.printf("  reading stride %d\n",mw_rstride_);
+    1027           6 :     if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1028             :   } else {
+    1029         142 :     if(walkers_mpi_) {
+    1030          38 :       log.printf("  Multiple walkers active using MPI communnication\n");
+    1031          38 :       if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1032          38 :       if(comm.Get_rank()==0) {
+    1033             :         // Only root of group can communicate with other walkers
+    1034          23 :         mpi_nw_=multi_sim_comm.Get_size();
+    1035             :       }
+    1036             :       // Communicate to the other members of the same group
+    1037             :       // info abount number of walkers and walker index
+    1038          38 :       comm.Bcast(mpi_nw_,0);
+    1039             :     }
+    1040             :   }
+    1041             : 
+    1042         148 :   if(flying_) {
+    1043           6 :     if(!walkers_mpi_) error("Flying Gaussian method must be used with MPI version of multiple walkers");
+    1044           6 :     log.printf("  Flying Gaussian method with %d walkers active\n",mpi_nw_);
+    1045             :   }
+    1046             : 
+    1047         148 :   if(nlist_) {
+    1048           1 :     addComponent("nlker");
+    1049           1 :     componentIsNotPeriodic("nlker");
+    1050           1 :     addComponent("nlsteps");
+    1051           2 :     componentIsNotPeriodic("nlsteps");
+    1052             :   }
+    1053             : 
+    1054         148 :   if(calc_rct_) {
+    1055          12 :     addComponent("rbias"); componentIsNotPeriodic("rbias");
+    1056          12 :     addComponent("rct"); componentIsNotPeriodic("rct");
+    1057           6 :     log.printf("  The c(t) reweighting factor will be calculated every %u hills\n",rct_ustride_);
+    1058          12 :     getPntrToComponent("rct")->set(reweight_factor_);
+    1059             :   }
+    1060             : 
+    1061         150 :   if(calc_work_) { addComponent("work"); componentIsNotPeriodic("work"); }
+    1062             : 
+    1063         148 :   if(acceleration_) {
+    1064           4 :     if (kbt_ == 0.0) {
+    1065           0 :       error("The calculation of the acceleration works only if simulation temperature has been defined");
+    1066             :     }
+    1067           4 :     log.printf("  calculation on the fly of the acceleration factor\n");
+    1068          12 :     addComponent("acc"); componentIsNotPeriodic("acc");
+    1069             :     // Set the initial value of the the acceleration.
+    1070             :     // If this is not a restart, set to 1.0.
+    1071           4 :     if (acc_rfilename.length() == 0) {
+    1072           4 :       getPntrToComponent("acc")->set(1.0);
+    1073           2 :       if(getRestart()) {
+    1074           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");
+    1075           1 :         log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1076             :       }
+    1077             :       // Otherwise, read and set the restart value.
+    1078             :     } else {
+    1079             :       // Restart of acceleration does not make sense if the restart timestep is zero.
+    1080             :       //if (getStep() == 0) {
+    1081             :       //  error("Restarting calculation of acceleration factors works only if simulation timestep is restarted correctly");
+    1082             :       //}
+    1083             :       // Open the ACCELERATION_RFILE.
+    1084           2 :       IFile acc_rfile;
+    1085           2 :       acc_rfile.link(*this);
+    1086           2 :       if(acc_rfile.FileExist(acc_rfilename)) {
+    1087           2 :         acc_rfile.open(acc_rfilename);
+    1088             :       } else {
+    1089           0 :         error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", cannot be found!");
+    1090             :       }
+    1091             :       // Read the file to find the restart acceleration.
+    1092           2 :       double acc_rmean=0.0;
+    1093           2 :       double acc_rtime=0.0;
+    1094             :       bool found=false;
+    1095           2 :       std::string acclabel = getLabel() + ".acc";
+    1096           2 :       acc_rfile.allowIgnoredFields();
+    1097         248 :       while(acc_rfile.scanField("time", acc_rtime)) {
+    1098         122 :         acc_rfile.scanField(acclabel, acc_rmean);
+    1099         122 :         acc_rfile.scanField();
+    1100             :         found=true;
+    1101             :       }
+    1102           2 :       if(!found) error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", does not contain a time field!");
+    1103           2 :       acc_restart_mean_ = acc_rmean;
+    1104             :       // Set component based on the read values.
+    1105           2 :       getPntrToComponent("acc")->set(acc_rmean);
+    1106           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);
+    1107           2 :     }
+    1108             :   }
+    1109             : 
+    1110         148 :   if (calc_max_bias_) {
+    1111           0 :     if (!grid_) error("Calculating the maximum bias on the fly works only with a grid");
+    1112           0 :     log.printf("  calculation on the fly of the maximum bias max(V(s,t)) \n");
+    1113           0 :     addComponent("maxbias");
+    1114           0 :     componentIsNotPeriodic("maxbias");
+    1115             :   }
+    1116             : 
+    1117         148 :   if (calc_transition_bias_) {
+    1118          13 :     if (!grid_) error("Calculating the transition bias on the fly works only with a grid");
+    1119          13 :     log.printf("  calculation on the fly of the transition bias V*(t)\n");
+    1120          13 :     addComponent("transbias");
+    1121          13 :     componentIsNotPeriodic("transbias");
+    1122          13 :     log<<"  Number of transition wells "<<transitionwells_.size()<<"\n";
+    1123          13 :     if (transitionwells_.size() == 0) error("Calculating the transition bias on the fly requires definition of at least one transition well");
+    1124             :     // Check that a grid is in use.
+    1125          13 :     if (!grid_) error(" transition barrier finding requires a grid for the bias");
+    1126             :     // Log the wells and check that they are in the grid.
+    1127          39 :     for (unsigned i = 0; i < transitionwells_.size(); i++) {
+    1128             :       // Log the coordinate.
+    1129          26 :       log.printf("  Transition well %d at coordinate ", i);
+    1130          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) log.printf("%f ", transitionwells_[i][j]);
+    1131          26 :       log.printf("\n");
+    1132             :       // Check that the coordinate is in the grid.
+    1133          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) {
+    1134             :         double max, min;
+    1135          38 :         Tools::convert(gmin[j], min);
+    1136          38 :         Tools::convert(gmax[j], max);
+    1137          38 :         if (transitionwells_[i][j] < min || transitionwells_[i][j] > max) error(" transition well is not in grid");
+    1138             :       }
+    1139             :     }
+    1140             :   }
+    1141             : 
+    1142         148 :   if(freq_adaptive_) {
+    1143           2 :     if(!acceleration_) {
+    1144           0 :       plumed_merror("Frequency adaptive metadynamics only works if the calculation of the acceleration factor is enabled with the ACCELERATION keyword\n");
+    1145             :     }
+    1146           2 :     if(walkers_mpi_) {
+    1147           0 :       plumed_merror("Combining frequency adaptive metadynamics with MPI multiple walkers is not allowed");
+    1148             :     }
+    1149             : 
+    1150           2 :     log.printf("  Frequency adaptive metadynamics enabled\n");
+    1151           2 :     if(getRestart() && acc_rfilename.length() == 0) {
+    1152           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");
+    1153           0 :       log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1154             :     }
+    1155           2 :     log.printf("  The frequency for hill addition will change dynamically based on the metadynamics acceleration factor\n");
+    1156           2 :     log.printf("  The hill addition frequency will be updated every %d steps\n",fa_update_frequency_);
+    1157           2 :     if(fa_min_acceleration_>1.0) {
+    1158           2 :       log.printf("  The hill addition frequency will only be updated once the metadynamics acceleration factor becomes larger than %.1f \n",fa_min_acceleration_);
+    1159             :     }
+    1160           2 :     if(fa_max_stride_!=0) {
+    1161           2 :       log.printf("  The hill addition frequency will not become larger than %d steps\n",fa_max_stride_);
+    1162             :     }
+    1163           4 :     addComponent("pace"); componentIsNotPeriodic("pace");
+    1164           2 :     updateFrequencyAdaptiveStride();
+    1165             :   }
+    1166             : 
+    1167             :   // initializing and checking grid
+    1168             :   bool restartedFromGrid=false;  // restart from grid file
+    1169         148 :   if(grid_) {
+    1170          60 :     if(!(gridreadfilename_.length()>0)) {
+    1171             :       // check for mesh and sigma size
+    1172         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1173             :         double a,b;
+    1174          74 :         Tools::convert(gmin[i],a);
+    1175          74 :         Tools::convert(gmax[i],b);
+    1176          74 :         double mesh=(b-a)/((double)gbin[i]);
+    1177          74 :         if(adaptive_==FlexibleBin::none) {
+    1178          74 :           if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a METAD with a Grid Spacing larger than half of the Gaussians width (SIGMA) can produce artifacts\n";
+    1179             :         } else {
+    1180           0 :           if(sigma0min_[i]<0.) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+    1181           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";
+    1182             :         }
+    1183             :       }
+    1184          42 :       std::string funcl=getLabel() + ".bias";
+    1185          42 :       if(!sparsegrid) {BiasGrid_=Tools::make_unique<Grid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1186           6 :       else {BiasGrid_=Tools::make_unique<SparseGrid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1187          42 :       std::vector<std::string> actualmin=BiasGrid_->getMin();
+    1188          42 :       std::vector<std::string> actualmax=BiasGrid_->getMax();
+    1189         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1190             :         std::string is;
+    1191          74 :         Tools::convert(i,is);
+    1192          74 :         if(gmin[i]!=actualmin[i]) error("GRID_MIN["+is+"] must be adjusted to "+actualmin[i]+" to fit periodicity");
+    1193          74 :         if(gmax[i]!=actualmax[i]) error("GRID_MAX["+is+"] must be adjusted to "+actualmax[i]+" to fit periodicity");
+    1194             :       }
+    1195          42 :     } else {
+    1196             :       // read the grid in input, find the keys
+    1197             : #ifdef __PLUMED_HAS_GETCWD
+    1198          18 :       if(walkers_mpi_&&gridreadfilename_.at(0)!='/') {
+    1199             :         //if possible the root replica will share its current folder so that all walkers will read the same file
+    1200           0 :         char cwd[4096]= {0};
+    1201             :         const char* ret=getcwd(cwd,4096);
+    1202           0 :         plumed_assert(ret)<<"Name of current directory too long, increase buffer size";
+    1203           0 :         gridreadfilename_ = "/" + gridreadfilename_;
+    1204           0 :         gridreadfilename_ = ret + gridreadfilename_;
+    1205           0 :         if(comm.Get_rank()==0) multi_sim_comm.Bcast(gridreadfilename_,0);
+    1206           0 :         comm.Bcast(gridreadfilename_,0);
+    1207             :       }
+    1208             : #endif
+    1209          18 :       IFile gridfile;
+    1210          18 :       gridfile.link(*this);
+    1211          18 :       if(gridfile.FileExist(gridreadfilename_)) {
+    1212          18 :         gridfile.open(gridreadfilename_);
+    1213             :       } else {
+    1214           0 :         error("The GRID file you want to read: " + gridreadfilename_ + ", cannot be found!");
+    1215             :       }
+    1216          18 :       std::string funcl=getLabel() + ".bias";
+    1217          36 :       BiasGrid_=GridBase::create(funcl, getArguments(), gridfile, gmin, gmax, gbin, sparsegrid, spline, true);
+    1218          18 :       if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1219          45 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1220          54 :         if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1221             :         double a, b;
+    1222          27 :         Tools::convert(gmin[i],a);
+    1223          27 :         Tools::convert(gmax[i],b);
+    1224          27 :         double mesh=(b-a)/((double)gbin[i]);
+    1225          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";
+    1226             :       }
+    1227          18 :       log.printf("  Restarting from %s\n",gridreadfilename_.c_str());
+    1228          18 :       if(getRestart()) restartedFromGrid=true;
+    1229          18 :     }
+    1230             :   }
+    1231             : 
+    1232             :   // if we are restarting from GRID and using WALKERS_MPI we can check that all walkers have actually read the grid
+    1233         148 :   if(getRestart()&&walkers_mpi_) {
+    1234           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1235           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromGrid), restarted);
+    1236           9 :     comm.Bcast(restarted,0);
+    1237             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1238           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from GRID while other do not!");
+    1239             :   }
+    1240             : 
+    1241             : #ifdef __PLUMED_HAS_GETCWD
+    1242         186 :   if(walkers_mpi_&&mw_dir_==""&&hillsfname.at(0)!='/') {
+    1243             :     //if possible the root replica will share its current folder so that all walkers will read the same file
+    1244          38 :     char cwd[4096]= {0};
+    1245             :     const char* ret=getcwd(cwd,4096);
+    1246          38 :     plumed_assert(ret)<<"Name of current directory too long, increase buffer size";
+    1247             :     mw_dir_ = ret;
+    1248          38 :     mw_dir_ = mw_dir_ + "/";
+    1249          38 :     if(comm.Get_rank()==0) multi_sim_comm.Bcast(mw_dir_,0);
+    1250          38 :     comm.Bcast(mw_dir_,0);
+    1251             :   }
+    1252             : #endif
+    1253             : 
+    1254             :   // creating std::vector of ifile* for hills reading
+    1255             :   // open all files at the beginning and read Gaussians if restarting
+    1256             :   bool restartedFromHills=false;  // restart from hills files
+    1257         308 :   for(int i=0; i<mw_n_; ++i) {
+    1258             :     std::string fname;
+    1259         160 :     if(mw_dir_!="") {
+    1260          47 :       if(mw_n_>1) {
+    1261           9 :         std::stringstream out; out << i;
+    1262          18 :         fname = mw_dir_+"/"+hillsfname+"."+out.str();
+    1263          47 :       } else if(walkers_mpi_) {
+    1264          76 :         fname = mw_dir_+"/"+hillsfname;
+    1265             :       } else {
+    1266             :         fname = hillsfname;
+    1267             :       }
+    1268             :     } else {
+    1269         113 :       if(mw_n_>1) {
+    1270           9 :         std::stringstream out; out << i;
+    1271          18 :         fname = hillsfname+"."+out.str();
+    1272           9 :       } else {
+    1273             :         fname = hillsfname;
+    1274             :       }
+    1275             :     }
+    1276         160 :     ifiles_.emplace_back(Tools::make_unique<IFile>());
+    1277             :     // this is just a shortcut pointer to the last element:
+    1278             :     IFile *ifile = ifiles_.back().get();
+    1279         160 :     ifilesnames_.push_back(fname);
+    1280         160 :     ifile->link(*this);
+    1281         160 :     if(ifile->FileExist(fname)) {
+    1282          36 :       ifile->open(fname);
+    1283          36 :       if(getRestart()&&!restartedFromGrid) {
+    1284          19 :         log.printf("  Restarting from %s:",ifilesnames_[i].c_str());
+    1285          19 :         readGaussians(ifiles_[i].get());
+    1286             :         restartedFromHills=true;
+    1287             :       }
+    1288          36 :       ifiles_[i]->reset(false);
+    1289             :       // close only the walker own hills file for later writing
+    1290          36 :       if(i==mw_id_) ifiles_[i]->close();
+    1291             :     } else {
+    1292             :       // in case a file does not exist and we are restarting, complain that the file was not found
+    1293         124 :       if(getRestart()&&!restartedFromGrid) error("restart file "+fname+" not found");
+    1294             :     }
+    1295             :   }
+    1296             : 
+    1297             :   // if we are restarting from FILE and using WALKERS_MPI we can check that all walkers have actually read the FILE
+    1298         148 :   if(getRestart()&&walkers_mpi_) {
+    1299           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1300           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromHills), restarted);
+    1301           9 :     comm.Bcast(restarted,0);
+    1302             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1303           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from FILE while other do not!");
+    1304             :   }
+    1305             : 
+    1306         148 :   comm.Barrier();
+    1307             :   // this barrier is needed when using walkers_mpi
+    1308             :   // to be sure that all files have been read before
+    1309             :   // backing them up
+    1310             :   // it should not be used when walkers_mpi is false otherwise
+    1311             :   // it would introduce troubles when using replicas without METAD
+    1312             :   // (e.g. in bias exchange with a neutral replica)
+    1313             :   // see issue #168 on github
+    1314         148 :   if(comm.Get_rank()==0 && walkers_mpi_) multi_sim_comm.Barrier();
+    1315             : 
+    1316         148 :   if(targetfilename_.length()>0) {
+    1317           2 :     IFile gridfile; gridfile.open(targetfilename_);
+    1318           2 :     std::string funcl=getLabel() + ".target";
+    1319           4 :     TargetGrid_=GridBase::create(funcl,getArguments(),gridfile,false,false,true);
+    1320           2 :     if(TargetGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1321           4 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1322           4 :       if( getPntrToArgument(i)->isPeriodic()!=TargetGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1323             :     }
+    1324           2 :   }
+    1325             : 
+    1326         148 :   if(getRestart()) {
+    1327             :     // if this is a restart the neighbor list should be immediately updated
+    1328          37 :     if(nlist_) nlist_update_=true;
+    1329             :     // Calculate the Tiwary-Parrinello reweighting factor if we are restarting from previous hills
+    1330          37 :     if(calc_rct_) computeReweightingFactor();
+    1331             :     // Calculate all special bias quantities desired if restarting with nonzero bias.
+    1332          37 :     if(calc_max_bias_) {
+    1333           0 :       max_bias_ = BiasGrid_->getMaxValue();
+    1334           0 :       getPntrToComponent("maxbias")->set(max_bias_);
+    1335             :     }
+    1336          37 :     if(calc_transition_bias_) {
+    1337          13 :       transition_bias_ = getTransitionBarrierBias();
+    1338          26 :       getPntrToComponent("transbias")->set(transition_bias_);
+    1339             :     }
+    1340             :   }
+    1341             : 
+    1342             :   // open grid file for writing
+    1343         148 :   if(wgridstride_>0) {
+    1344          19 :     gridfile_.link(*this);
+    1345          19 :     if(walkers_mpi_) {
+    1346           0 :       int r=0;
+    1347           0 :       if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1348           0 :       comm.Bcast(r,0);
+    1349           0 :       if(r>0) gridfilename_="/dev/null";
+    1350           0 :       gridfile_.enforceSuffix("");
+    1351             :     }
+    1352          19 :     if(mw_n_>1) gridfile_.enforceSuffix("");
+    1353          19 :     gridfile_.open(gridfilename_);
+    1354             :   }
+    1355             : 
+    1356             :   // open hills file for writing
+    1357         148 :   hillsOfile_.link(*this);
+    1358         148 :   if(walkers_mpi_) {
+    1359          38 :     int r=0;
+    1360          38 :     if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1361          38 :     comm.Bcast(r,0);
+    1362          38 :     if(r>0) ifilesnames_[mw_id_]="/dev/null";
+    1363          76 :     hillsOfile_.enforceSuffix("");
+    1364             :   }
+    1365         154 :   if(mw_n_>1) hillsOfile_.enforceSuffix("");
+    1366         148 :   hillsOfile_.open(ifilesnames_[mw_id_]);
+    1367         148 :   if(fmt_.length()>0) hillsOfile_.fmtField(fmt_);
+    1368         148 :   hillsOfile_.addConstantField("multivariate");
+    1369         148 :   hillsOfile_.addConstantField("kerneltype");
+    1370         148 :   if(doInt_) {
+    1371           4 :     hillsOfile_.addConstantField("lower_int").printField("lower_int",lowI_);
+    1372           4 :     hillsOfile_.addConstantField("upper_int").printField("upper_int",uppI_);
+    1373             :   }
+    1374             :   hillsOfile_.setHeavyFlush();
+    1375             :   // output periodicities of variables
+    1376         415 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) hillsOfile_.setupPrintValue( getPntrToArgument(i) );
+    1377             : 
+    1378             :   bool concurrent=false;
+    1379         148 :   const ActionSet&actionSet(plumed.getActionSet());
+    1380         541 :   for(const auto & p : actionSet) if(dynamic_cast<MetaD*>(p.get())) { concurrent=true; break; }
+    1381         148 :   if(concurrent) log<<"  You are using concurrent metadynamics\n";
+    1382         148 :   if(rect_biasf_.size()>0) {
+    1383          18 :     if(walkers_mpi_) {
+    1384          12 :       log<<"  You are using RECT in its 'altruistic' implementation\n";
+    1385             :     }{
+    1386          18 :       log<<"  You are using RECT\n";
+    1387             :     }
+    1388             :   }
+    1389             : 
+    1390         296 :   log<<"  Bibliography "<<plumed.cite("Laio and Parrinello, PNAS 99, 12562 (2002)");
+    1391         186 :   if(welltemp_) log<<plumed.cite("Barducci, Bussi, and Parrinello, Phys. Rev. Lett. 100, 020603 (2008)");
+    1392         148 :   if(tt_specs_.is_active) {
+    1393           6 :     log << plumed.cite("Dama, Rotskoff, Parrinello, and Voth, J. Chem. Theory Comput. 10, 3626 (2014)");
+    1394           6 :     log << plumed.cite("Dama, Parrinello, and Voth, Phys. Rev. Lett. 112, 240602 (2014)");
+    1395             :   }
+    1396         192 :   if(mw_n_>1||walkers_mpi_) log<<plumed.cite("Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
+    1397         169 :   if(adaptive_!=FlexibleBin::none) log<<plumed.cite("Branduardi, Bussi, and Parrinello, J. Chem. Theory Comput. 8, 2247 (2012)");
+    1398         150 :   if(doInt_) log<<plumed.cite("Baftizadeh, Cossio, Pietrucci, and Laio, Curr. Phys. Chem. 2, 79 (2012)");
+    1399         152 :   if(acceleration_) log<<plumed.cite("Pratyush and Parrinello, Phys. Rev. Lett. 111, 230602 (2013)");
+    1400         154 :   if(calc_rct_) log<<plumed.cite("Pratyush and Parrinello, J. Phys. Chem. B, 119, 736 (2015)");
+    1401         228 :   if(concurrent || rect_biasf_.size()>0) log<<plumed.cite("Gil-Ley and Bussi, J. Chem. Theory Comput. 11, 1077 (2015)");
+    1402         160 :   if(rect_biasf_.size()>0 && walkers_mpi_) log<<plumed.cite("Hosek, Toulcova, Bortolato, and Spiwok, J. Phys. Chem. B 120, 2209 (2016)");
+    1403         148 :   if(targetfilename_.length()>0) {
+    1404           4 :     log<<plumed.cite("White, Dama, and Voth, J. Chem. Theory Comput. 11, 2451 (2015)");
+    1405           4 :     log<<plumed.cite("Marinelli and Faraldo-GoÌmez,  Biophys. J. 108, 2779 (2015)");
+    1406           4 :     log<<plumed.cite("Gil-Ley, Bottaro, and Bussi, J. Chem. Theory Comput. 12, 2790 (2016)");
+    1407             :   }
+    1408         150 :   if(freq_adaptive_) log<<plumed.cite("Wang, Valsson, Tiwary, Parrinello, and Lindorff-Larsen, J. Chem. Phys. 149, 072309 (2018)");
+    1409         148 :   log<<"\n";
+    1410         396 : }
+    1411             : 
+    1412         151 : void MetaD::readTemperingSpecs(TemperingSpecs &t_specs)
+    1413             : {
+    1414             :   // Set global tempering parameters.
+    1415         151 :   parse(t_specs.name_stem + "BIASFACTOR", t_specs.biasf);
+    1416         151 :   if (t_specs.biasf != -1.0) {
+    1417           3 :     if (kbt_ == 0.0) {
+    1418           0 :       error("Unless the MD engine passes the temperature to plumed, with tempered metad you must specify it using TEMP");
+    1419             :     }
+    1420           3 :     if (t_specs.biasf == 1.0) {
+    1421           0 :       error("A bias factor of 1 corresponds to zero delta T and zero hill size, so it is not allowed.");
+    1422             :     }
+    1423           3 :     t_specs.is_active = true;
+    1424           3 :     parse(t_specs.name_stem + "BIASTHRESHOLD", t_specs.threshold);
+    1425           3 :     if (t_specs.threshold < 0.0) {
+    1426           0 :       error(t_specs.name + " bias threshold is nonsensical");
+    1427             :     }
+    1428           3 :     parse(t_specs.name_stem + "ALPHA", t_specs.alpha);
+    1429           3 :     if (t_specs.alpha <= 0.0 || t_specs.alpha > 1.0) {
+    1430           0 :       error(t_specs.name + " decay shape parameter alpha is nonsensical");
+    1431             :     }
+    1432             :   }
+    1433         151 : }
+    1434             : 
+    1435           3 : void MetaD::logTemperingSpecs(const TemperingSpecs &t_specs)
+    1436             : {
+    1437           3 :   log.printf("  %s bias factor %f\n", t_specs.name.c_str(), t_specs.biasf);
+    1438           3 :   log.printf("  KbT %f\n", kbt_);
+    1439           3 :   if (t_specs.threshold != 0.0) log.printf("  %s bias threshold %f\n", t_specs.name.c_str(), t_specs.threshold);
+    1440           3 :   if (t_specs.alpha != 1.0) log.printf("  %s decay shape parameter alpha %f\n", t_specs.name.c_str(), t_specs.alpha);
+    1441           3 : }
+    1442             : 
+    1443        6037 : void MetaD::readGaussians(IFile *ifile)
+    1444             : {
+    1445        6037 :   unsigned ncv=getNumberOfArguments();
+    1446        6037 :   std::vector<double> center(ncv);
+    1447        6037 :   std::vector<double> sigma(ncv);
+    1448             :   double height;
+    1449             :   int nhills=0;
+    1450        6037 :   bool multivariate=false;
+    1451             : 
+    1452             :   std::vector<Value> tmpvalues;
+    1453       18124 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) tmpvalues.push_back( Value( this, getPntrToArgument(j)->getName(), false ) );
+    1454             : 
+    1455        8542 :   while(scanOneHill(ifile,tmpvalues,center,sigma,height,multivariate))
+    1456             :   {
+    1457        2505 :     nhills++;
+    1458             :     // note that for gamma=1 we store directly -F
+    1459        2505 :     if(welltemp_ && biasf_>1.0) height*=(biasf_-1.0)/biasf_;
+    1460        2505 :     addGaussian(Gaussian(multivariate,height,center,sigma));
+    1461             :   }
+    1462        6037 :   log.printf("      %d Gaussians read\n",nhills);
+    1463       12074 : }
+    1464             : 
+    1465        2922 : void MetaD::writeGaussian(const Gaussian& hill, OFile&file)
+    1466             : {
+    1467        2922 :   unsigned ncv=getNumberOfArguments();
+    1468        2922 :   file.printField("time",getTimeStep()*getStep());
+    1469        8194 :   for(unsigned i=0; i<ncv; ++i) {
+    1470        5272 :     file.printField(getPntrToArgument(i),hill.center[i]);
+    1471             :   }
+    1472        5844 :   hillsOfile_.printField("kerneltype","stretched-gaussian");
+    1473        2922 :   if(hill.multivariate) {
+    1474         892 :     hillsOfile_.printField("multivariate","true");
+    1475             :     Matrix<double> mymatrix(ncv,ncv);
+    1476             :     unsigned k=0;
+    1477        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1478        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1479             :         // recompose the full inverse matrix
+    1480         756 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1481         756 :         k++;
+    1482             :       }
+    1483             :     }
+    1484             :     // invert it
+    1485             :     Matrix<double> invmatrix(ncv,ncv);
+    1486         446 :     Invert(mymatrix,invmatrix);
+    1487             :     // enforce symmetry
+    1488        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1489        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1490         756 :         invmatrix(i,j)=invmatrix(j,i);
+    1491             :       }
+    1492             :     }
+    1493             : 
+    1494             :     // do cholesky so to have a "sigma like" number
+    1495             :     Matrix<double> lower(ncv,ncv);
+    1496         446 :     cholesky(invmatrix,lower);
+    1497             :     // loop in band form
+    1498        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1499        1357 :       for(unsigned j=0; j<ncv-i; j++) {
+    1500        1512 :         file.printField("sigma_"+getPntrToArgument(j+i)->getName()+"_"+getPntrToArgument(j)->getName(),lower(j+i,j));
+    1501             :       }
+    1502             :     }
+    1503             :   } else {
+    1504        4952 :     hillsOfile_.printField("multivariate","false");
+    1505        7147 :     for(unsigned i=0; i<ncv; ++i)
+    1506        9342 :       file.printField("sigma_"+getPntrToArgument(i)->getName(),hill.sigma[i]);
+    1507             :   }
+    1508        2922 :   double height=hill.height;
+    1509             :   // note that for gamma=1 we store directly -F
+    1510        2922 :   if(welltemp_ && biasf_>1.0) height*=biasf_/(biasf_-1.0);
+    1511        5844 :   file.printField("height",height).printField("biasf",biasf_);
+    1512        4431 :   if(mw_n_>1) file.printField("clock",int(std::time(0)));
+    1513        2922 :   file.printField();
+    1514        2922 : }
+    1515             : 
+    1516        5589 : void MetaD::addGaussian(const Gaussian& hill)
+    1517             : {
+    1518        5589 :   if(grid_) {
+    1519         640 :     size_t ncv=getNumberOfArguments();
+    1520         640 :     std::vector<unsigned> nneighb=getGaussianSupport(hill);
+    1521         640 :     std::vector<Grid::index_t> neighbors=BiasGrid_->getNeighbors(hill.center,nneighb);
+    1522         640 :     std::vector<double> der(ncv);
+    1523         640 :     std::vector<double> xx(ncv);
+    1524         640 :     if(comm.Get_size()==1) {
+    1525             :       // for performance reasons and thread safety
+    1526         544 :       std::vector<double> dp(ncv);
+    1527       55324 :       for(size_t i=0; i<neighbors.size(); ++i) {
+    1528       54780 :         Grid::index_t ineigh=neighbors[i];
+    1529      158922 :         for(unsigned j=0; j<ncv; ++j) der[j]=0.0;
+    1530       54780 :         BiasGrid_->getPoint(ineigh,xx);
+    1531       54780 :         double bias=evaluateGaussianAndDerivatives(xx,hill,der,dp);
+    1532       54780 :         BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
+    1533             :       }
+    1534             :     } else {
+    1535          96 :       unsigned stride=comm.Get_size();
+    1536          96 :       unsigned rank=comm.Get_rank();
+    1537          96 :       std::vector<double> allder(ncv*neighbors.size(),0.0);
+    1538          96 :       std::vector<double> n_der(ncv,0.0);
+    1539          96 :       std::vector<double> allbias(neighbors.size(),0.0);
+    1540             :       // for performance reasons and thread safety
+    1541          96 :       std::vector<double> dp(ncv);
+    1542       27148 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+    1543       27052 :         Grid::index_t ineigh=neighbors[i];
+    1544       81156 :         for(unsigned j=0; j<ncv; ++j) n_der[j]=0.0;
+    1545       27052 :         BiasGrid_->getPoint(ineigh,xx);
+    1546       27052 :         allbias[i]=evaluateGaussianAndDerivatives(xx,hill,n_der,dp);
+    1547       81156 :         for(unsigned j=0; j<ncv; j++) allder[ncv*i+j]=n_der[j];
+    1548             :       }
+    1549          96 :       comm.Sum(allbias);
+    1550          96 :       comm.Sum(allder);
+    1551      103200 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+    1552      103104 :         Grid::index_t ineigh=neighbors[i];
+    1553      309312 :         for(unsigned j=0; j<ncv; ++j) der[j]=allder[ncv*i+j];
+    1554      103104 :         BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
+    1555             :       }
+    1556             :     }
+    1557        4949 :   } else hills_.push_back(hill);
+    1558        5589 : }
+    1559             : 
+    1560         640 : std::vector<unsigned> MetaD::getGaussianSupport(const Gaussian& hill)
+    1561             : {
+    1562             :   std::vector<unsigned> nneigh;
+    1563             :   std::vector<double> cutoff;
+    1564         640 :   unsigned ncv=getNumberOfArguments();
+    1565             : 
+    1566             :   // traditional or flexible hill?
+    1567         640 :   if(hill.multivariate) {
+    1568             :     unsigned k=0;
+    1569             :     Matrix<double> mymatrix(ncv,ncv);
+    1570           0 :     for(unsigned i=0; i<ncv; i++) {
+    1571           0 :       for(unsigned j=i; j<ncv; j++) {
+    1572             :         // recompose the full inverse matrix
+    1573           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1574           0 :         k++;
+    1575             :       }
+    1576             :     }
+    1577             :     // Reinvert so to have the ellipses
+    1578             :     Matrix<double> myinv(ncv,ncv);
+    1579           0 :     Invert(mymatrix,myinv);
+    1580             :     Matrix<double> myautovec(ncv,ncv);
+    1581           0 :     std::vector<double> myautoval(ncv); //should I take this or their square root?
+    1582           0 :     diagMat(myinv,myautoval,myautovec);
+    1583             :     double maxautoval=0.;
+    1584             :     unsigned ind_maxautoval; ind_maxautoval=ncv;
+    1585           0 :     for(unsigned i=0; i<ncv; i++) {
+    1586           0 :       if(myautoval[i]>maxautoval) {maxautoval=myautoval[i]; ind_maxautoval=i;}
+    1587             :     }
+    1588           0 :     for(unsigned i=0; i<ncv; i++) {
+    1589           0 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*std::abs(std::sqrt(maxautoval)*myautovec(i,ind_maxautoval)));
+    1590             :     }
+    1591             :   } else {
+    1592        1618 :     for(unsigned i=0; i<ncv; ++i) {
+    1593         978 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*hill.sigma[i]);
+    1594             :     }
+    1595             :   }
+    1596             : 
+    1597         640 :   if(doInt_) {
+    1598           2 :     if(hill.center[0]+cutoff[0] > uppI_ || hill.center[0]-cutoff[0] < lowI_) {
+    1599             :       // in this case, we updated the entire grid to avoid problems
+    1600           2 :       return BiasGrid_->getNbin();
+    1601             :     } else {
+    1602           0 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[0]/BiasGrid_->getDx()[0])) );
+    1603             :       return nneigh;
+    1604             :     }
+    1605             :   } else {
+    1606        1614 :     for(unsigned i=0; i<ncv; i++) {
+    1607         976 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[i]/BiasGrid_->getDx()[i])) );
+    1608             :     }
+    1609             :   }
+    1610             : 
+    1611             :   return nneigh;
+    1612             : }
+    1613             : 
+    1614         285 : double MetaD::getBias(const std::vector<double>& cv)
+    1615             : {
+    1616         285 :   double bias=0.0;
+    1617         285 :   if(grid_) bias = BiasGrid_->getValue(cv);
+    1618             :   else {
+    1619          82 :     unsigned nt=OpenMP::getNumThreads();
+    1620          82 :     unsigned stride=comm.Get_size();
+    1621          82 :     unsigned rank=comm.Get_rank();
+    1622             : 
+    1623          82 :     if(!nlist_) {
+    1624          82 :       #pragma omp parallel num_threads(nt)
+    1625             :       {
+    1626             :         #pragma omp for reduction(+:bias) nowait
+    1627             :         for(unsigned i=rank; i<hills_.size(); i+=stride) bias+=evaluateGaussian(cv,hills_[i]);
+    1628             :       }
+    1629             :     } else {
+    1630           0 :       #pragma omp parallel num_threads(nt)
+    1631             :       {
+    1632             :         #pragma omp for reduction(+:bias) nowait
+    1633             :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) bias+=evaluateGaussian(cv,nlist_hills_[i]);
+    1634             :       }
+    1635             :     }
+    1636          82 :     comm.Sum(bias);
+    1637             :   }
+    1638             : 
+    1639         285 :   return bias;
+    1640             : }
+    1641             : 
+    1642        8395 : double MetaD::getBiasAndDerivatives(const std::vector<double>& cv, std::vector<double>& der)
+    1643             : {
+    1644        8395 :   unsigned ncv=getNumberOfArguments();
+    1645        8395 :   double bias=0.0;
+    1646        8395 :   if(grid_) {
+    1647        1506 :     std::vector<double> vder(ncv);
+    1648        1506 :     bias=BiasGrid_->getValueAndDerivatives(cv,vder);
+    1649        3498 :     for(unsigned i=0; i<ncv; i++) der[i]=vder[i];
+    1650             :   } else {
+    1651        6889 :     unsigned nt=OpenMP::getNumThreads();
+    1652        6889 :     unsigned stride=comm.Get_size();
+    1653        6889 :     unsigned rank=comm.Get_rank();
+    1654             : 
+    1655        6889 :     if(!nlist_) {
+    1656        6884 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1657             :         // for performance reasons and thread safety
+    1658        2588 :         std::vector<double> dp(ncv);
+    1659        6705 :         for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1660        4117 :           bias+=evaluateGaussianAndDerivatives(cv,hills_[i],der,dp);
+    1661             :         }
+    1662             :       } else {
+    1663        4296 :         #pragma omp parallel num_threads(nt)
+    1664             :         {
+    1665             :           std::vector<double> omp_deriv(ncv,0.);
+    1666             :           // for performance reasons and thread safety
+    1667             :           std::vector<double> dp(ncv);
+    1668             :           #pragma omp for reduction(+:bias) nowait
+    1669             :           for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1670             :             bias+=evaluateGaussianAndDerivatives(cv,hills_[i],omp_deriv,dp);
+    1671             :           }
+    1672             :           #pragma omp critical
+    1673             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1674             :         }
+    1675             :       }
+    1676             :     } else {
+    1677           5 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1678             :         // for performance reasons and thread safety
+    1679           0 :         std::vector<double> dp(ncv);
+    1680           0 :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1681           0 :           bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],der,dp);
+    1682             :         }
+    1683             :       } else {
+    1684           5 :         #pragma omp parallel num_threads(nt)
+    1685             :         {
+    1686             :           std::vector<double> omp_deriv(ncv,0.);
+    1687             :           // for performance reasons and thread safety
+    1688             :           std::vector<double> dp(ncv);
+    1689             :           #pragma omp for reduction(+:bias) nowait
+    1690             :           for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1691             :             bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],omp_deriv,dp);
+    1692             :           }
+    1693             :           #pragma omp critical
+    1694             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1695             :         }
+    1696             :       }
+    1697             :     }
+    1698        6889 :     comm.Sum(bias);
+    1699        6889 :     comm.Sum(der);
+    1700             :   }
+    1701             : 
+    1702        8395 :   return bias;
+    1703             : }
+    1704             : 
+    1705           0 : double MetaD::getGaussianNormalization(const Gaussian& hill)
+    1706             : {
+    1707             :   double norm=1;
+    1708           0 :   unsigned ncv=hill.center.size();
+    1709             : 
+    1710           0 :   if(hill.multivariate) {
+    1711             :     // recompose the full sigma from the upper diag cholesky
+    1712             :     unsigned k=0;
+    1713             :     Matrix<double> mymatrix(ncv,ncv);
+    1714           0 :     for(unsigned i=0; i<ncv; i++) {
+    1715           0 :       for(unsigned j=i; j<ncv; j++) {
+    1716           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1717           0 :         k++;
+    1718             :       }
+    1719           0 :       double ldet; logdet( mymatrix, ldet );
+    1720           0 :       norm = std::exp( ldet );  // Not sure here if mymatrix is sigma or inverse
+    1721             :     }
+    1722             :   } else {
+    1723           0 :     for(unsigned i=0; i<hill.sigma.size(); i++) norm*=hill.sigma[i];
+    1724             :   }
+    1725             : 
+    1726           0 :   return norm*std::pow(2*pi,static_cast<double>(ncv)/2.0);
+    1727             : }
+    1728             : 
+    1729         192 : double MetaD::evaluateGaussian(const std::vector<double>& cv, const Gaussian& hill)
+    1730             : {
+    1731         192 :   unsigned ncv=cv.size();
+    1732             : 
+    1733             :   // I use a pointer here because cv is const (and should be const)
+    1734             :   // but when using doInt it is easier to locally replace cv[0] with
+    1735             :   // the upper/lower limit in case it is out of range
+    1736             :   double tmpcv[1];
+    1737             :   const double *pcv=NULL; // pointer to cv
+    1738         192 :   if(ncv>0) pcv=&cv[0];
+    1739         192 :   if(doInt_) {
+    1740           0 :     plumed_assert(ncv==1);
+    1741           0 :     tmpcv[0]=cv[0];
+    1742           0 :     if(cv[0]<lowI_) tmpcv[0]=lowI_;
+    1743           0 :     if(cv[0]>uppI_) tmpcv[0]=uppI_;
+    1744             :     pcv=&(tmpcv[0]);
+    1745             :   }
+    1746             : 
+    1747             :   double dp2=0.0;
+    1748         192 :   if(hill.multivariate) {
+    1749             :     unsigned k=0;
+    1750             :     // recompose the full sigma from the upper diag cholesky
+    1751             :     Matrix<double> mymatrix(ncv,ncv);
+    1752           0 :     for(unsigned i=0; i<ncv; i++) {
+    1753           0 :       for(unsigned j=i; j<ncv; j++) {
+    1754           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1755           0 :         k++;
+    1756             :       }
+    1757             :     }
+    1758           0 :     for(unsigned i=0; i<ncv; i++) {
+    1759           0 :       double dp_i=difference(i,hill.center[i],pcv[i]);
+    1760           0 :       for(unsigned j=i; j<ncv; j++) {
+    1761           0 :         if(i==j) {
+    1762           0 :           dp2+=dp_i*dp_i*mymatrix(i,j)*0.5;
+    1763             :         } else {
+    1764           0 :           double dp_j=difference(j,hill.center[j],pcv[j]);
+    1765           0 :           dp2+=dp_i*dp_j*mymatrix(i,j);
+    1766             :         }
+    1767             :       }
+    1768             :     }
+    1769             :   } else {
+    1770         576 :     for(unsigned i=0; i<ncv; i++) {
+    1771         384 :       double dp=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1772         384 :       dp2+=dp*dp;
+    1773             :     }
+    1774         192 :     dp2*=0.5;
+    1775             :   }
+    1776             : 
+    1777             :   double bias=0.0;
+    1778         192 :   if(dp2<dp2cutoff) bias=hill.height*(stretchA*std::exp(-dp2)+stretchB);
+    1779             : 
+    1780         192 :   return bias;
+    1781             : }
+    1782             : 
+    1783     2408601 : double MetaD::evaluateGaussianAndDerivatives(const std::vector<double>& cv, const Gaussian& hill, std::vector<double>& der, std::vector<double>& dp_)
+    1784             : {
+    1785     2408601 :   unsigned ncv=cv.size();
+    1786             : 
+    1787             :   // I use a pointer here because cv is const (and should be const)
+    1788             :   // but when using doInt it is easier to locally replace cv[0] with
+    1789             :   // the upper/lower limit in case it is out of range
+    1790             :   const double *pcv=NULL; // pointer to cv
+    1791             :   double tmpcv[1]; // tmp array with cv (to be used with doInt_)
+    1792     2408601 :   if(ncv>0) pcv=&cv[0];
+    1793     2408601 :   if(doInt_) {
+    1794         602 :     plumed_assert(ncv==1);
+    1795         602 :     tmpcv[0]=cv[0];
+    1796         602 :     if(cv[0]<lowI_) tmpcv[0]=lowI_;
+    1797         602 :     if(cv[0]>uppI_) tmpcv[0]=uppI_;
+    1798             :     pcv=&(tmpcv[0]);
+    1799             :   }
+    1800             : 
+    1801             :   bool int_der=false;
+    1802     2408601 :   if(doInt_) {
+    1803         602 :     if(cv[0]<lowI_ || cv[0]>uppI_) int_der=true;
+    1804             :   }
+    1805             : 
+    1806             :   double dp2=0.0;
+    1807             :   double bias=0.0;
+    1808     2408601 :   if(hill.multivariate) {
+    1809             :     unsigned k=0;
+    1810             :     // recompose the full sigma from the upper diag cholesky
+    1811             :     Matrix<double> mymatrix(ncv,ncv);
+    1812      161635 :     for(unsigned i=0; i<ncv; i++) {
+    1813      162513 :       for(unsigned j=i; j<ncv; j++) {
+    1814       81476 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1815       81476 :         k++;
+    1816             :       }
+    1817             :     }
+    1818      161635 :     for(unsigned i=0; i<ncv; i++) {
+    1819       81037 :       dp_[i]=difference(i,hill.center[i],pcv[i]);
+    1820      162513 :       for(unsigned j=i; j<ncv; j++) {
+    1821       81476 :         if(i==j) {
+    1822       81037 :           dp2+=dp_[i]*dp_[i]*mymatrix(i,j)*0.5;
+    1823             :         } else {
+    1824         439 :           double dp_j=difference(j,hill.center[j],pcv[j]);
+    1825         439 :           dp2+=dp_[i]*dp_j*mymatrix(i,j);
+    1826             :         }
+    1827             :       }
+    1828             :     }
+    1829       80598 :     if(dp2<dp2cutoff) {
+    1830       77683 :       bias=hill.height*std::exp(-dp2);
+    1831       77683 :       if(!int_der) {
+    1832      155673 :         for(unsigned i=0; i<ncv; i++) {
+    1833             :           double tmp=0.0;
+    1834      156594 :           for(unsigned j=0; j<ncv; j++) tmp += dp_[j]*mymatrix(i,j)*bias;
+    1835       77990 :           der[i]-=tmp*stretchA;
+    1836             :         }
+    1837             :       } else {
+    1838           0 :         for(unsigned i=0; i<ncv; i++) der[i]=0.;
+    1839             :       }
+    1840       77683 :       bias=stretchA*bias+hill.height*stretchB;
+    1841             :     }
+    1842             :   } else {
+    1843     6974367 :     for(unsigned i=0; i<ncv; i++) {
+    1844     4646364 :       dp_[i]=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1845     4646364 :       dp2+=dp_[i]*dp_[i];
+    1846             :     }
+    1847     2328003 :     dp2*=0.5;
+    1848     2328003 :     if(dp2<dp2cutoff) {
+    1849     1355486 :       bias=hill.height*std::exp(-dp2);
+    1850     1355486 :       if(!int_der) {
+    1851     4057679 :         for(unsigned i=0; i<ncv; i++) der[i]-=bias*dp_[i]*hill.invsigma[i]*stretchA;
+    1852             :       } else {
+    1853         478 :         for(unsigned i=0; i<ncv; i++) der[i]=0.;
+    1854             :       }
+    1855     1355486 :       bias=stretchA*bias+hill.height*stretchB;
+    1856             :     }
+    1857             :   }
+    1858             : 
+    1859     2408601 :   return bias;
+    1860             : }
+    1861             : 
+    1862        2736 : double MetaD::getHeight(const std::vector<double>& cv)
+    1863             : {
+    1864        2736 :   double height=height0_;
+    1865        2736 :   if(welltemp_) {
+    1866         275 :     double vbias = getBias(cv);
+    1867         275 :     if(biasf_>1.0) {
+    1868         259 :       height = height0_*std::exp(-vbias/(kbt_*(biasf_-1.0)));
+    1869             :     } else {
+    1870             :       // notice that if gamma=1 we store directly -F
+    1871          16 :       height = height0_*std::exp(-vbias/kbt_);
+    1872             :     }
+    1873             :   }
+    1874        2736 :   if(dampfactor_>0.0) {
+    1875          18 :     plumed_assert(BiasGrid_);
+    1876          18 :     double m=BiasGrid_->getMaxValue();
+    1877          18 :     height*=std::exp(-m/(kbt_*(dampfactor_)));
+    1878             :   }
+    1879        2736 :   if (tt_specs_.is_active) {
+    1880          60 :     double vbarrier = transition_bias_;
+    1881          60 :     temperHeight(height, tt_specs_, vbarrier);
+    1882             :   }
+    1883        2736 :   if(TargetGrid_) {
+    1884          18 :     double f=TargetGrid_->getValue(cv)-TargetGrid_->getMaxValue();
+    1885          18 :     height*=std::exp(f/kbt_);
+    1886             :   }
+    1887        2736 :   return height;
+    1888             : }
+    1889             : 
+    1890          60 : void MetaD::temperHeight(double& height, const TemperingSpecs& t_specs, const double tempering_bias)
+    1891             : {
+    1892          60 :   if (t_specs.alpha == 1.0) {
+    1893          80 :     height *= std::exp(-std::max(0.0, tempering_bias - t_specs.threshold) / (kbt_ * (t_specs.biasf - 1.0)));
+    1894             :   } else {
+    1895          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));
+    1896             :   }
+    1897          60 : }
+    1898             : 
+    1899        8435 : void MetaD::calculate()
+    1900             : {
+    1901             :   // this is because presently there is no way to properly pass information
+    1902             :   // on adaptive hills (diff) after exchanges:
+    1903        8435 :   if(adaptive_==FlexibleBin::diffusion && getExchangeStep()) error("ADAPTIVE=DIFF is not compatible with replica exchange");
+    1904             : 
+    1905        8435 :   const unsigned ncv=getNumberOfArguments();
+    1906        8435 :   std::vector<double> cv(ncv);
+    1907       21082 :   for(unsigned i=0; i<ncv; ++i) cv[i]=getArgument(i);
+    1908             : 
+    1909        8435 :   if(nlist_) {
+    1910           5 :     nlist_steps_++;
+    1911           5 :     if(getExchangeStep()) nlist_update_=true;
+    1912             :     else {
+    1913          11 :       for(unsigned i=0; i<ncv; ++i) {
+    1914           8 :         double d = difference(i, cv[i], nlist_center_[i]);
+    1915           8 :         double nk_dist2 = d*d/nlist_dev2_[i];
+    1916           8 :         if(nk_dist2>nlist_param_[1]) {nlist_update_=true; break;}
+    1917             :       }
+    1918             :     }
+    1919           5 :     if(nlist_update_) updateNlist();
+    1920             :   }
+    1921             : 
+    1922             :   double ene = 0.;
+    1923        8435 :   std::vector<double> der(ncv,0.);
+    1924        8435 :   if(biasf_!=1.0) ene = getBiasAndDerivatives(cv,der);
+    1925             :   setBias(ene);
+    1926       21082 :   for(unsigned i=0; i<ncv; i++) setOutputForce(i,-der[i]);
+    1927             : 
+    1928        8440 :   if(calc_work_) getPntrToComponent("work")->set(work_);
+    1929        8545 :   if(calc_rct_) getPntrToComponent("rbias")->set(ene - reweight_factor_);
+    1930             :   // calculate the acceleration factor
+    1931        8435 :   if(acceleration_&&!isFirstStep_) {
+    1932         329 :     acc_ += static_cast<double>(getStride()) * std::exp(ene/(kbt_));
+    1933         329 :     const double mean_acc = acc_/((double) getStep());
+    1934         329 :     getPntrToComponent("acc")->set(mean_acc);
+    1935        8435 :   } else if (acceleration_ && isFirstStep_ && acc_restart_mean_ > 0.0) {
+    1936           2 :     acc_ = acc_restart_mean_ * static_cast<double>(getStep());
+    1937           2 :     if(freq_adaptive_) {
+    1938             :       // has to be done here if restarting, as the acc is not defined before
+    1939           1 :       updateFrequencyAdaptiveStride();
+    1940             :     }
+    1941             :   }
+    1942        8435 : }
+    1943             : 
+    1944        6239 : void MetaD::update()
+    1945             : {
+    1946             :   // adding hills criteria (could be more complex though)
+    1947             :   bool nowAddAHill;
+    1948        6239 :   if(getStep()%current_stride_==0 && !isFirstStep_) nowAddAHill=true;
+    1949             :   else {
+    1950             :     nowAddAHill=false;
+    1951        3503 :     isFirstStep_=false;
+    1952             :   }
+    1953             : 
+    1954        6239 :   unsigned ncv=getNumberOfArguments();
+    1955        6239 :   std::vector<double> cv(ncv);
+    1956       16690 :   for(unsigned i=0; i<ncv; ++i) cv[i] = getArgument(i);
+    1957             : 
+    1958             :   double vbias=0.;
+    1959        6239 :   if(calc_work_) vbias=getBias(cv);
+    1960             : 
+    1961             :   // if you use adaptive, call the FlexibleBin
+    1962             :   bool multivariate=false;
+    1963        6239 :   if(adaptive_!=FlexibleBin::none) {
+    1964         778 :     flexbin_->update(nowAddAHill);
+    1965             :     multivariate=true;
+    1966             :   }
+    1967             : 
+    1968             :   std::vector<double> thissigma;
+    1969        6239 :   if(nowAddAHill) {
+    1970             :     // add a Gaussian
+    1971        2736 :     double height=getHeight(cv);
+    1972             :     // returns upper diagonal inverse
+    1973        3110 :     if(adaptive_!=FlexibleBin::none) thissigma=flexbin_->getInverseMatrix();
+    1974             :     // returns normal sigma
+    1975        2362 :     else thissigma=sigma0_;
+    1976             : 
+    1977             :     // In case we use walkers_mpi, it is now necessary to communicate with other replicas.
+    1978        2736 :     if(walkers_mpi_) {
+    1979             :       // Allocate arrays to store all walkers hills
+    1980         174 :       std::vector<double> all_cv(mpi_nw_*ncv,0.0);
+    1981         174 :       std::vector<double> all_sigma(mpi_nw_*thissigma.size(),0.0);
+    1982         174 :       std::vector<double> all_height(mpi_nw_,0.0);
+    1983         174 :       std::vector<int>    all_multivariate(mpi_nw_,0);
+    1984         174 :       if(comm.Get_rank()==0) {
+    1985             :         // Communicate (only root)
+    1986          99 :         multi_sim_comm.Allgather(cv,all_cv);
+    1987          99 :         multi_sim_comm.Allgather(thissigma,all_sigma);
+    1988             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    1989          99 :         multi_sim_comm.Allgather(height*(biasf_>1.0?biasf_/(biasf_-1.0):1.0),all_height);
+    1990          99 :         multi_sim_comm.Allgather(int(multivariate),all_multivariate);
+    1991             :       }
+    1992             :       // Share info with group members
+    1993         174 :       comm.Bcast(all_cv,0);
+    1994         174 :       comm.Bcast(all_sigma,0);
+    1995         174 :       comm.Bcast(all_height,0);
+    1996         174 :       comm.Bcast(all_multivariate,0);
+    1997             : 
+    1998             :       // Flying Gaussian
+    1999         174 :       if (flying_) {
+    2000          54 :         hills_.clear();
+    2001          54 :         comm.Barrier();
+    2002             :       }
+    2003             : 
+    2004         696 :       for(unsigned i=0; i<mpi_nw_; i++) {
+    2005             :         // actually add hills one by one
+    2006         522 :         std::vector<double> cv_now(ncv);
+    2007         522 :         std::vector<double> sigma_now(thissigma.size());
+    2008        1566 :         for(unsigned j=0; j<ncv; j++) cv_now[j]=all_cv[i*ncv+j];
+    2009        1674 :         for(unsigned j=0; j<thissigma.size(); j++) sigma_now[j]=all_sigma[i*thissigma.size()+j];
+    2010             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    2011         522 :         double fact=(biasf_>1.0?(biasf_-1.0)/biasf_:1.0);
+    2012         522 :         Gaussian newhill=Gaussian(all_multivariate[i],all_height[i]*fact,cv_now,sigma_now);
+    2013         522 :         addGaussian(newhill);
+    2014         522 :         if(!flying_) writeGaussian(newhill,hillsOfile_);
+    2015         522 :       }
+    2016             :     } else {
+    2017        2562 :       Gaussian newhill=Gaussian(multivariate,height,cv,thissigma);
+    2018        2562 :       addGaussian(newhill);
+    2019        2562 :       writeGaussian(newhill,hillsOfile_);
+    2020        2562 :     }
+    2021             : 
+    2022             :     // this is to update the hills neighbor list
+    2023        2736 :     if(nlist_) nlist_update_=true;
+    2024             :   }
+    2025             : 
+    2026             :   // this should be outside of the if block in case
+    2027             :   // mw_rstride_ is not a multiple of stride_
+    2028        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) hillsOfile_.flush();
+    2029             : 
+    2030        6239 :   if(calc_work_) {
+    2031           5 :     if(nlist_) updateNlist();
+    2032           5 :     double vbias1=getBias(cv);
+    2033           5 :     work_+=vbias1-vbias;
+    2034             :   }
+    2035             : 
+    2036             :   // dump grid on file
+    2037        6239 :   if(wgridstride_>0&&(getStep()%wgridstride_==0||getCPT())) {
+    2038             :     // in case old grids are stored, a sequence of grids should appear
+    2039             :     // this call results in a repetition of the header:
+    2040          91 :     if(storeOldGrids_) gridfile_.clearFields();
+    2041             :     // in case only latest grid is stored, file should be rewound
+    2042             :     // this will overwrite previously written grids
+    2043             :     else {
+    2044          51 :       int r = 0;
+    2045          51 :       if(walkers_mpi_) {
+    2046           0 :         if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    2047           0 :         comm.Bcast(r,0);
+    2048             :       }
+    2049          51 :       if(r==0) gridfile_.rewind();
+    2050             :     }
+    2051          91 :     BiasGrid_->writeToFile(gridfile_);
+    2052             :     // if a single grid is stored, it is necessary to flush it, otherwise
+    2053             :     // the file might stay empty forever (when a single grid is not large enough to
+    2054             :     // trigger flushing from the operating system).
+    2055             :     // on the other hand, if grids are stored one after the other this is
+    2056             :     // no necessary, and we leave the flushing control to the user as usual
+    2057             :     // (with FLUSH keyword)
+    2058          91 :     if(!storeOldGrids_) gridfile_.flush();
+    2059             :   }
+    2060             : 
+    2061             :   // if multiple walkers and time to read Gaussians
+    2062        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) {
+    2063       12048 :     for(int i=0; i<mw_n_; ++i) {
+    2064             :       // don't read your own Gaussians
+    2065        9036 :       if(i==mw_id_) continue;
+    2066             :       // if the file is not open yet
+    2067        6024 :       if(!(ifiles_[i]->isOpen())) {
+    2068             :         // check if it exists now and open it!
+    2069           6 :         if(ifiles_[i]->FileExist(ifilesnames_[i])) {
+    2070           6 :           ifiles_[i]->open(ifilesnames_[i]);
+    2071           6 :           ifiles_[i]->reset(false);
+    2072             :         }
+    2073             :         // otherwise read the new Gaussians
+    2074             :       } else {
+    2075        6018 :         log.printf("  Reading hills from %s:",ifilesnames_[i].c_str());
+    2076        6018 :         readGaussians(ifiles_[i].get());
+    2077        6018 :         ifiles_[i]->reset(false);
+    2078             :       }
+    2079             :     }
+    2080             :     // this is to update the hills neighbor list
+    2081        3012 :     if(nlist_) nlist_update_=true;
+    2082             :   }
+    2083             : 
+    2084             :   // Recalculate special bias quantities whenever the bias has been changed by the update.
+    2085        6239 :   bool bias_has_changed = (nowAddAHill || (mw_n_ > 1 && getStep() % mw_rstride_ == 0));
+    2086        6239 :   if (calc_rct_ && bias_has_changed && getStep()%(stride_*rct_ustride_)==0) computeReweightingFactor();
+    2087        6239 :   if (calc_max_bias_ && bias_has_changed) {
+    2088           0 :     max_bias_ = BiasGrid_->getMaxValue();
+    2089           0 :     getPntrToComponent("maxbias")->set(max_bias_);
+    2090             :   }
+    2091        6239 :   if (calc_transition_bias_ && bias_has_changed) {
+    2092         260 :     transition_bias_ = getTransitionBarrierBias();
+    2093         520 :     getPntrToComponent("transbias")->set(transition_bias_);
+    2094             :   }
+    2095             : 
+    2096             :   // Frequency adaptive metadynamics - update hill addition frequency
+    2097        6239 :   if(freq_adaptive_ && getStep()%fa_update_frequency_==0) {
+    2098         151 :     updateFrequencyAdaptiveStride();
+    2099             :   }
+    2100        6239 : }
+    2101             : 
+    2102             : /// takes a pointer to the file and a template std::string with values v and gives back the next center, sigma and height
+    2103        8542 : bool MetaD::scanOneHill(IFile* ifile, std::vector<Value>& tmpvalues, std::vector<double>& center, std::vector<double>& sigma, double& height, bool& multivariate)
+    2104             : {
+    2105             :   double dummy;
+    2106        8542 :   multivariate=false;
+    2107       17084 :   if(ifile->scanField("time",dummy)) {
+    2108        2505 :     unsigned ncv=tmpvalues.size();
+    2109        7469 :     for(unsigned i=0; i<ncv; ++i) {
+    2110        4964 :       ifile->scanField( &tmpvalues[i] );
+    2111        4964 :       if( tmpvalues[i].isPeriodic() && ! getPntrToArgument(i)->isPeriodic() ) {
+    2112           0 :         error("in hills file periodicity for variable " + tmpvalues[i].getName() + " does not match periodicity in input");
+    2113        4964 :       } else if( tmpvalues[i].isPeriodic() ) {
+    2114           0 :         std::string imin, imax; tmpvalues[i].getDomain( imin, imax );
+    2115           0 :         std::string rmin, rmax; getPntrToArgument(i)->getDomain( rmin, rmax );
+    2116           0 :         if( imin!=rmin || imax!=rmax ) {
+    2117           0 :           error("in hills file periodicity for variable " + tmpvalues[i].getName() + " does not match periodicity in input");
+    2118             :         }
+    2119             :       }
+    2120        4964 :       center[i]=tmpvalues[i].get();
+    2121             :     }
+    2122             :     // scan for kerneltype
+    2123        2505 :     std::string ktype="stretched-gaussian";
+    2124        7506 :     if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+    2125        2505 :     if( ktype=="gaussian" ) {
+    2126          12 :       noStretchWarning();
+    2127        2493 :     } else if( ktype!="stretched-gaussian") {
+    2128           0 :       error("non Gaussian kernels are not supported in MetaD");
+    2129             :     }
+    2130             :     // scan for multivariate label: record the actual file position so to eventually rewind
+    2131             :     std::string sss;
+    2132        5010 :     ifile->scanField("multivariate",sss);
+    2133        2505 :     if(sss=="true") multivariate=true;
+    2134        2505 :     else if(sss=="false") multivariate=false;
+    2135           0 :     else plumed_merror("cannot parse multivariate = "+ sss);
+    2136        2505 :     if(multivariate) {
+    2137           0 :       sigma.resize(ncv*(ncv+1)/2);
+    2138             :       Matrix<double> upper(ncv,ncv);
+    2139             :       Matrix<double> lower(ncv,ncv);
+    2140           0 :       for(unsigned i=0; i<ncv; i++) {
+    2141           0 :         for(unsigned j=0; j<ncv-i; j++) {
+    2142           0 :           ifile->scanField("sigma_"+getPntrToArgument(j+i)->getName()+"_"+getPntrToArgument(j)->getName(),lower(j+i,j));
+    2143           0 :           upper(j,j+i)=lower(j+i,j);
+    2144             :         }
+    2145             :       }
+    2146             :       Matrix<double> mymult(ncv,ncv);
+    2147             :       Matrix<double> invmatrix(ncv,ncv);
+    2148           0 :       mult(lower,upper,mymult);
+    2149             :       // now invert and get the sigmas
+    2150           0 :       Invert(mymult,invmatrix);
+    2151             :       // put the sigmas in the usual order: upper diagonal (this time in normal form and not in band form)
+    2152             :       unsigned k=0;
+    2153           0 :       for(unsigned i=0; i<ncv; i++) {
+    2154           0 :         for(unsigned j=i; j<ncv; j++) {
+    2155           0 :           sigma[k]=invmatrix(i,j);
+    2156           0 :           k++;
+    2157             :         }
+    2158             :       }
+    2159             :     } else {
+    2160        7469 :       for(unsigned i=0; i<ncv; ++i) {
+    2161        9928 :         ifile->scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    2162             :       }
+    2163             :     }
+    2164             : 
+    2165        2505 :     ifile->scanField("height",height);
+    2166        2505 :     ifile->scanField("biasf",dummy);
+    2167        7332 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+    2168        5010 :     if(ifile->FieldExist("lower_int")) ifile->scanField("lower_int",dummy);
+    2169        5010 :     if(ifile->FieldExist("upper_int")) ifile->scanField("upper_int",dummy);
+    2170        2505 :     ifile->scanField();
+    2171             :     return true;
+    2172             :   } else {
+    2173             :     return false;
+    2174             :   }
+    2175             : }
+    2176             : 
+    2177         102 : void MetaD::computeReweightingFactor()
+    2178             : {
+    2179         102 :   if(biasf_==1.0) { // in this case we have no bias, so reweight factor is 0.0
+    2180           0 :     getPntrToComponent("rct")->set(0.0);
+    2181           0 :     return;
+    2182             :   }
+    2183             : 
+    2184         102 :   double Z_0=0; //proportional to the integral of exp(-beta*F)
+    2185         102 :   double Z_V=0; //proportional to the integral of exp(-beta*(F+V))
+    2186         102 :   double minusBetaF=biasf_/(biasf_-1.)/kbt_;
+    2187         102 :   double minusBetaFplusV=1./(biasf_-1.)/kbt_;
+    2188         102 :   if (biasf_==-1.0) { //non well-tempered case
+    2189           0 :     minusBetaF=1./kbt_;
+    2190             :     minusBetaFplusV=0;
+    2191             :   }
+    2192         102 :   max_bias_=BiasGrid_->getMaxValue(); //to avoid exp overflow
+    2193             : 
+    2194         102 :   const unsigned rank=comm.Get_rank();
+    2195         102 :   const unsigned stride=comm.Get_size();
+    2196      920504 :   for (Grid::index_t t=rank; t<BiasGrid_->getSize(); t+=stride) {
+    2197      920402 :     const double val=BiasGrid_->getValue(t);
+    2198      920402 :     Z_0+=std::exp(minusBetaF*(val-max_bias_));
+    2199      920402 :     Z_V+=std::exp(minusBetaFplusV*(val-max_bias_));
+    2200             :   }
+    2201         102 :   comm.Sum(Z_0);
+    2202         102 :   comm.Sum(Z_V);
+    2203             : 
+    2204         102 :   reweight_factor_=kbt_*std::log(Z_0/Z_V)+max_bias_;
+    2205         204 :   getPntrToComponent("rct")->set(reweight_factor_);
+    2206             : }
+    2207             : 
+    2208         273 : double MetaD::getTransitionBarrierBias()
+    2209             : {
+    2210             :   // If there is only one well of interest, return the bias at that well point.
+    2211         273 :   if (transitionwells_.size() == 1) {
+    2212           0 :     double tb_bias = getBias(transitionwells_[0]);
+    2213           0 :     return tb_bias;
+    2214             : 
+    2215             :     // Otherwise, check for the least barrier bias between all pairs of wells.
+    2216             :     // Note that because the paths can be considered edges between the wells' nodes
+    2217             :     // to make a graph and the path barriers satisfy certain cycle inequalities, it
+    2218             :     // is sufficient to look at paths corresponding to a minimal spanning tree of the
+    2219             :     // overall graph rather than examining every edge in the graph.
+    2220             :     // For simplicity, I chose the star graph with center well 0 as the spanning tree.
+    2221             :     // It is most efficient to start the path searches from the wells that are
+    2222             :     // expected to be sampled last, so transitionwell_[0] should correspond to the
+    2223             :     // starting well. With this choice the searches will terminate in one step until
+    2224             :     // transitionwell_[1] is sampled.
+    2225             :   } else {
+    2226             :     double least_transition_bias;
+    2227         273 :     std::vector<double> sink = transitionwells_[0];
+    2228         273 :     std::vector<double> source = transitionwells_[1];
+    2229         273 :     least_transition_bias = BiasGrid_->findMaximalPathMinimum(source, sink);
+    2230         273 :     for (unsigned i = 2; i < transitionwells_.size(); i++) {
+    2231           0 :       if (least_transition_bias == 0.0) {
+    2232             :         break;
+    2233             :       }
+    2234           0 :       source = transitionwells_[i];
+    2235           0 :       double curr_transition_bias = BiasGrid_->findMaximalPathMinimum(source, sink);
+    2236           0 :       least_transition_bias = fmin(curr_transition_bias, least_transition_bias);
+    2237             :     }
+    2238             :     return least_transition_bias;
+    2239             :   }
+    2240             : }
+    2241             : 
+    2242         154 : void MetaD::updateFrequencyAdaptiveStride()
+    2243             : {
+    2244         154 :   plumed_massert(freq_adaptive_,"should only be used if frequency adaptive metadynamics is enabled");
+    2245         154 :   plumed_massert(acceleration_,"frequency adaptive metadynamics can only be used if the acceleration factor is calculated");
+    2246         154 :   const double mean_acc = acc_/((double) getStep());
+    2247         154 :   int tmp_stride= stride_*floor((mean_acc/fa_min_acceleration_)+0.5);
+    2248         154 :   if(mean_acc >= fa_min_acceleration_) {
+    2249         129 :     if(tmp_stride > current_stride_) {current_stride_ = tmp_stride;}
+    2250             :   }
+    2251         154 :   if(fa_max_stride_!=0 && current_stride_>fa_max_stride_) {
+    2252           0 :     current_stride_=fa_max_stride_;
+    2253             :   }
+    2254         154 :   getPntrToComponent("pace")->set(current_stride_);
+    2255         154 : }
+    2256             : 
+    2257        8435 : bool MetaD::checkNeedsGradients()const
+    2258             : {
+    2259        8435 :   if(adaptive_==FlexibleBin::geometry) {
+    2260         192 :     if(getStep()%stride_==0 && !isFirstStep_) return true;
+    2261         109 :     else return false;
+    2262             :   } else return false;
+    2263             : }
+    2264             : 
+    2265           4 : void MetaD::updateNlist()
+    2266             : {
+    2267             :   // no need to check for neighbors
+    2268           4 :   if(hills_.size()==0) return;
+    2269             : 
+    2270             :   // here we generate the neighbor list
+    2271           4 :   nlist_hills_.clear();
+    2272             :   std::vector<Gaussian> local_flat_nl;
+    2273           4 :   unsigned nt=OpenMP::getNumThreads();
+    2274           4 :   if(hills_.size()<2*nt) nt=1;
+    2275           4 :   #pragma omp parallel num_threads(nt)
+    2276             :   {
+    2277             :     std::vector<Gaussian> private_flat_nl;
+    2278             :     #pragma omp for nowait
+    2279             :     for(unsigned k=0; k<hills_.size(); k++)
+    2280             :     {
+    2281             :       double dist2=0;
+    2282             :       for(unsigned i=0; i<getNumberOfArguments(); i++)
+    2283             :       {
+    2284             :         const double d=difference(i,getArgument(i),hills_[k].center[i])/hills_[k].sigma[i];
+    2285             :         dist2+=d*d;
+    2286             :       }
+    2287             :       if(dist2<=nlist_param_[0]*dp2cutoff) private_flat_nl.push_back(hills_[k]);
+    2288             :     }
+    2289             :     #pragma omp critical
+    2290             :     local_flat_nl.insert(local_flat_nl.end(), private_flat_nl.begin(), private_flat_nl.end());
+    2291             :   }
+    2292           4 :   nlist_hills_ = local_flat_nl;
+    2293             : 
+    2294             :   // here we set some properties that are used to decide when to update it again
+    2295          12 :   for(unsigned i=0; i<getNumberOfArguments(); i++) nlist_center_[i]=getArgument(i);
+    2296             :   std::vector<double> dev2;
+    2297           4 :   dev2.resize(getNumberOfArguments(),0);
+    2298          46 :   for(unsigned k=0; k<nlist_hills_.size(); k++)
+    2299             :   {
+    2300         126 :     for(unsigned i=0; i<getNumberOfArguments(); i++)
+    2301             :     {
+    2302          84 :       const double d=difference(i,getArgument(i),nlist_hills_[k].center[i]);
+    2303          84 :       dev2[i]+=d*d;
+    2304             :     }
+    2305             :   }
+    2306          12 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    2307           8 :     if(dev2[i]>0.) nlist_dev2_[i]=dev2[i]/static_cast<double>(nlist_hills_.size());
+    2308           0 :     else nlist_dev2_[i]=hills_.back().sigma[i]*hills_.back().sigma[i];
+    2309             :   }
+    2310             : 
+    2311             :   // we are done
+    2312           4 :   getPntrToComponent("nlker")->set(nlist_hills_.size());
+    2313           4 :   getPntrToComponent("nlsteps")->set(nlist_steps_);
+    2314           4 :   nlist_steps_=0;
+    2315           4 :   nlist_update_=false;
+    2316           4 : }
+    2317             : 
+    2318             : }
+    2319             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.func-sort-c.html b/coverage/bias/MovingRestraint.cpp.func-sort-c.html new file mode 100644 index 0000000000..59e8288d3e --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe1176createERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.func.html b/coverage/bias/MovingRestraint.cpp.func.html new file mode 100644 index 0000000000..453d9fd5e0 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe1176createERKNS_13ActionOptionsE4
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_128MovingRestraintRegisterMe117D2Ev4168
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.gcov.html b/coverage/bias/MovingRestraint.cpp.gcov.html new file mode 100644 index 0000000000..8945e20997 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + 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-05-27 13:05: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 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       12512 : PLUMED_REGISTER_ACTION(MovingRestraint,"MOVINGRESTRAINT")
+     118             : 
+     119           6 : void MovingRestraint::registerKeywords( Keywords& keys ) {
+     120           6 :   Bias::registerKeywords(keys);
+     121           6 :   keys.use("ARG");
+     122          12 :   keys.add("compulsory","VERSE","B","Tells plumed whether the restraint is only acting for CV larger (U) or smaller (L) than "
+     123             :            "the restraint or whether it is acting on both sides (B)");
+     124          12 :   keys.add("numbered","STEP","This keyword appears multiple times as STEP\\f$x\\f$ with x=0,1,2,...,n. Each value given represents "
+     125             :            "the MD step at which the restraint parameters take the values KAPPA\\f$x\\f$ and AT\\f$x\\f$.");
+     126          12 :   keys.reset_style("STEP","compulsory");
+     127          12 :   keys.add("numbered","AT","AT\\f$x\\f$ is equal to the position of the restraint at time STEP\\f$x\\f$. For intermediate times this parameter "
+     128             :            "is linearly interpolated. If no AT\\f$x\\f$ is specified for STEP\\f$x\\f$ then the values of AT are kept constant "
+     129             :            "during the interval of time between STEP\\f$x-1\\f$ and STEP\\f$x\\f$.");
+     130          12 :   keys.reset_style("AT","compulsory");
+     131          12 :   keys.add("numbered","KAPPA","KAPPA\\f$x\\f$ is equal to the value of the force constants at time STEP\\f$x\\f$. For intermediate times this "
+     132             :            "parameter is linearly interpolated.  If no KAPPA\\f$x\\f$ is specified for STEP\\f$x\\f$ then the values of KAPPA\\f$x\\f$ "
+     133             :            "are kept constant during the interval of time between STEP\\f$x-1\\f$ and STEP\\f$x\\f$.");
+     134          12 :   keys.reset_style("KAPPA","compulsory");
+     135          12 :   keys.addOutputComponent("work","default","the total work performed changing this restraint");
+     136          12 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     137          12 :   keys.addOutputComponent("_cntr","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     138             :                           "these quantities will named with  the arguments of the bias followed by "
+     139             :                           "the character string _cntr. These quantities give the instantaneous position "
+     140             :                           "of the center of the harmonic potential.");
+     141          12 :   keys.addOutputComponent("_work","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     142             :                           "These quantities will named with the arguments of the bias followed by "
+     143             :                           "the character string _work. These quantities tell the user how much work has "
+     144             :                           "been done by the potential in dragging the system along the various colvar axis.");
+     145          12 :   keys.addOutputComponent("_kappa","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     146             :                           "These quantities will named with the arguments of the bias followed by "
+     147             :                           "the character string _kappa. These quantities tell the user the time dependent value of kappa.");
+     148           6 : }
+     149             : 
+     150           4 : MovingRestraint::MovingRestraint(const ActionOptions&ao):
+     151             :   PLUMED_BIAS_INIT(ao),
+     152           4 :   verse(getNumberOfArguments())
+     153             : {
+     154           4 :   parseVector("VERSE",verse);
+     155           4 :   std::vector<long long int> ss(1); ss[0]=-1;
+     156           4 :   std::vector<double> kk( getNumberOfArguments() ), aa( getNumberOfArguments() );
+     157          10 :   for(int i=0;; i++) {
+     158             :     // Read in step
+     159          28 :     if( !parseNumberedVector("STEP",i,ss) ) break;
+     160          19 :     for(unsigned j=0; j<step.size(); j++) {
+     161           9 :       if(ss[0]<step[j]) error("in moving restraint step number must always increase");
+     162             :     }
+     163          10 :     step.push_back(ss[0]);
+     164             : 
+     165             :     // Try to read kappa
+     166          20 :     if( !parseNumberedVector("KAPPA",i,kk) ) kk=kappa[i-1];
+     167          10 :     kappa.push_back(kk);
+     168             : 
+     169             :     // Now read AT
+     170          20 :     if( !parseNumberedVector("AT",i,aa) ) aa=at[i-1];
+     171          10 :     at.push_back(aa);
+     172          10 :   }
+     173           4 :   checkRead();
+     174             : 
+     175          14 :   for(unsigned i=0; i<step.size(); i++) {
+     176          10 :     log.printf("  step%u %lld\n",i,step[i]);
+     177          10 :     log.printf("  at");
+     178          22 :     for(unsigned j=0; j<at[i].size(); j++) log.printf(" %f",at[i][j]);
+     179          10 :     log.printf("\n");
+     180          10 :     log.printf("  with force constant");
+     181          22 :     for(unsigned j=0; j<kappa[i].size(); j++) log.printf(" %f",kappa[i][j]);
+     182          10 :     log.printf("\n");
+     183             :   };
+     184             : 
+     185          12 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     186             : 
+     187             :   // add the centers of the restraint as additional components that can be retrieved (useful for debug)
+     188             : 
+     189             :   std::string comp;
+     190           9 :   for(unsigned i=0; i< getNumberOfArguments() ; i++) {
+     191           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           8 :   log<<cite("Grubmuller, Heymann, and Tavan, Science 271, 997 (1996)")<<"\n";
+     204             : 
+     205           4 : }
+     206             : 
+     207             : 
+     208         566 : void MovingRestraint::calculate() {
+     209             :   double ene=0.0;
+     210             :   double totf2=0.0;
+     211         566 :   unsigned narg=getNumberOfArguments();
+     212         566 :   long long int now=getStep();
+     213         566 :   std::vector<double> kk(narg),aa(narg),f(narg),dpotdk(narg);
+     214         566 :   if(now<=step[0]) {
+     215           3 :     kk=kappa[0];
+     216           3 :     aa=at[0];
+     217           3 :     oldaa=at[0];
+     218           3 :     oldk=kappa[0];
+     219           3 :     olddpotdk.resize(narg);
+     220           3 :     oldf.resize(narg);
+     221         563 :   } else if(now>=step[step.size()-1]) {
+     222          47 :     kk=kappa[step.size()-1];
+     223          47 :     aa=at[step.size()-1];
+     224             :   } else {
+     225             :     unsigned i=0;
+     226         521 :     for(i=1; i<step.size()-1; i++) if(now<step[i]) break;
+     227         516 :     double c2=(now-step[i-1])/double(step[i]-step[i-1]);
+     228         516 :     double c1=1.0-c2;
+     229        1040 :     for(unsigned j=0; j<narg; j++) kk[j]=(c1*kappa[i-1][j]+c2*kappa[i][j]);
+     230        1040 :     for(unsigned j=0; j<narg; j++) {
+     231         524 :       const double a1=at[i-1][j];
+     232         524 :       const double a2=at[i][j];
+     233         524 :       aa[j]=(c1*a1+c2*(a1+difference(j,a1,a2)));
+     234             :     }
+     235             :   }
+     236         566 :   tot_work=0.0;
+     237        1142 :   for(unsigned i=0; i<narg; ++i) {
+     238         576 :     const double cv=difference(i,aa[i],getArgument(i)); // this gives: getArgument(i) - aa[i]
+     239        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_cntr")->set(aa[i]);
+     240         576 :     const double k=kk[i];
+     241         576 :     f[i]=-k*cv;
+     242         576 :     if(verse[i]=="U" && cv<0) continue;
+     243         576 :     if(verse[i]=="L" && cv>0) continue;
+     244        1728 :     plumed_assert(verse[i]=="U" || verse[i]=="L" || verse[i]=="B");
+     245         576 :     dpotdk[i]=0.5*cv*cv;
+     246         576 :     if(oldaa.size()==aa.size() && oldf.size()==f.size()) work[i]+=0.5*(oldf[i]+f[i])*(aa[i]-oldaa[i]) + 0.5*( dpotdk[i]+olddpotdk[i] )*(kk[i]-oldk[i]);
+     247        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_work")->set(work[i]);
+     248        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_kappa")->set(kk[i]);
+     249         576 :     tot_work+=work[i];
+     250         576 :     ene+=0.5*k*cv*cv;
+     251         576 :     setOutputForce(i,f[i]);
+     252         576 :     totf2+=f[i]*f[i];
+     253             :   };
+     254         566 :   getPntrToComponent("work")->set(tot_work);
+     255         566 :   oldf=f;
+     256         566 :   oldaa=aa;
+     257         566 :   oldk=kk;
+     258         566 :   olddpotdk=dpotdk;
+     259             :   setBias(ene);
+     260        1132 :   getPntrToComponent("force2")->set(totf2);
+     261         566 : }
+     262             : 
+     263             : }
+     264             : }
+     265             : 
+     266             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.func-sort-c.html b/coverage/bias/PBMetaD.cpp.func-sort-c.html new file mode 100644 index 0000000000..dec8554473 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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:57064688.2 %
Date:2024-05-27 13:05: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_120PBMetaDRegisterMe3326createERKNS_13ActionOptionsE41
_ZN4PLMD4bias7PBMetaDC1ERKNS_13ActionOptionsE41
_ZN4PLMD4bias7PBMetaD16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD4bias7PBMetaD18getGaussianSupportEjRKNS1_8GaussianE196
_ZN4PLMD4bias7PBMetaD6updateEv335
_ZN4PLMD4bias7PBMetaD9calculateEv335
_ZNK4PLMD4bias7PBMetaD19checkNeedsGradientsEv335
_ZN4PLMD4bias7PBMetaD13writeGaussianEjRKNS1_8GaussianEPNS_5OFileE1100
_ZN4PLMD4bias7PBMetaD11addGaussianEjRKNS1_8GaussianE1108
_ZN4PLMD4bias7PBMetaD8GaussianC2ERKSt6vectorIdSaIdEES7_db1108
_ZN4PLMD4bias7PBMetaD21getBiasAndDerivativesEjRKSt6vectorIdSaIdEEPd1269
_ZN4PLMD4bias12_GLOBAL__N_120PBMetaDRegisterMe332C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_120PBMetaDRegisterMe332D2Ev4168
_ZN4PLMD4bias7PBMetaD16evaluateGaussianEjRKSt6vectorIdSaIdEERKNS1_8GaussianEPd8664
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.func.html b/coverage/bias/PBMetaD.cpp.func.html new file mode 100644 index 0000000000..751f877a1e --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func.html @@ -0,0 +1,144 @@ + + + + + + + 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:57064688.2 %
Date:2024-05-27 13:05:14Functions:161888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe706createERKNS_13ActionOptionsE178
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE180
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70D2Ev4168
_ZN4PLMD4bias9Restraint9calculateEv4670
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.func.html b/coverage/bias/Restraint.cpp.func.html new file mode 100644 index 0000000000..292193a978 --- /dev/null +++ b/coverage/bias/Restraint.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe706createERKNS_13ActionOptionsE178
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_121RestraintRegisterMe70D2Ev4168
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE180
_ZN4PLMD4bias9Restraint9calculateEv4670
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.gcov.html b/coverage/bias/Restraint.cpp.gcov.html new file mode 100644 index 0000000000..c1d5d615e3 --- /dev/null +++ b/coverage/bias/Restraint.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + 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-05-27 13:05: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       12857 : PLUMED_REGISTER_ACTION(Restraint,"RESTRAINT")
+      71             : 
+      72         180 : void Restraint::registerKeywords(Keywords& keys) {
+      73         180 :   Bias::registerKeywords(keys);
+      74         180 :   keys.use("ARG");
+      75         360 :   keys.add("compulsory","SLOPE","0.0","specifies that the restraint is linear and what the values of the force constants on each of the variables are");
+      76         360 :   keys.add("compulsory","KAPPA","0.0","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+      77         360 :   keys.add("compulsory","AT","the position of the restraint");
+      78         360 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      79         180 : }
+      80             : 
+      81         178 : Restraint::Restraint(const ActionOptions&ao):
+      82             :   PLUMED_BIAS_INIT(ao),
+      83         350 :   at(getNumberOfArguments()),
+      84         175 :   kappa(getNumberOfArguments(),0.0),
+      85         353 :   slope(getNumberOfArguments(),0.0)
+      86             : {
+      87         175 :   parseVector("SLOPE",slope);
+      88         175 :   parseVector("KAPPA",kappa);
+      89         175 :   parseVector("AT",at);
+      90         175 :   checkRead();
+      91             : 
+      92         175 :   log.printf("  at");
+      93         385 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+      94         175 :   log.printf("\n");
+      95         175 :   log.printf("  with harmonic force constant");
+      96         385 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+      97         175 :   log.printf("\n");
+      98         175 :   log.printf("  and linear force constant");
+      99         385 :   for(unsigned i=0; i<slope.size(); i++) log.printf(" %f",slope[i]);
+     100         175 :   log.printf("\n");
+     101             : 
+     102         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.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func-sort-c.html b/coverage/bias/ReweightBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..94de2033e8 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD4bias12ReweightBase9calculateEv6232
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func.html b/coverage/bias/ReweightBase.cpp.func.html new file mode 100644 index 0000000000..8d452e3529 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD4bias12ReweightBase9calculateEv6232
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.gcov.html b/coverage/bias/ReweightBase.cpp.gcov.html new file mode 100644 index 0000000000..ae0d832761 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.gcov.html @@ -0,0 +1,133 @@ + + + + + + + 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-05-27 13:05: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          28 : void ReweightBase::registerKeywords(Keywords& keys) {
+      30          28 :   Action::registerKeywords( keys );
+      31          28 :   ActionWithValue::registerKeywords( keys );
+      32          28 :   ActionWithArguments::registerKeywords( keys );
+      33          28 :   keys.setComponentsIntroduction("This action calculates the logarithm of a weight for reweighting");
+      34          56 :   keys.add("optional","TEMP","the system temperature.  This is not required if your MD code passes this quantity to PLUMED");
+      35          28 :   keys.remove("NUMERICAL_DERIVATIVES");
+      36          28 : }
+      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.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func-sort-c.html b/coverage/bias/ReweightBase.h.func-sort-c.html new file mode 100644 index 0000000000..976cd4a7f8 --- /dev/null +++ b/coverage/bias/ReweightBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func.html b/coverage/bias/ReweightBase.h.func.html new file mode 100644 index 0000000000..6fba56a83f --- /dev/null +++ b/coverage/bias/ReweightBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.gcov.html b/coverage/bias/ReweightBase.h.gcov.html new file mode 100644 index 0000000000..dd0ffed90a --- /dev/null +++ b/coverage/bias/ReweightBase.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func-sort-c.html b/coverage/bias/ReweightBias.cpp.func-sort-c.html new file mode 100644 index 0000000000..931726bffc --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe786createERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func.html b/coverage/bias/ReweightBias.cpp.func.html new file mode 100644 index 0000000000..82f6c8de5b --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe786createERKNS_13ActionOptionsE3
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_124ReweightBiasRegisterMe78D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.gcov.html b/coverage/bias/ReweightBias.cpp.gcov.html new file mode 100644 index 0000000000..d7580550d5 --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.gcov.html @@ -0,0 +1,174 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(ReweightBias,"REWEIGHT_BIAS")
+      79             : 
+      80           5 : void ReweightBias::registerKeywords(Keywords& keys ) {
+      81           5 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      82          10 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+      83           5 : }
+      84             : 
+      85           3 : ReweightBias::ReweightBias(const ActionOptions&ao):
+      86             :   Action(ao),
+      87           3 :   ReweightBase(ao)
+      88             : {
+      89           3 : }
+      90             : 
+      91        1007 : double ReweightBias::getLogWeight() {
+      92             :   // Retrieve the bias
+      93        2014 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      94        1007 :   return bias / simtemp;
+      95             : }
+      96             : 
+      97             : }
+      98             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.func-sort-c.html b/coverage/bias/ReweightMetad.cpp.func-sort-c.html new file mode 100644 index 0000000000..bb7edf5680 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.func.html b/coverage/bias/ReweightMetad.cpp.func.html new file mode 100644 index 0000000000..837be963f9 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe756createERKNS_13ActionOptionsE1
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_125ReweightMetadRegisterMe75D2Ev4168
_ZN4PLMD4bias13ReweightMetad12getLogWeightEv2
_ZN4PLMD4bias13ReweightMetad16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias13ReweightMetadC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.gcov.html b/coverage/bias/ReweightMetad.cpp.gcov.html new file mode 100644 index 0000000000..5b905fb431 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(ReweightMetad,"REWEIGHT_METAD")
+      76             : 
+      77           3 : void ReweightMetad::registerKeywords(Keywords& keys ) {
+      78           3 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      79           6 :   keys.add("compulsory","ARG","*.rbias","the biases that must be taken into account when reweighting");
+      80           3 : }
+      81             : 
+      82           1 : ReweightMetad::ReweightMetad(const ActionOptions&ao):
+      83             :   Action(ao),
+      84           1 :   ReweightBase(ao)
+      85             : {
+      86           1 : }
+      87             : 
+      88           2 : double ReweightMetad::getLogWeight() {
+      89             :   // Retrieve the bias
+      90           4 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      91           2 :   return bias / simtemp;
+      92             : }
+      93             : 
+      94             : }
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html new file mode 100644 index 0000000000..b8516606c4 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe1906createERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.func.html b/coverage/bias/ReweightTemperaturePressure.cpp.func.html new file mode 100644 index 0000000000..0a25f982f9 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe1906createERKNS_13ActionOptionsE4
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_140ReweightTemperaturePressureRegisterMe190D2Ev4168
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html new file mode 100644 index 0000000000..f035674c4d --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(ReweightTemperaturePressure,"REWEIGHT_TEMP_PRESS")
+     191             : 
+     192           6 : void ReweightTemperaturePressure::registerKeywords(Keywords& keys ) {
+     193           6 :   ReweightBase::registerKeywords( keys );
+     194           6 :   keys.remove("ARG");
+     195          12 :   keys.add("optional","ENERGY","Energy");
+     196          12 :   keys.add("optional","VOLUME","Volume");
+     197          12 :   keys.add("optional","REWEIGHT_PRESSURE","Reweighting pressure");
+     198          12 :   keys.add("optional","PRESSURE","The system pressure");
+     199          12 :   keys.add("optional","REWEIGHT_TEMP","Reweighting temperature");
+     200           6 : }
+     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.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.func-sort-c.html b/coverage/bias/ReweightWham.cpp.func-sort-c.html new file mode 100644 index 0000000000..db133f6dbc --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE14
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96D2Ev4168
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.func.html b/coverage/bias/ReweightWham.cpp.func.html new file mode 100644 index 0000000000..c85168cee0 --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
_ZN4PLMD4bias12ReweightWham16calculateWeightsERKj7
_ZN4PLMD4bias12ReweightWham16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD4bias12ReweightWham9clearDataEv0
_ZN4PLMD4bias12ReweightWhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD4bias12ReweightWhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe966createERKNS_13ActionOptionsE12
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_124ReweightWhamRegisterMe96D2Ev4168
_ZNK4PLMD4bias12ReweightWham17buildsWeightStoreEv12
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.gcov.html b/coverage/bias/ReweightWham.cpp.gcov.html new file mode 100644 index 0000000000..790e94f98e --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + 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-05-27 13:05: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       12528 : PLUMED_REGISTER_ACTION(ReweightWham,"REWEIGHT_WHAM")
+      97             : 
+      98          14 : void ReweightWham::registerKeywords(Keywords& keys ) {
+      99          14 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+     100          28 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+     101          28 :   keys.add("compulsory","MAXITER","1000","maximum number of iterations for WHAM algorithm");
+     102          28 :   keys.add("compulsory","WHAMTOL","1e-10","threshold for convergence of WHAM algorithm");
+     103          14 : }
+     104             : 
+     105          12 : ReweightWham::ReweightWham(const ActionOptions&ao):
+     106             :   Action(ao),
+     107             :   ReweightBase(ao),
+     108          12 :   weightsCalculated(false)
+     109             : {
+     110          24 :   parse("MAXITER",maxiter); parse("WHAMTOL",thresh);
+     111          12 :   if(comm.Get_rank()==0) nreplicas=multi_sim_comm.Get_size();
+     112          12 :   comm.Bcast(nreplicas,0);
+     113          12 : }
+     114             : 
+     115        4224 : double ReweightWham::getLogWeight() {
+     116        4224 :   if( getStep()==0 ) return 1.0;  // This is here as first step is ignored in all analyses
+     117        4212 :   weightsCalculated=false;
+     118        8424 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+     119             : 
+     120        4212 :   std::vector<double> biases(nreplicas,0.0);
+     121        4212 :   if(comm.Get_rank()==0) multi_sim_comm.Allgather(bias,biases);
+     122        4212 :   comm.Bcast(biases,0);
+     123       29484 :   for(unsigned i=0; i<biases.size(); i++) stored_biases.push_back( biases[i] );
+     124             :   return 1.0;
+     125             : }
+     126             : 
+     127           0 : void ReweightWham::clearData() {
+     128           0 :   stored_biases.resize(0);
+     129           0 : }
+     130             : 
+     131        2457 : double ReweightWham::getWeight( const unsigned& iweight ) const {
+     132             :   plumed_dbg_assert( weightsCalculated && iweight<final_weights.size() );
+     133        2457 :   return final_weights[iweight];
+     134             : }
+     135             : 
+     136           7 : void ReweightWham::calculateWeights( const unsigned& nframes ) {
+     137           7 :   if( stored_biases.size()!=nreplicas*nframes ) error("wrong number of weights stored");
+     138             :   // Get the minimum value of the bias
+     139           7 :   double minv = *min_element(std::begin(stored_biases), std::end(stored_biases));
+     140             :   // Resize final weights array
+     141           7 :   plumed_assert( stored_biases.size()%nreplicas==0 );
+     142           7 :   final_weights.resize( stored_biases.size() / nreplicas, 1.0 );
+     143             :   // Offset and exponential of the bias
+     144           7 :   std::vector<double> expv( stored_biases.size() );
+     145       14749 :   for(unsigned i=0; i<expv.size(); ++i) expv[i] = std::exp( (-stored_biases[i]+minv) / simtemp );
+     146             :   // Initialize Z
+     147           7 :   std::vector<double> Z( nreplicas, 1.0 ), oldZ( nreplicas );
+     148             :   // Now the iterative loop to calculate the WHAM weights
+     149        2674 :   for(unsigned iter=0; iter<maxiter; ++iter) {
+     150             :     // Store Z
+     151       18718 :     for(unsigned j=0; j<Z.size(); ++j) oldZ[j]=Z[j];
+     152             :     // Recompute weights
+     153             :     double norm=0;
+     154      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     155             :       double ew=0;
+     156     6570018 :       for(unsigned k=0; k<Z.size(); ++k) ew += expv[j*Z.size()+k]  / Z[k];
+     157      938574 :       final_weights[j] = 1.0 / ew; norm += final_weights[j];
+     158             :     }
+     159             :     // Normalize weights
+     160      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) final_weights[j] /= norm;
+     161             :     // Recompute Z
+     162       18718 :     for(unsigned j=0; j<Z.size(); ++j) Z[j] = 0.0;
+     163      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     164     6570018 :       for(unsigned k=0; k<Z.size(); ++k) Z[k] += final_weights[j]*expv[j*Z.size()+k];
+     165             :     }
+     166             :     // Normalize Z and compute change in Z
+     167       18718 :     double change=0; norm=0; for(unsigned k=0; k<Z.size(); ++k) norm+=Z[k];
+     168       18718 :     for(unsigned k=0; k<Z.size(); ++k) {
+     169       16044 :       Z[k] /= norm; double d = std::log( Z[k] / oldZ[k] ); change += d*d;
+     170             :     }
+     171        2681 :     if( change<thresh ) { weightsCalculated=true; return; }
+     172             :   }
+     173           0 :   error("Too many iterations in WHAM" );
+     174             : }
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func-sort-c.html b/coverage/bias/UWalls.cpp.func-sort-c.html new file mode 100644 index 0000000000..c961040509 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75D2Ev4168
_ZN4PLMD4bias6UWalls9calculateEv28015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func.html b/coverage/bias/UWalls.cpp.func.html new file mode 100644 index 0000000000..9fc4d97df8 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE17
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75C2Ev4168
_ZN4PLMD4bias12_GLOBAL__N_118UWallsRegisterMe75D2Ev4168
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD4bias6UWalls9calculateEv28015
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.gcov.html b/coverage/bias/UWalls.cpp.gcov.html new file mode 100644 index 0000000000..91d26a1437 --- /dev/null +++ b/coverage/bias/UWalls.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05: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       12538 : PLUMED_REGISTER_ACTION(UWalls,"UPPER_WALLS")
+      76             : 
+      77          19 : void UWalls::registerKeywords(Keywords& keys) {
+      78          19 :   Bias::registerKeywords(keys);
+      79          19 :   keys.use("ARG");
+      80          38 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      81          38 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      82          38 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      83          38 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      84          38 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      85          38 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      86          19 : }
+      87             : 
+      88          17 : UWalls::UWalls(const ActionOptions&ao):
+      89             :   PLUMED_BIAS_INIT(ao),
+      90          34 :   at(getNumberOfArguments(),0),
+      91          17 :   kappa(getNumberOfArguments(),0.0),
+      92          17 :   exp(getNumberOfArguments(),2.0),
+      93          17 :   eps(getNumberOfArguments(),1.0),
+      94          34 :   offset(getNumberOfArguments(),0.0)
+      95             : {
+      96             :   // Note : the sizes of these vectors are checked automatically by parseVector
+      97          17 :   parseVector("OFFSET",offset);
+      98          17 :   parseVector("EPS",eps);
+      99          17 :   parseVector("EXP",exp);
+     100          17 :   parseVector("KAPPA",kappa);
+     101          17 :   parseVector("AT",at);
+     102          17 :   checkRead();
+     103             : 
+     104          17 :   log.printf("  at");
+     105          34 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     106          17 :   log.printf("\n");
+     107          17 :   log.printf("  with an offset");
+     108          34 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     109          17 :   log.printf("\n");
+     110          17 :   log.printf("  with force constant");
+     111          34 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     112          17 :   log.printf("\n");
+     113          17 :   log.printf("  and exponent");
+     114          34 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     115          17 :   log.printf("\n");
+     116          17 :   log.printf("  rescaled");
+     117          34 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     118          17 :   log.printf("\n");
+     119             : 
+     120          34 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     121          17 : }
+     122             : 
+     123       28015 : void UWalls::calculate() {
+     124             :   double ene=0.0;
+     125             :   double totf2=0.0;
+     126       56030 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     127             :     double f = 0.0;
+     128       28015 :     const double cv=difference(i,at[i],getArgument(i));
+     129       28015 :     const double off=offset[i];
+     130       28015 :     const double epsilon=eps[i];
+     131       28015 :     const double uscale = (cv+off)/epsilon;
+     132       28015 :     if( uscale > 0.) {
+     133           6 :       const double k=kappa[i];
+     134           6 :       const double exponent=exp[i];
+     135           6 :       double power = pow( uscale, exponent );
+     136           6 :       f = -( k / epsilon ) * exponent * power / uscale;
+     137           6 :       ene += k * power;
+     138           6 :       totf2 += f * f;
+     139             :     }
+     140             :     setOutputForce(i,f);
+     141             :   }
+     142             :   setBias(ene);
+     143       28015 :   getPntrToComponent("force2")->set(totf2);
+     144       28015 : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-f.html b/coverage/bias/index-sort-f.html new file mode 100644 index 0000000000..0ddbc547bd --- /dev/null +++ b/coverage/bias/index-sort-f.html @@ -0,0 +1,273 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2393261791.4 %
Date:2024-05-27 13:05: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
ReweightBase.cpp +
95.0%95.0%
+
95.0 %19 / 2075.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
ReweightWham.cpp +
91.8%91.8%
+
91.8 %45 / 4981.8 %9 / 11
External.cpp +
100.0%
+
100.0 %40 / 4085.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
UWalls.cpp +
100.0%
+
100.0 %55 / 5585.7 %6 / 7
ReweightTemperaturePressure.cpp +
97.9%97.9%
+
97.9 %46 / 4785.7 %6 / 7
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReweightMetad.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
BiasValue.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
Restraint.cpp +
100.0%
+
100.0 %40 / 4085.7 %6 / 7
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10185.7 %6 / 7
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %93 / 9487.5 %7 / 8
PBMetaD.cpp +
88.2%88.2%
+
88.2 %570 / 64688.9 %16 / 18
MaxEnt.cpp +
96.2%96.2%
+
96.2 %227 / 23692.9 %13 / 14
MetaD.cpp +
88.2%88.2%
+
88.2 %955 / 108393.5 %29 / 31
Bias.h +
100.0%
+
100.0 %6 / 6100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-l.html b/coverage/bias/index-sort-l.html new file mode 100644 index 0000000000..663c7892d7 --- /dev/null +++ b/coverage/bias/index-sort-l.html @@ -0,0 +1,273 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2393261791.4 %
Date:2024-05-27 13:05: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
MetaD.cpp +
88.2%88.2%
+
88.2 %955 / 108393.5 %29 / 31
PBMetaD.cpp +
88.2%88.2%
+
88.2 %570 / 64688.9 %16 / 18
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
ReweightBias.cpp +
100.0%
+
100.0 %11 / 1185.7 %6 / 7
ReweightMetad.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
External.cpp +
100.0%
+
100.0 %40 / 4085.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
UWalls.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.16
+
+ + + diff --git a/coverage/bias/index.html b/coverage/bias/index.html new file mode 100644 index 0000000000..1ad1f02415 --- /dev/null +++ b/coverage/bias/index.html @@ -0,0 +1,273 @@ + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2393261791.4 %
Date:2024-05-27 13:05: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.2%88.2%
+
88.2 %955 / 108393.5 %29 / 31
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10185.7 %6 / 7
PBMetaD.cpp +
88.2%88.2%
+
88.2 %570 / 64688.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.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func-sort-c.html b/coverage/cltools/Completion.cpp.func-sort-c.html new file mode 100644 index 0000000000..cf88af09f7 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4168
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func.html b/coverage/cltools/Completion.cpp.func.html new file mode 100644 index 0000000000..893b7a9ba4 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev4168
_ZNK4PLMD7cltools10Completion11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.gcov.html b/coverage/cltools/Completion.cpp.gcov.html new file mode 100644 index 0000000000..cd7b2cc0cf --- /dev/null +++ b/coverage/cltools/Completion.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_CLTOOL(Completion,"completion")
+      65             : 
+      66        4168 : void Completion::registerKeywords( Keywords& keys ) {
+      67        4168 :   CLTool::registerKeywords( keys );
+      68        4168 : }
+      69             : 
+      70           4 : Completion::Completion(const CLToolOptions& co ):
+      71           4 :   CLTool(co)
+      72             : {
+      73           4 :   inputdata=commandline;
+      74           4 : }
+      75             : 
+      76           0 : int Completion::main(FILE* in, FILE*out,Communicator& pc) {
+      77             :   static const char completion [] = {
+      78             : #include "completion.xxd"
+      79             : // cppcheck-suppress syntaxError
+      80             :     , 0x00
+      81             :   };
+      82             :   std::fprintf(out,"local cmds=\"help -h --help");
+      83             : // Build list of available C++ tools:
+      84           0 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+      85             : // Build list of available shell tools:
+      86           0 :   std::vector<std::string> tmp=Tools::ls(std::string(config::getPlumedRoot()+"/scripts"));
+      87           0 :   for(unsigned j=0; j<tmp.size(); ++j) {
+      88           0 :     size_t ff=tmp[j].find(".sh");
+      89           0 :     if(ff==std::string::npos) tmp[j].erase();
+      90           0 :     else                 tmp[j].erase(ff);
+      91             :   }
+      92           0 :   for(unsigned j=0; j<availableCxx.size(); j++) std::fprintf(out," %s",availableCxx[j].c_str());
+      93           0 :   for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) std::fprintf(out," %s",tmp[j].c_str());
+      94             :   std::fprintf(out,"\"\n");
+      95             : 
+      96           0 :   for(unsigned j=0; j<availableCxx.size(); j++) {
+      97           0 :     std::string s=availableCxx[j];
+      98             : // handle - sign (convert to underscore)
+      99             :     for(;;) {
+     100           0 :       size_t n=s.find("-");
+     101           0 :       if(n==std::string::npos) break;
+     102           0 :       s[n]='_';
+     103           0 :     }
+     104             :     std::fprintf(out,"local cmd_keys_%s=\"",s.c_str());
+     105           0 :     std::vector<std::string> keys=cltoolRegister().getKeys(availableCxx[j]);
+     106           0 :     for(unsigned k=0; k<keys.size(); k++) {
+     107             : // handle --help/-h
+     108           0 :       std::string s=keys[k];
+     109             :       for(;;) {
+     110           0 :         size_t n=s.find("/");
+     111           0 :         if(n==std::string::npos) break;
+     112           0 :         s[n]=' ';
+     113           0 :       }
+     114             :       std::fprintf(out," %s",s.c_str());
+     115             :     }
+     116             :     std::fprintf(out,"\"\n");
+     117           0 :   }
+     118             : 
+     119             :   std::fprintf(out,"%s\n",completion);
+     120           0 :   std::string name=config::getPlumedProgramName();
+     121             : 
+     122             :   std::fprintf(out,
+     123             :                "############################################\n"
+     124             :                "## ADD THESE COMMANDS TO YOUR .bashrc FILE:\n"
+     125             :                "############################################\n"
+     126             :                "# _%s() { eval \"$(%s --no-mpi completion 2>/dev/null)\";}\n"
+     127             :                "# complete -F _%s -o default %s\n"
+     128             :                "############################################\n",
+     129             :                name.c_str(),name.c_str(),name.c_str(),name.c_str());
+     130             : 
+     131           0 :   return 0;
+     132           0 : }
+     133             : 
+     134             : } // End of namespace
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.func-sort-c.html b/coverage/cltools/Driver.cpp.func-sort-c.html new file mode 100644 index 0000000000..ef4491bcfc --- /dev/null +++ b/coverage/cltools/Driver.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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:54360789.5 %
Date:2024-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_25
_ZZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_247
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE804
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE808
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE75024
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.func.html b/coverage/cltools/Driver.cpp.func.html new file mode 100644 index 0000000000..0a7dcbfd2a --- /dev/null +++ b/coverage/cltools/Driver.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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:54360789.5 %
Date:2024-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_25
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE804
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE808
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE75024
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_247
_ZZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.gcov.html b/coverage/cltools/Driver.cpp.gcov.html new file mode 100644 index 0000000000..600187140d --- /dev/null +++ b/coverage/cltools/Driver.cpp.gcov.html @@ -0,0 +1,1248 @@ + + + + + + + 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:54360789.5 %
Date:2024-05-27 13:05:14Functions:91275.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE808
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.func.html b/coverage/cltools/DriverDouble.cpp.func.html new file mode 100644 index 0000000000..923c0c1b3d --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE808
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.gcov.html b/coverage/cltools/DriverDouble.cpp.gcov.html new file mode 100644 index 0000000000..7a6f329cbb --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.gcov.html @@ -0,0 +1,113 @@ + + + + + + + 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-05-27 13:05: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       13312 : PLUMED_REGISTER_CLTOOL(DriverDouble,"driver")
+      34             : 
+      35             : }
+      36             : }
+      37             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func-sort-c.html b/coverage/cltools/DriverFloat.cpp.func-sort-c.html new file mode 100644 index 0000000000..c7ba0bc972 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func.html b/coverage/cltools/DriverFloat.cpp.func.html new file mode 100644 index 0000000000..fe3548deb6 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev4168
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.gcov.html b/coverage/cltools/DriverFloat.cpp.gcov.html new file mode 100644 index 0000000000..907c4df708 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_CLTOOL(DriverFloat,"driver-float")
+      39             : 
+      40             : }
+      41             : }
+      42             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func-sort-c.html b/coverage/cltools/GenExample.cpp.func-sort-c.html new file mode 100644 index 0000000000..39580bc3b0 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4168
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func.html b/coverage/cltools/GenExample.cpp.func.html new file mode 100644 index 0000000000..a849c45c28 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10GenExample15createLongInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EE0
_ZN4PLMD7cltools10GenExample16registerKeywordsERNS_8KeywordsE4168
_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_120GenExampleRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev4168
_ZNK4PLMD7cltools10GenExample11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.gcov.html b/coverage/cltools/GenExample.cpp.gcov.html new file mode 100644 index 0000000000..e89a68548f --- /dev/null +++ b/coverage/cltools/GenExample.cpp.gcov.html @@ -0,0 +1,426 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_CLTOOL(GenExample,"gen_example")
+      81             : 
+      82        4168 : void GenExample::registerKeywords( Keywords& keys ) {
+      83        4168 :   CLTool::registerKeywords( keys );
+      84        8336 :   keys.add("compulsory","--plumed","plumed.dat","convert the input in this file to the html manual");
+      85        8336 :   keys.add("compulsory","--out","example.html","the file on which to output the example in html");
+      86        8336 :   keys.add("compulsory","--name","ppp","the name to use for this particular input");
+      87        8336 :   keys.add("compulsory","--status","nobadge","whether or not the input file works");
+      88        8336 :   keys.add("compulsory","--multi","0","set number of replicas for multi environment (needs MPI)");
+      89        4168 : }
+      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.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.func-sort-c.html b/coverage/cltools/GenJson.cpp.func-sort-c.html new file mode 100644 index 0000000000..ddf8c19b50 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9292100.0 %
Date:2024-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools7GenJson4mainEP8_IO_FILES3_RNS_12CommunicatorE1
_ZNK4PLMD7cltools7GenJson11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools7GenJsonC2ERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev4168
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.func.html b/coverage/cltools/GenJson.cpp.func.html new file mode 100644 index 0000000000..136d55b867 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9292100.0 %
Date:2024-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev4168
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools7GenJson4mainEP8_IO_FILES3_RNS_12CommunicatorE1
_ZN4PLMD7cltools7GenJsonC2ERKNS_13CLToolOptionsE5
_ZNK4PLMD7cltools7GenJson11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.gcov.html b/coverage/cltools/GenJson.cpp.gcov.html new file mode 100644 index 0000000000..cff2d3a1c9 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9292100.0 %
Date:2024-05-27 13:05:14Functions:77100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev4168
_ZNK4PLMD7cltools11GenTemplate11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.gcov.html b/coverage/cltools/GenTemplate.cpp.gcov.html new file mode 100644 index 0000000000..f32df2e5e6 --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_CLTOOL(GenTemplate,"gentemplate")
+      64             : 
+      65        4168 : void GenTemplate::registerKeywords( Keywords& keys ) {
+      66        4168 :   CLTool::registerKeywords( keys );
+      67        8336 :   keys.add("optional","--action","print the template for this particular action");
+      68        8336 :   keys.addFlag("--list",false,"print a list of the available actions");
+      69        8336 :   keys.addFlag("--include-optional",false,"also print optional modifiers");
+      70        4168 : }
+      71             : 
+      72           4 : GenTemplate::GenTemplate(const CLToolOptions& co ):
+      73           4 :   CLTool(co)
+      74             : {
+      75           4 :   inputdata=commandline;
+      76           4 : }
+      77             : 
+      78           0 : int GenTemplate::main(FILE* in, FILE*out,Communicator& pc) {
+      79             : 
+      80             :   std::string action;
+      81           0 :   bool list_templates=false;
+      82           0 :   parseFlag("--list",list_templates);
+      83             : 
+      84           0 :   if(list_templates) {
+      85           0 :     std::cerr<<actionRegister()<<"\n";
+      86             :     return 0;
+      87           0 :   } else if(parse("--action",action)) {
+      88             :     bool include_optional;
+      89           0 :     parseFlag("--include-optional",include_optional);
+      90           0 :     if( !actionRegister().printTemplate(action,include_optional) ) {
+      91           0 :       error("there is no registered action named " + action);
+      92             :       return 1;
+      93             :     }
+      94             :   } else return 1;
+      95             : 
+      96             : 
+      97             : 
+      98           0 :   return 0;
+      99             : }
+     100             : }
+     101             : 
+     102             : } // End of namespace
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.func-sort-c.html b/coverage/cltools/Info.cpp.func-sort-c.html new file mode 100644 index 0000000000..d06a26db98 --- /dev/null +++ b/coverage/cltools/Info.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1853
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1857
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1857
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev4168
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.func.html b/coverage/cltools/Info.cpp.func.html new file mode 100644 index 0000000000..0453b25ef1 --- /dev/null +++ b/coverage/cltools/Info.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1857
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev4168
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1853
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1857
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.gcov.html b/coverage/cltools/Info.cpp.gcov.html new file mode 100644 index 0000000000..0a894f89a7 --- /dev/null +++ b/coverage/cltools/Info.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-05-27 13:05: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       14361 : PLUMED_REGISTER_CLTOOL(Info,"info")
+      62             : 
+      63        4168 : void Info::registerKeywords( Keywords& keys ) {
+      64        4168 :   CLTool::registerKeywords( keys );
+      65        8336 :   keys.addFlag("--configuration",false,"prints the configuration file");
+      66        8336 :   keys.addFlag("--root",false,"print the location of the root directory for the plumed source");
+      67        8336 :   keys.addFlag("--user-doc",false,"print the location of user manual (html)");
+      68        8336 :   keys.addFlag("--developer-doc",false,"print the location of user manual (html)");
+      69        8336 :   keys.addFlag("--version",false,"print the version number");
+      70        8336 :   keys.addFlag("--long-version",false,"print the version number (long version)");
+      71        8336 :   keys.addFlag("--git-version",false,"print the version number (git version, if available)");
+      72        8336 :   keys.addFlag("--include-dir",false,"print the location of the include dir");
+      73        8336 :   keys.addFlag("--soext",false,"print the extension of shared libraries (so or dylib)");
+      74        4168 : }
+      75             : 
+      76        1857 : Info::Info(const CLToolOptions& co ):
+      77        1857 :   CLTool(co)
+      78             : {
+      79        1857 :   inputdata=commandline;
+      80        1857 : }
+      81             : 
+      82        1853 : int Info::main(FILE* in, FILE*out,Communicator& pc) {
+      83             : 
+      84        1853 :   bool printconfiguration; parseFlag("--configuration",printconfiguration);
+      85        1853 :   bool printroot; parseFlag("--root",printroot);
+      86        1853 :   bool printuserdoc; parseFlag("--user-doc",printuserdoc);
+      87        1853 :   bool printdeveloperdoc; parseFlag("--developer-doc",printdeveloperdoc);
+      88        1853 :   bool printversion; parseFlag("--version",printversion);
+      89        1853 :   bool printlongversion; parseFlag("--long-version",printlongversion);
+      90        1853 :   bool printgitversion; parseFlag("--git-version",printgitversion);
+      91        1853 :   bool printincludedir; parseFlag("--include-dir",printincludedir);
+      92        1853 :   bool printsoext; parseFlag("--soext",printsoext);
+      93        2461 :   if(printroot) std::fprintf(out,"%s\n",config::getPlumedRoot().c_str());
+      94        1884 :   if(printconfiguration) std::fprintf(out,"%s",config::getMakefile().c_str());
+      95        1853 :   if(printincludedir) std::fprintf(out,"%s\n",config::getPlumedIncludedir().c_str());
+      96        1853 :   if(printuserdoc) {
+      97           0 :     std::string userdoc=config::getPlumedHtmldir()+"/user-doc/html/index.html";
+      98           0 :     FILE *ff=std::fopen(userdoc.c_str(),"r");
+      99             :     // no exception here
+     100           0 :     if(ff) std::fclose(ff);
+     101           0 :     else userdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/user-doc/html/index.html";
+     102             :     std::fprintf(out,"%s\n",userdoc.c_str());
+     103             :   }
+     104        1853 :   if(printdeveloperdoc) {
+     105           0 :     std::string developerdoc=config::getPlumedHtmldir()+"/developer-doc/html/index.html";
+     106           0 :     FILE *ff=std::fopen(developerdoc.c_str(),"r");
+     107             :     // no exception here
+     108           0 :     if(ff) std::fclose(ff);
+     109           0 :     else developerdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/developer-doc/html/index.html";
+     110             :     std::fprintf(out,"%s\n",developerdoc.c_str());
+     111             :   }
+     112        1853 :   if(printversion) std::fprintf(out,"%s\n",config::getVersion().c_str());
+     113        1853 :   if(printlongversion) std::fprintf(out,"%s\n",config::getVersionLong().c_str());
+     114        1853 :   if(printgitversion) std::fprintf(out,"%s\n",config::getVersionGit().c_str());
+     115        3067 :   if(printsoext) std::fprintf(out,"%s\n",config::getSoExt().c_str());
+     116             : 
+     117        1853 :   return 0;
+     118             : }
+     119             : 
+     120             : 
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func-sort-c.html b/coverage/cltools/Manual.cpp.func-sort-c.html new file mode 100644 index 0000000000..6501f8aad1 --- /dev/null +++ b/coverage/cltools/Manual.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE293
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE297
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE297
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev4168
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func.html b/coverage/cltools/Manual.cpp.func.html new file mode 100644 index 0000000000..d4fce9902b --- /dev/null +++ b/coverage/cltools/Manual.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE297
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev4168
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE293
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE297
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.gcov.html b/coverage/cltools/Manual.cpp.gcov.html new file mode 100644 index 0000000000..aee072abf7 --- /dev/null +++ b/coverage/cltools/Manual.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + 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-05-27 13:05: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       12801 : PLUMED_REGISTER_CLTOOL(Manual,"manual")
+      67             : 
+      68        4168 : void Manual::registerKeywords( Keywords& keys ) {
+      69        4168 :   CLTool::registerKeywords( keys );
+      70        8336 :   keys.add("compulsory","--action","print the manual for this particular action");
+      71        8336 :   keys.addFlag("--vim",false,"print the keywords in vim syntax");
+      72        8336 :   keys.addFlag("--spelling",false,"print a list of the keywords and component names for the spell checker");
+      73        4168 : }
+      74             : 
+      75         297 : Manual::Manual(const CLToolOptions& co ):
+      76         297 :   CLTool(co)
+      77             : {
+      78         297 :   inputdata=commandline;
+      79         297 : }
+      80             : 
+      81         293 : int Manual::main(FILE* in, FILE*out,Communicator& pc) {
+      82             : 
+      83             :   std::string action;
+      84         586 :   if( !parse("--action",action) ) return 1;
+      85         293 :   std::cerr<<"LIST OF DOCUMENTED ACTIONS:\n";
+      86         293 :   std::cerr<<actionRegister()<<"\n";
+      87         293 :   std::cerr<<"LIST OF DOCUMENTED COMMAND LINE TOOLS:\n";
+      88         293 :   std::cerr<<cltoolRegister()<<"\n\n";
+      89         293 :   bool vimout; parseFlag("--vim",vimout);
+      90         293 :   bool spellout; parseFlag("--spelling",spellout);
+      91         293 :   if( vimout && spellout ) error("can only use one of --vim and --spelling at a time");
+      92         293 :   if( !actionRegister().printManual(action,vimout,spellout) && !cltoolRegister().printManual(action,spellout) ) {
+      93           1 :     std::fprintf(stderr,"specified action is not registered\n");
+      94             :     return 1;
+      95             :   }
+      96             : 
+      97             :   return 0;
+      98             : }
+      99             : 
+     100             : } // End of namespace
+     101             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.func-sort-c.html b/coverage/cltools/PdbRenumber.cpp.func-sort-c.html new file mode 100644 index 0000000000..2287a1ed23 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4168
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.func.html b/coverage/cltools/PdbRenumber.cpp.func.html new file mode 100644 index 0000000000..d5f3e76f5c --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev4168
_ZNK4PLMD7cltools11PdbRenumber11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.gcov.html b/coverage/cltools/PdbRenumber.cpp.gcov.html new file mode 100644 index 0000000000..3b53e5651a --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + 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-05-27 13:05: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       12511 : PLUMED_REGISTER_CLTOOL(PdbRenumber,"pdbrenumber")
+     113             : 
+     114        4168 : void PdbRenumber::registerKeywords( Keywords& keys ) {
+     115        4168 :   CLTool::registerKeywords( keys );
+     116        8336 :   keys.add("compulsory","--ipdb","specify the name of the input PDB file");
+     117        8336 :   keys.add("compulsory","--opdb","specify the name of the output PDB file");
+     118        8336 :   keys.add("optional","--firstatomnumber","specify the desired serial number of the first atom of the output file");
+     119        8336 :   keys.add("optional","--atomnumbers","specify the desired serial numbers of the atoms of the output file using a separate list");
+     120        4168 : }
+     121             : 
+     122           7 : PdbRenumber::PdbRenumber(const CLToolOptions& co ):
+     123           7 :   CLTool(co)
+     124             : {
+     125           7 :   inputdata=commandline;
+     126           7 : }
+     127             : 
+     128           3 : int PdbRenumber::main(FILE* in, FILE*out,Communicator& pc) {
+     129             : 
+     130             :   std::string ipdb;
+     131           6 :   parse("--ipdb",ipdb);
+     132             :   std::string opdb;
+     133           3 :   parse("--opdb",opdb);
+     134             : 
+     135           3 :   unsigned iat=0;
+     136             : 
+     137           6 :   parse("--firstatomnumber",iat);
+     138             : 
+     139             :   std::string atomnumbers;
+     140           6 :   parse("--atomnumbers",atomnumbers);
+     141             : 
+     142           3 :   plumed_assert(ipdb.length()>0) << "please specify the input PDB with --ipdb";
+     143           3 :   plumed_assert(opdb.length()>0) << "please specify the onput PDB with --opdb";
+     144             :   std::fprintf(out,"  with input PDB: %s\n",ipdb.c_str());
+     145             :   std::fprintf(out,"  with output PDB: %s\n",opdb.c_str());
+     146             : 
+     147             :   std::vector<unsigned> serials;
+     148             : 
+     149           3 :   if(atomnumbers.length()>0) {
+     150           1 :     plumed_assert(iat==0) << "it is not possible to use both --atomnumbers and --firstatomnumber";
+     151             :     std::fprintf(out,"  reading atom numbers from file %s\n",atomnumbers.c_str());
+     152           1 :     IFile ifile;
+     153           1 :     ifile.open(atomnumbers);
+     154             :     std::string line;
+     155           7 :     while(ifile.getline(line)) {
+     156             :       int i;
+     157           6 :       Tools::convert(line,i);
+     158           6 :       serials.push_back(i);
+     159             :     }
+     160           1 :   } else {
+     161           2 :     if(iat==0) iat=1;
+     162           2 :     std::fprintf(out,"  with atoms starting from %u\n",iat);
+     163             :   }
+     164             : 
+     165           3 :   IFile ifile;
+     166           3 :   ifile.open(ipdb);
+     167             : 
+     168           3 :   OFile ofile;
+     169           3 :   ofile.open(opdb);
+     170             : 
+     171             :   std::string line;
+     172      100112 :   while(ifile.getline(line)) {
+     173      100109 :     std::string record=line.substr(0,6);
+     174      100109 :     Tools::trim(record);
+     175             : 
+     176      100109 :     if(record=="ATOM" || record=="HETATM") {
+     177             :       std::array<char,6> at;
+     178      100109 :       unsigned ii=iat;
+     179      100109 :       if(serials.size()>0) {
+     180           6 :         plumed_assert(iat<serials.size()) << "there are more atoms in the PDB than serials in the file";
+     181           6 :         ii=serials[iat];
+     182             :       }
+     183      100109 :       const char* msg = h36::hy36encode(5,ii,&at[0]);
+     184      100109 :       plumed_assert(msg==nullptr) << msg;
+     185      100109 :       at[5]=0;
+     186      200218 :       ofile << line.substr(0,6) << &at[0] << line.substr(11) << "\n";
+     187      100109 :       iat++;
+     188             :     } else {
+     189           0 :       if(record=="END" || record=="ENDMDL") iat=0;
+     190           0 :       ofile << line << "\n";
+     191             :     }
+     192             :   }
+     193             : 
+     194           3 :   return 0;
+     195           3 : }
+     196             : }
+     197             : 
+     198             : } // End of namespace
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func-sort-c.html b/coverage/cltools/SimpleMD.cpp.func-sort-c.html new file mode 100644 index 0000000000..37bce2ee74 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-05-27 13:05:14Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools8SimpleMD11descriptionB5cxx11Ev4
_ZN4PLMD7cltools8SimpleMD10read_inputERdS2_S2_S2_S2_RiS3_S3_RbRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_S3_S3_S2_S2_9
_ZN4PLMD7cltools8SimpleMD11read_natomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi9
_ZN4PLMD7cltools8SimpleMD14read_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_13VectorGenericILj3EEESaISC_EEPd9
_ZN4PLMD7cltools8SimpleMD20randomize_velocitiesEiidRKSt6vectorIdSaIdEERS2_INS_13VectorGenericILj3EEESaIS8_EERNS_6RandomE9
_ZN4PLMD7cltools8SimpleMD21write_final_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb9
_ZN4PLMD7cltools8SimpleMD4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools8SimpleMDC2ERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb39
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd174
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE458
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev4168
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb5700
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd5700
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd5709
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE11400
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_9982883
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func.html b/coverage/cltools/SimpleMD.cpp.func.html new file mode 100644 index 0000000000..4a5498e39e --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-05-27 13:05:14Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev4168
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb5700
_ZN4PLMD7cltools8SimpleMD10read_inputERdS2_S2_S2_S2_RiS3_S3_RbRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_S3_S3_S2_S2_9
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE11400
_ZN4PLMD7cltools8SimpleMD11read_natomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi9
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE458
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd5700
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd5709
_ZN4PLMD7cltools8SimpleMD14read_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_13VectorGenericILj3EEESaISC_EEPd9
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb39
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd174
_ZN4PLMD7cltools8SimpleMD20randomize_velocitiesEiidRKSt6vectorIdSaIdEERS2_INS_13VectorGenericILj3EEESaIS8_EERNS_6RandomE9
_ZN4PLMD7cltools8SimpleMD21write_final_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb9
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_9982883
_ZN4PLMD7cltools8SimpleMD4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools8SimpleMDC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools8SimpleMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.gcov.html b/coverage/cltools/SimpleMD.cpp.gcov.html new file mode 100644 index 0000000000..e6a86f9ce8 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.gcov.html @@ -0,0 +1,684 @@ + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-05-27 13:05:14Functions:2020100.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IS7_SaIS7_EESaISC_EERSC_SG_RbRS7_SI_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev4168
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func.html b/coverage/cltools/SumHills.cpp.func.html new file mode 100644 index 0000000000..bffd9a5d11 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev4168
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IS7_SaIS7_EESaISC_EERSC_SG_RbRS7_SI_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.gcov.html b/coverage/cltools/SumHills.cpp.gcov.html new file mode 100644 index 0000000000..2c759da318 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.gcov.html @@ -0,0 +1,701 @@ + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-05-27 13:05: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(const std::string & filename, std::vector< std::vector <std::string> > &cvs,std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_);
+     196             : };
+     197             : 
+     198        4168 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
+     199        4168 :   CLTool::registerKeywords( keys );
+     200        8336 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
+     201        8336 :   keys.add("optional","--hills","specify the name of the hills file");
+     202        8336 :   keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
+     203        8336 :   keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
+     204        8336 :   keys.add("optional","--min","the lower bounds for the grid");
+     205        8336 :   keys.add("optional","--max","the upper bounds for the grid");
+     206        8336 :   keys.add("optional","--bin","the number of bins for the grid");
+     207        8336 :   keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
+     208        8336 :   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        8336 :   keys.add("optional","--outfile","specify the output file for sumhills");
+     210        8336 :   keys.add("optional","--outhisto","specify the output file for the histogram");
+     211        8336 :   keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
+     212        8336 :   keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
+     213        8336 :   keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
+     214        8336 :   keys.addFlag("--nohistory",false," to be used with --stride:  it splits the bias/histogram in pieces without previous history ");
+     215        8336 :   keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
+     216        8336 :   keys.add("optional","--fmt","specify the output format");
+     217        4168 : }
+     218             : 
+     219          13 : CLToolSumHills::CLToolSumHills(const CLToolOptions& co ):
+     220          13 :   CLTool(co)
+     221             : {
+     222          13 :   inputdata=commandline;
+     223          13 : }
+     224             : 
+     225           4 : std::string CLToolSumHills::description()const { return "sum the hills with  plumed"; }
+     226             : 
+     227           9 : int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc) {
+     228             : 
+     229             : // Read the hills input file name
+     230             :   std::vector<std::string> hillsFiles;
+     231             :   bool dohills;
+     232          18 :   dohills=parseVector("--hills",hillsFiles);
+     233             : // Read the histogram file
+     234             :   std::vector<std::string> histoFiles;
+     235             :   bool dohisto;
+     236           9 :   dohisto=parseVector("--histo",histoFiles);
+     237             : 
+     238           9 :   plumed_massert(dohisto || dohills,"you should use --histo or/and --hills command");
+     239             : 
+     240             :   std::vector< std::vector<std::string> > vcvs;
+     241             :   std::vector<std::string> vpmin;
+     242             :   std::vector<std::string> vpmax;
+     243             :   std::string lowI_, uppI_;
+     244           9 :   if(dohills) {
+     245             :     // parse it as it was a restart
+     246             :     bool vmultivariate;
+     247           8 :     findCvsAndPeriodic(hillsFiles[0], vcvs, vpmin, vpmax, vmultivariate, lowI_, uppI_);
+     248             :   }
+     249             : 
+     250             :   std::vector< std::vector<std::string> > hcvs;
+     251             :   std::vector<std::string> hpmin;
+     252             :   std::vector<std::string> hpmax;
+     253             : 
+     254             :   std::vector<std::string> sigma;
+     255           9 :   if(dohisto) {
+     256             :     bool hmultivariate;
+     257           1 :     findCvsAndPeriodic(histoFiles[0], hcvs, hpmin, hpmax, hmultivariate, lowI_, uppI_);
+     258             :     // here need also the vector of sigmas
+     259           2 :     parseVector("--sigma",sigma);
+     260           1 :     if(sigma.size()==0)plumed_merror("you should define --sigma vector when using histogram");
+     261             :     lowI_=uppI_="-1.";  // Interval is not use for histograms
+     262             :   }
+     263             : 
+     264           9 :   if(dohisto && dohills) {
+     265           0 :     plumed_massert(vcvs==hcvs,"variables for histogram and bias should have the same labels");
+     266           0 :     plumed_massert(hpmin==vpmin,"variables for histogram and bias should have the same min for periodicity");
+     267           0 :     plumed_massert(hpmax==vpmax,"variables for histogram and bias should have the same max for periodicity");
+     268             :   }
+     269             : 
+     270             :   // now put into a neutral vector
+     271             : 
+     272             :   std::vector< std::vector<std::string> > cvs;
+     273             :   std::vector<std::string> pmin;
+     274             :   std::vector<std::string> pmax;
+     275             : 
+     276           9 :   if(dohills) {
+     277           8 :     cvs=vcvs;
+     278           8 :     pmin=vpmin;
+     279           8 :     pmax=vpmax;
+     280             :   }
+     281           9 :   if(dohisto) {
+     282           1 :     cvs=hcvs;
+     283           1 :     pmin=hpmin;
+     284           1 :     pmax=hpmax;
+     285             :   }
+     286             : 
+     287             : 
+     288             :   // setup grids
+     289             :   unsigned grid_check=0;
+     290           9 :   std::vector<std::string> gmin(cvs.size());
+     291          18 :   if(parseVector("--min",gmin)) {
+     292           4 :     if(gmin.size()!=cvs.size() && gmin.size()!=0) plumed_merror("not enough values for --min");
+     293             :     grid_check++;
+     294             :   }
+     295           9 :   std::vector<std::string> gmax(cvs.size() );
+     296          18 :   if(parseVector("--max",gmax)) {
+     297           4 :     if(gmax.size()!=cvs.size() && gmax.size()!=0) plumed_merror("not enough values for --max");
+     298           4 :     grid_check++;
+     299             :   }
+     300           9 :   std::vector<std::string> gbin(cvs.size());
+     301             :   bool grid_has_bin; grid_has_bin=false;
+     302          18 :   if(parseVector("--bin",gbin)) {
+     303           5 :     if(gbin.size()!=cvs.size() && gbin.size()!=0) plumed_merror("not enough values for --bin");
+     304             :     grid_has_bin=true;
+     305             :   }
+     306           9 :   std::vector<std::string> gspacing(cvs.size());
+     307             :   bool grid_has_spacing; grid_has_spacing=false;
+     308          18 :   if(parseVector("--spacing",gspacing)) {
+     309           1 :     if(gspacing.size()!=cvs.size() && gspacing.size()!=0) plumed_merror("not enough values for --spacing");
+     310             :     grid_has_spacing=true;
+     311             :   }
+     312             :   // allowed: no grids only bin
+     313             :   // not allowed: partial grid definition
+     314           9 :   plumed_massert( gmin.size()==gmax.size() && (gmin.size()==0 ||  gmin.size()==cvs.size() ),"you should specify --min and --max together with same number of components");
+     315             : 
+     316             : 
+     317             : 
+     318           9 :   PlumedMain plumed;
+     319             :   std::string ss;
+     320           9 :   unsigned nn=1;
+     321             :   ss="setNatoms";
+     322           9 :   plumed.cmd(ss,&nn);
+     323           9 :   if(Communicator::initialized())  plumed.cmd("setMPIComm",&pc.Get_comm());
+     324          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          10 :     addme="GRID_BIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gbin[i]+","; addme+=gbin[ncv-1];
+     463           5 :     actioninput.push_back(addme);
+     464             :   }
+     465           9 :   if(grid_has_spacing) {
+     466           1 :     addme="GRID_SPACING="; for(unsigned i=0; i<(ncv-1); i++)addme+=gspacing[i]+","; addme+=gspacing[ncv-1];
+     467           1 :     actioninput.push_back(addme);
+     468             :   }
+     469             :   std::string  stride; stride="";
+     470          18 :   if(parse("--stride",stride)) {
+     471           1 :     actioninput.push_back("INITSTRIDE="+stride);
+     472             :     bool  nohistory;
+     473           1 :     parseFlag("--nohistory",nohistory);
+     474           1 :     if(nohistory) {
+     475           0 :       actioninput.push_back("NOHISTORY");
+     476             :     }
+     477             :   }
+     478             :   bool  mintozero;
+     479           9 :   parseFlag("--mintozero",mintozero);
+     480           9 :   if(mintozero) {
+     481           0 :     actioninput.push_back("MINTOZERO");
+     482             :   }
+     483           9 :   if(idw.size()!=0) {
+     484             :     addme="PROJ=";
+     485           2 :     for(unsigned i=0; i<idw.size()-1; i++) {addme+=idw[i]+",";}
+     486             :     addme+=idw.back();
+     487           2 :     actioninput.push_back(addme);
+     488             :   }
+     489             : 
+     490           9 :   if(dohisto) {
+     491           1 :     if(idw.size()==0) {
+     492           1 :       if(sigma.size()!=hcvs.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+     493             :     } else {
+     494           0 :       if(idw.size()!=sigma.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+     495             :     }
+     496             :   }
+     497             : 
+     498           9 :   if(idw.size()!=0 || dohisto) {
+     499           6 :     actioninput.push_back("KT="+kt);
+     500             :   }
+     501           9 :   if(dohisto) {
+     502           1 :     addme="HISTOFILES="; for(unsigned i=0; i<histoFiles.size()-1; i++) {addme+=histoFiles[i]+",";} addme+=histoFiles[histoFiles.size()-1];
+     503           1 :     actioninput.push_back(addme);
+     504             : 
+     505             :     addme="HISTOSIGMA=";
+     506           2 :     for(unsigned i=0; i<sigma.size()-1; i++) {addme+=sigma[i]+",";}
+     507             :     addme+=sigma.back();
+     508           1 :     actioninput.push_back(addme);
+     509             :   }
+     510             : 
+     511             :   bool negbias;
+     512           9 :   parseFlag("--negbias",negbias);
+     513           9 :   if(negbias) {
+     514           2 :     actioninput.push_back("NEGBIAS");
+     515             :   }
+     516             : 
+     517           9 :   if(lowI_!=uppI_) {
+     518           0 :     addme="INTERVAL="; addme+=lowI_+","; addme+=uppI_;
+     519           0 :     actioninput.push_back(addme);
+     520             :   }
+     521             : 
+     522             :   std::string fmt; fmt="";
+     523          18 :   parse("--fmt",fmt);
+     524          18 :   if(fmt!="")actioninput.push_back("FMT="+fmt);
+     525             : 
+     526             : 
+     527             : //  for(unsigned i=0;i< actioninput.size();i++){
+     528             : //   cerr<<"AA "<<actioninput[i]<<endl;
+     529             : //  }
+     530           9 :   plumed.readInputWords(actioninput);
+     531             :   // if not a grid, then set it up automatically
+     532           9 :   return 0;
+     533          27 : }
+     534             : 
+     535           9 : bool CLToolSumHills::findCvsAndPeriodic(const std::string & filename, std::vector< std::vector<std::string>  > &cvs, std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_) {
+     536           9 :   IFile ifile;
+     537           9 :   ifile.allowIgnoredFields();
+     538             :   std::vector<std::string> fields;
+     539           9 :   if(ifile.FileExist(filename)) {
+     540             :     cvs.clear(); pmin.clear(); pmax.clear();
+     541           9 :     ifile.open(filename);
+     542           9 :     ifile.scanFieldList(fields);
+     543             :     bool before_sigma=true;
+     544         121 :     for(unsigned i=0; i<fields.size(); i++) {
+     545             :       size_t pos = 0;
+     546             :       size_t founds,foundm,foundp;
+     547             :       //found=(fields[i].find("sigma_", pos) || fields[i].find("min_", pos) || fields[i].find("max_", pos) ) ;
+     548         112 :       founds=fields[i].find("sigma_", pos)  ;
+     549         112 :       foundm=fields[i].find("min_", pos)  ;
+     550         112 :       foundp=fields[i].find("max_", pos)  ;
+     551         112 :       if (founds!=std::string::npos || foundm!=std::string::npos ||  foundp!=std::string::npos )before_sigma=false;
+     552             :       // cvs are after time and before sigmas
+     553             :       size_t  found;
+     554         112 :       found=fields[i].find("time", pos);
+     555         112 :       if( found==std::string::npos && before_sigma) {
+     556             :         // separate the components
+     557             :         size_t dot=fields[i].find_first_of('.');
+     558             :         std::vector<std::string> ss;
+     559             :         // this loop does not take into account repetitions
+     560          17 :         if(dot!=std::string::npos) {
+     561           1 :           std::string a=fields[i].substr(0,dot);
+     562           1 :           std::string name=fields[i].substr(dot+1);
+     563           1 :           ss.push_back(a);
+     564           1 :           ss.push_back(name);
+     565           1 :           cvs.push_back(ss);
+     566             :         } else {
+     567             :           std::vector<std::string> ss;
+     568          16 :           ss.push_back(fields[i]);
+     569          16 :           cvs.push_back(ss);
+     570          16 :         }
+     571             :         //std::cerr<<"found variable number  "<<cvs.size()<<" :  "<<cvs.back()[0]<<std::endl;
+     572             :         //if((cvs.back()).size()!=1){
+     573             :         //      std::cerr<<"component    "<<(cvs.back()).back()<<std::endl;
+     574             :         //}
+     575             :         // get periodicity
+     576          17 :         pmin.push_back("none");
+     577          34 :         pmax.push_back("none");
+     578          18 :         std::string mm; if((cvs.back()).size()>1) {mm=cvs.back()[0]+"."+cvs.back()[1];} else {mm=cvs.back()[0];}
+     579          34 :         if(ifile.FieldExist("min_"+mm)) {
+     580             :           std::string val;
+     581          28 :           ifile.scanField("min_"+mm,val);
+     582             :           pmin[pmin.size()-1]=val;
+     583             :           // std::cerr<<"found min   :  "<<pmin.back()<<std::endl;
+     584             :         }
+     585             :         //std::cerr<<"found min   :  "<<pmin.back()<<std::endl;
+     586          34 :         if(ifile.FieldExist("max_"+mm)) {
+     587             :           std::string val;
+     588          28 :           ifile.scanField("max_"+mm,val);
+     589             :           pmax[pmax.size()-1]=val;
+     590             :           // std::cerr<<"found max   :  "<<pmax.back()<<std::endl;
+     591             :         }
+     592             :         //std::cerr<<"found max   :  "<<pmax.back()<<std::endl;
+     593          17 :       }
+     594             :     }
+     595             :     // is multivariate ???
+     596             :     std::string sss;
+     597           9 :     multivariate=false;
+     598          18 :     if(ifile.FieldExist("multivariate")) {
+     599             :       ;
+     600          18 :       ifile.scanField("multivariate",sss);
+     601           9 :       if(sss=="true") { multivariate=true;}
+     602           3 :       else if(sss=="false") { multivariate=false;}
+     603             :     }
+     604             :     // do interval?
+     605          18 :     if(ifile.FieldExist("lower_int")) {
+     606           0 :       ifile.scanField("lower_int",lowI_);
+     607           0 :       ifile.scanField("upper_int",uppI_);
+     608             :     } else {
+     609             :       lowI_="-1.";
+     610             :       uppI_="-1.";
+     611             :     }
+     612           9 :     ifile.scanField();
+     613             :     return true;
+     614             :   } else {
+     615             :     return false;
+     616             :   }
+     617           9 : }
+     618             : 
+     619             : 
+     620       12517 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
+     621             : 
+     622             : 
+     623             : 
+     624             : }
+     625             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-f.html b/coverage/cltools/index-sort-f.html new file mode 100644 index 0000000000..95baca6380 --- /dev/null +++ b/coverage/cltools/index-sort-f.html @@ -0,0 +1,223 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1359169980.0 %
Date:2024-05-27 13:05:14Functions:10311292.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
89.5%89.5%
+
89.5 %543 / 60775.0 %9 / 12
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
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %92 / 92100.0 %7 / 7
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.0 %7 / 7
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-l.html b/coverage/cltools/index-sort-l.html new file mode 100644 index 0000000000..80a91351d7 --- /dev/null +++ b/coverage/cltools/index-sort-l.html @@ -0,0 +1,223 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1359169980.0 %
Date:2024-05-27 13:05:14Functions:10311292.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
Driver.cpp +
89.5%89.5%
+
89.5 %543 / 60775.0 %9 / 12
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %92 / 92100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.0 %7 / 7
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index.html b/coverage/cltools/index.html new file mode 100644 index 0000000000..4f3a35df25 --- /dev/null +++ b/coverage/cltools/index.html @@ -0,0 +1,223 @@ + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1359169980.0 %
Date:2024-05-27 13:05:14Functions:10311292.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
89.5%89.5%
+
89.5 %543 / 60775.0 %9 / 12
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
GenExample.cpp +
7.7%7.7%
+
7.7 %17 / 22066.7 %6 / 9
GenJson.cpp +
100.0%
+
100.0 %92 / 92100.0 %7 / 7
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
kT.cpp +
63.2%63.2%
+
63.2 %12 / 1985.7 %6 / 7
pesmd.cpp +
100.0%
+
100.0 %128 / 128100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func-sort-c.html b/coverage/cltools/kT.cpp.func-sort-c.html new file mode 100644 index 0000000000..2f70f34d82 --- /dev/null +++ b/coverage/cltools/kT.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_112ktRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev4168
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func.html b/coverage/cltools/kT.cpp.func.html new file mode 100644 index 0000000000..dcc79ccd42 --- /dev/null +++ b/coverage/cltools/kT.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev4168
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.gcov.html b/coverage/cltools/kT.cpp.gcov.html new file mode 100644 index 0000000000..db120c07e3 --- /dev/null +++ b/coverage/cltools/kT.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + 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-05-27 13:05: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 k_B T 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       12508 : PLUMED_REGISTER_CLTOOL(kt,"kt")
+      63             : 
+      64        4168 : void kt::registerKeywords( Keywords& keys ) {
+      65        4168 :   CLTool::registerKeywords( keys );
+      66        8336 :   keys.add("compulsory","--temp","print the manual for this particular action");
+      67        8336 :   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        4168 : }
+      69             : 
+      70           4 : kt::kt(const CLToolOptions& co ):
+      71           4 :   CLTool(co)
+      72             : {
+      73           4 :   inputdata=commandline;
+      74           4 : }
+      75             : 
+      76           0 : int kt::main(FILE* in, FILE*out,Communicator& pc) {
+      77             : 
+      78           0 :   std::string unitname; parse("--units",unitname);
+      79           0 :   Units units; units.setEnergy( unitname );
+      80           0 :   double temp; parse("--temp",temp);
+      81           0 :   double kk=(kBoltzmann*temp)/units.getEnergy();
+      82             :   std::fprintf(out,"When the temperature is %f kelvin kT is equal to %f %s\n",temp,kk,unitname.c_str());
+      83           0 :   return 0;
+      84           0 : }
+      85             : 
+      86             : } // End of namespace
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func-sort-c.html b/coverage/cltools/pesmd.cpp.func-sort-c.html new file mode 100644 index 0000000000..3d77ad84f9 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_115PesMDRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev4168
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func.html b/coverage/cltools/pesmd.cpp.func.html new file mode 100644 index 0000000000..306e7fcbda --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev4168
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev4168
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD7cltools5PesMD4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools5PesMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.gcov.html b/coverage/cltools/pesmd.cpp.gcov.html new file mode 100644 index 0000000000..94e24a9ba7 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.gcov.html @@ -0,0 +1,389 @@ + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:128128100.0 %
Date:2024-05-27 13:05: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        4168 :   static void registerKeywords( Keywords& keys ) {
+     104        8336 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+     105        8336 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+     106        8336 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     107        8336 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     108        8336 :     keys.add("compulsory","dimension","the dimension of your energy landscape");
+     109        8336 :     keys.add("compulsory","plumed","plumed.dat","the name of the plumed input file containing the potential");
+     110        8336 :     keys.add("compulsory","ipos","0.0","the initial position of the system");
+     111        8336 :     keys.add("compulsory","idum","0","The random number seed");
+     112        8336 :     keys.addFlag("periodic",false,"are your input coordinates periodic");
+     113        8336 :     keys.add("optional","min","minimum value the coordinates can take for a periodic domain");
+     114        8336 :     keys.add("optional","max","maximum value the coordinates can take for a periodic domain");
+     115        4168 :   }
+     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           3 :     Tools::set_to_zero(forces);
+     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         150 :       Tools::set_to_zero(forces);
+     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       12511 : PLUMED_REGISTER_CLTOOL(PesMD,"pesmd")
+     311             : 
+     312             : }
+     313             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func-sort-c.html b/coverage/colvar/Angle.cpp.func-sort-c.html new file mode 100644 index 0000000000..ae0ee4fe05 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe916createERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD6colvar5Angle9calculateEv304
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func.html b/coverage/colvar/Angle.cpp.func.html new file mode 100644 index 0000000000..e59e850e13 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe916createERKNS_13ActionOptionsE18
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_117AngleRegisterMe91D2Ev4168
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD6colvar5Angle9calculateEv304
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.gcov.html b/coverage/colvar/Angle.cpp.gcov.html new file mode 100644 index 0000000000..29ed56b778 --- /dev/null +++ b/coverage/colvar/Angle.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + 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-05-27 13:05: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       12539 : PLUMED_REGISTER_ACTION(Angle,"ANGLE")
+      92             : 
+      93          20 : void Angle::registerKeywords( Keywords& keys ) {
+      94          20 :   Colvar::registerKeywords(keys);
+      95          40 :   keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
+      96          20 : }
+      97             : 
+      98          18 : Angle::Angle(const ActionOptions&ao):
+      99             :   PLUMED_COLVAR_INIT(ao),
+     100          18 :   pbc(true)
+     101             : {
+     102             :   std::vector<AtomNumber> atoms;
+     103          18 :   parseAtomList("ATOMS",atoms);
+     104          18 :   bool nopbc=!pbc;
+     105          18 :   parseFlag("NOPBC",nopbc);
+     106          18 :   pbc=!nopbc;
+     107             : 
+     108          18 :   if(atoms.size()==3) {
+     109          12 :     log.printf("  between atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
+     110          12 :     atoms.resize(4);
+     111          12 :     atoms[3]=atoms[2];
+     112          12 :     atoms[2]=atoms[1];
+     113           6 :   } else if(atoms.size()==4) {
+     114           5 :     log.printf("  between lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     115           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.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func-sort-c.html b/coverage/colvar/Cell.cpp.func-sort-c.html new file mode 100644 index 0000000000..ff9de9e172 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe586createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar4Cell9calculateEv150
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func.html b/coverage/colvar/Cell.cpp.func.html new file mode 100644 index 0000000000..8ad69406a5 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe586createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_116CellRegisterMe58D2Ev4168
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar4Cell9calculateEv150
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.gcov.html b/coverage/colvar/Cell.cpp.gcov.html new file mode 100644 index 0000000000..20c1ebf75c --- /dev/null +++ b/coverage/colvar/Cell.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + 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-05-27 13:05: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       12522 : PLUMED_REGISTER_ACTION(Cell,"CELL")
+      59             : 
+      60           9 : Cell::Cell(const ActionOptions&ao):
+      61           9 :   PLUMED_COLVAR_INIT(ao)
+      62             : {
+      63             :   std::vector<AtomNumber> atoms;
+      64           9 :   checkRead();
+      65             : 
+      66          27 :   addComponentWithDerivatives("ax"); componentIsNotPeriodic("ax"); components[0][0]=getPntrToComponent("ax");
+      67          27 :   addComponentWithDerivatives("ay"); componentIsNotPeriodic("ay"); components[0][1]=getPntrToComponent("ay");
+      68          27 :   addComponentWithDerivatives("az"); componentIsNotPeriodic("az"); components[0][2]=getPntrToComponent("az");
+      69          27 :   addComponentWithDerivatives("bx"); componentIsNotPeriodic("bx"); components[1][0]=getPntrToComponent("bx");
+      70          27 :   addComponentWithDerivatives("by"); componentIsNotPeriodic("by"); components[1][1]=getPntrToComponent("by");
+      71          27 :   addComponentWithDerivatives("bz"); componentIsNotPeriodic("bz"); components[1][2]=getPntrToComponent("bz");
+      72          27 :   addComponentWithDerivatives("cx"); componentIsNotPeriodic("cx"); components[2][0]=getPntrToComponent("cx");
+      73          27 :   addComponentWithDerivatives("cy"); componentIsNotPeriodic("cy"); components[2][1]=getPntrToComponent("cy");
+      74          27 :   addComponentWithDerivatives("cz"); componentIsNotPeriodic("cz"); components[2][2]=getPntrToComponent("cz");
+      75           9 :   requestAtoms(atoms);
+      76           9 : }
+      77             : 
+      78          11 : void Cell::registerKeywords( Keywords& keys ) {
+      79          11 :   Action::registerKeywords( keys );
+      80          11 :   ActionWithValue::registerKeywords( keys );
+      81          11 :   ActionAtomistic::registerKeywords( keys );
+      82          11 :   componentsAreNotOptional(keys);
+      83          22 :   keys.addOutputComponent("ax","default","the ax component of the cell matrix");
+      84          22 :   keys.addOutputComponent("ay","default","the ay component of the cell matrix");
+      85          22 :   keys.addOutputComponent("az","default","the az component of the cell matrix");
+      86          22 :   keys.addOutputComponent("bx","default","the bx component of the cell matrix");
+      87          22 :   keys.addOutputComponent("by","default","the by component of the cell matrix");
+      88          22 :   keys.addOutputComponent("bz","default","the bz component of the cell matrix");
+      89          22 :   keys.addOutputComponent("cx","default","the cx component of the cell matrix");
+      90          22 :   keys.addOutputComponent("cy","default","the cy component of the cell matrix");
+      91          22 :   keys.addOutputComponent("cz","default","the cz component of the cell matrix");
+      92          11 : }
+      93             : 
+      94             : 
+      95             : // calculator
+      96         150 : void Cell::calculate() {
+      97             : 
+      98        1950 :   for(int i=0; i<3; i++) for(int j=0; j<3; j++) components[i][j]->set(getBox()[i][j]);
+      99        1950 :   for(int l=0; l<3; l++) for(int m=0; m<3; m++) {
+     100        5400 :       Tensor der; for(int i=0; i<3; i++) der[i][m]=getBox()[l][i];
+     101        1350 :       setBoxDerivatives(components[l][m],-der);
+     102             :     }
+     103         150 : }
+     104             : 
+     105             : }
+     106             : }
+     107             : 
+     108             : 
+     109             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.func-sort-c.html b/coverage/colvar/Constant.cpp.func-sort-c.html new file mode 100644 index 0000000000..34fbcdd67f --- /dev/null +++ b/coverage/colvar/Constant.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe696createERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar8Constant9calculateEv3401
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.func.html b/coverage/colvar/Constant.cpp.func.html new file mode 100644 index 0000000000..4fa603dceb --- /dev/null +++ b/coverage/colvar/Constant.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe696createERKNS_13ActionOptionsE39
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120ConstantRegisterMe69D2Ev4168
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar8Constant9calculateEv3401
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.gcov.html b/coverage/colvar/Constant.cpp.gcov.html new file mode 100644 index 0000000000..0f3787c9b3 --- /dev/null +++ b/coverage/colvar/Constant.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + LCOV - plumed test coverage - colvar/Constant.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434595.6 %
Date:2024-05-27 13:05: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       12582 : 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          41 : void Constant::registerKeywords( Keywords& keys ) {
+     108          41 :   Colvar::registerKeywords( keys );
+     109          41 :   componentsAreNotOptional(keys);
+     110          41 :   keys.remove("NUMERICAL_DERIVATIVES");
+     111          82 :   keys.add("optional","VALUES","The values of the constants");
+     112          82 :   keys.add("optional","VALUE","The value of the constant");
+     113          82 :   keys.addFlag("NODERIV",false,"Set to TRUE if you want values without derivatives.");
+     114          82 :   keys.addOutputComponent("v","default","the # value");
+     115          41 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func-sort-c.html b/coverage/colvar/ContactMap.cpp.func-sort-c.html new file mode 100644 index 0000000000..b4abcf85ff --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZN4PLMD6colvar10ContactMap9calculateEv2215
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func.html b/coverage/colvar/ContactMap.cpp.func.html new file mode 100644 index 0000000000..747bbf1b45 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ContactMap16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar10ContactMap18checkFieldsAllowedEv0
_ZN4PLMD6colvar10ContactMap9calculateEv2215
_ZN4PLMD6colvar10ContactMapC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar10ContactMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe1186createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_123ContactMapRegisterMe118D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.gcov.html b/coverage/colvar/ContactMap.cpp.gcov.html new file mode 100644 index 0000000000..05859f34a2 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.gcov.html @@ -0,0 +1,402 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(ContactMap,"CONTACTMAP")
+     119             : 
+     120          10 : void ContactMap::registerKeywords( Keywords& keys ) {
+     121          10 :   Colvar::registerKeywords( keys );
+     122          20 :   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          20 :   keys.reset_style("ATOMS","atoms");
+     126          20 :   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          20 :   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          20 :   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          20 :   keys.reset_style("SWITCH","compulsory");
+     137          20 :   keys.addFlag("SUM",false,"calculate the sum of all the contacts in the input");
+     138          20 :   keys.addFlag("CMDIST",false,"calculate the distance with respect to the provided reference contact map");
+     139          20 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     140          20 :   keys.addOutputComponent("contact","default","By not using SUM or CMDIST each contact will be stored in a component");
+     141          10 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func-sort-c.html b/coverage/colvar/Coordination.cpp.func-sort-c.html new file mode 100644 index 0000000000..1791976384 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe1056createERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE187
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105D2Ev4168
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263796
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func.html b/coverage/colvar/Coordination.cpp.func.html new file mode 100644 index 0000000000..ccd714eb48 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE187
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe1056createERKNS_13ActionOptionsE185
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_125CoordinationRegisterMe105D2Ev4168
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263796
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.gcov.html b/coverage/colvar/Coordination.cpp.gcov.html new file mode 100644 index 0000000000..7603c07cca --- /dev/null +++ b/coverage/colvar/Coordination.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + 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-05-27 13:05: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       12869 : PLUMED_REGISTER_ACTION(Coordination,"COORDINATION")
+     106             : 
+     107         187 : void Coordination::registerKeywords( Keywords& keys ) {
+     108         187 :   CoordinationBase::registerKeywords(keys);
+     109         374 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     110         374 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     111         374 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     112         374 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     113         374 :   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         187 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func-sort-c.html b/coverage/colvar/CoordinationBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..148321c5ec --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE194
_ZN4PLMD6colvar16CoordinationBaseD2Ev194
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE200
_ZN4PLMD6colvar16CoordinationBase9calculateEv3132
_ZN4PLMD6colvar16CoordinationBase7prepareEv3357
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func.html b/coverage/colvar/CoordinationBase.cpp.func.html new file mode 100644 index 0000000000..6fe11d5602 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE200
_ZN4PLMD6colvar16CoordinationBase7prepareEv3357
_ZN4PLMD6colvar16CoordinationBase9calculateEv3132
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE194
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseD2Ev194
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.gcov.html b/coverage/colvar/CoordinationBase.cpp.gcov.html new file mode 100644 index 0000000000..b1a43e8a08 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.gcov.html @@ -0,0 +1,283 @@ + + + + + + + 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-05-27 13:05: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         200 : void CoordinationBase::registerKeywords( Keywords& keys ) {
+      31         200 :   Colvar::registerKeywords(keys);
+      32         400 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      33         400 :   keys.addFlag("PAIR",false,"Pair only 1st element of the 1st group with 1st element in the second, etc");
+      34         400 :   keys.addFlag("NLIST",false,"Use a neighbor list to speed up the calculation");
+      35         400 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbor list");
+      36         400 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbor list");
+      37         400 :   keys.add("atoms","GROUPA","First list of atoms");
+      38         400 :   keys.add("atoms","GROUPB","Second list of atoms (if empty, N*(N-1)/2 pairs in GROUPA are counted)");
+      39         200 : }
+      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.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func-sort-c.html b/coverage/colvar/DHEnergy.cpp.func-sort-c.html new file mode 100644 index 0000000000..b1e744c1cc --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe756createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func.html b/coverage/colvar/DHEnergy.cpp.func.html new file mode 100644 index 0000000000..5612220794 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe756createERKNS_13ActionOptionsE8
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120DHEnergyRegisterMe75D2Ev4168
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.gcov.html b/coverage/colvar/DHEnergy.cpp.gcov.html new file mode 100644 index 0000000000..e75738d3d8 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323494.1 %
Date:2024-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(DHEnergy,"DHENERGY")
+      76             : 
+      77          10 : void DHEnergy::registerKeywords( Keywords& keys ) {
+      78          10 :   CoordinationBase::registerKeywords(keys);
+      79          20 :   keys.add("compulsory","I","1.0","Ionic strength (M)");
+      80          20 :   keys.add("compulsory","TEMP","300.0","Simulation temperature (K)");
+      81          20 :   keys.add("compulsory","EPSILON","80.0","Dielectric constant of solvent");
+      82          10 : }
+      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.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func-sort-c.html b/coverage/colvar/DRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..d6682ecff7 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe1226createERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar5DRMSD9calculateEv595
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func.html b/coverage/colvar/DRMSD.cpp.func.html new file mode 100644 index 0000000000..81b963400a --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe1226createERKNS_13ActionOptionsE12
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DRMSDRegisterMe122D2Ev4168
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar5DRMSD9calculateEv595
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.gcov.html b/coverage/colvar/DRMSD.cpp.gcov.html new file mode 100644 index 0000000000..9a9a197f7e --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + LCOV - plumed test coverage - colvar/DRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4444100.0 %
Date:2024-05-27 13:05: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       12527 : PLUMED_REGISTER_ACTION(DRMSD,"DRMSD")
+     123             : 
+     124          14 : void DRMSD::registerKeywords(Keywords& keys) {
+     125          14 :   Colvar::registerKeywords(keys);
+     126          28 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     127          28 :   keys.add("compulsory","LOWER_CUTOFF","only pairs of atoms further than LOWER_CUTOFF are considered in the calculation.");
+     128          28 :   keys.add("compulsory","UPPER_CUTOFF","only pairs of atoms closer than UPPER_CUTOFF are considered in the calculation.");
+     129          28 :   keys.add("compulsory","TYPE","DRMSD","what kind of DRMSD would you like to calculate.  You can use either the normal DRMSD involving all the distances between "
+     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          14 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func-sort-c.html b/coverage/colvar/Dimer.cpp.func-sort-c.html new file mode 100644 index 0000000000..d938da8084 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD6colvar5Dimer9calculateEv4
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func.html b/coverage/colvar/Dimer.cpp.func.html new file mode 100644 index 0000000000..48d232f0a6 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe1436createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DimerRegisterMe143D2Ev4168
_ZN4PLMD6colvar5Dimer16consistencyCheckEv2
_ZN4PLMD6colvar5Dimer16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar5Dimer9calculateEv4
_ZN4PLMD6colvar5DimerC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5DimerC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.gcov.html b/coverage/colvar/Dimer.cpp.gcov.html new file mode 100644 index 0000000000..9a5b00eaf4 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.gcov.html @@ -0,0 +1,393 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(Dimer, "DIMER")
+     144             : 
+     145             : 
+     146             : 
+     147           4 : void Dimer::registerKeywords( Keywords& keys) {
+     148           4 :   Colvar::registerKeywords(keys);
+     149             : 
+     150           8 :   keys.add("compulsory","DSIGMA","The interaction strength of the dimer bond.");
+     151           8 :   keys.add("compulsory", "Q", "The exponent of the dimer potential.");
+     152           8 :   keys.add("compulsory", "TEMP", "The temperature (in Kelvin) of the simulation.");
+     153           8 :   keys.add("atoms", "ATOMS1", "The list of atoms representing the first bead of each Dimer being considered by this CV. Used if ALLATOMS flag is missing");
+     154           8 :   keys.add("atoms", "ATOMS2", "The list of atoms representing the second bead of each Dimer being considered by this CV. Used if ALLATOMS flag is missing");
+     155           8 :   keys.addFlag("ALLATOMS", false, "Use EVERY atom of the system. Overrides ATOMS keyword.");
+     156           8 :   keys.addFlag("NOVSITES", false, "If present the configuration is without virtual sites at the centroid positions.");
+     157             : 
+     158           4 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func-sort-c.html b/coverage/colvar/Dipole.cpp.func-sort-c.html new file mode 100644 index 0000000000..ec42d6f82d --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe716createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar6Dipole9calculateEv923
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func.html b/coverage/colvar/Dipole.cpp.func.html new file mode 100644 index 0000000000..364fbb97cd --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe716createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118DipoleRegisterMe71D2Ev4168
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar6Dipole9calculateEv923
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.gcov.html b/coverage/colvar/Dipole.cpp.gcov.html new file mode 100644 index 0000000000..c9b81d14bf --- /dev/null +++ b/coverage/colvar/Dipole.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + 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-05-27 13:05: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       12612 : PLUMED_REGISTER_ACTION(Dipole,"DIPOLE")
+      72             : 
+      73          56 : void Dipole::registerKeywords(Keywords& keys) {
+      74          56 :   Colvar::registerKeywords(keys);
+      75         112 :   keys.add("atoms","GROUP","the group of atoms we are calculating the dipole moment for");
+      76         112 :   keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the dipole separately and store them as label.x, label.y and label.z");
+      77         112 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the dipole");
+      78         112 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the dipole");
+      79         112 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the dipole");
+      80          56 : }
+      81             : 
+      82          54 : Dipole::Dipole(const ActionOptions&ao):
+      83             :   PLUMED_COLVAR_INIT(ao),
+      84          54 :   components(false)
+      85             : {
+      86          54 :   parseAtomList("GROUP",ga_lista);
+      87          54 :   parseFlag("COMPONENTS",components);
+      88          54 :   parseFlag("NOPBC",nopbc);
+      89          54 :   checkRead();
+      90          54 :   if(components) {
+      91           4 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+      92           4 :     addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+      93           6 :     addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      94             :   } else {
+      95          52 :     addValueWithDerivatives(); setNotPeriodic();
+      96             :   }
+      97             : 
+      98          54 :   log.printf("  of %u atoms\n",static_cast<unsigned>(ga_lista.size()));
+      99         379 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+     100         325 :     log.printf("  %d", ga_lista[i].serial());
+     101             :   }
+     102          54 :   log.printf("  \n");
+     103          54 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     104          16 :   else      log.printf("  using periodic boundary conditions\n");
+     105             : 
+     106          54 :   requestAtoms(ga_lista);
+     107          54 : }
+     108             : 
+     109             : // calculator
+     110         923 : void Dipole::calculate()
+     111             : {
+     112         923 :   if(!nopbc) makeWhole();
+     113             :   double ctot=0.;
+     114             :   unsigned N=getNumberOfAtoms();
+     115         923 :   std::vector<double> charges(N);
+     116         923 :   Vector dipje;
+     117             : 
+     118        7258 :   for(unsigned i=0; i<N; ++i) {
+     119        6335 :     charges[i]=getCharge(i);
+     120        6335 :     ctot+=charges[i];
+     121             :   }
+     122         923 :   ctot/=(double)N;
+     123             : 
+     124        7258 :   for(unsigned i=0; i<N; ++i) {
+     125        6335 :     charges[i]-=ctot;
+     126        6335 :     dipje += charges[i]*getPosition(i);
+     127             :   }
+     128             : 
+     129         923 :   if(!components) {
+     130         778 :     double dipole = dipje.modulo();
+     131         778 :     double idip = 1./dipole;
+     132             : 
+     133        6243 :     for(unsigned i=0; i<N; i++) {
+     134        5465 :       double dfunc=charges[i]*idip;
+     135        5465 :       setAtomsDerivatives(i,dfunc*dipje);
+     136             :     }
+     137         778 :     setBoxDerivativesNoPbc();
+     138         778 :     setValue(dipole);
+     139             :   } else {
+     140         145 :     Value* valuex=getPntrToComponent("x");
+     141         145 :     Value* valuey=getPntrToComponent("y");
+     142         145 :     Value* valuez=getPntrToComponent("z");
+     143        1015 :     for(unsigned i=0; i<N; i++) {
+     144         870 :       setAtomsDerivatives(valuex,i,charges[i]*Vector(1.0,0.0,0.0));
+     145         870 :       setAtomsDerivatives(valuey,i,charges[i]*Vector(0.0,1.0,0.0));
+     146         870 :       setAtomsDerivatives(valuez,i,charges[i]*Vector(0.0,0.0,1.0));
+     147             :     }
+     148         145 :     setBoxDerivativesNoPbc(valuex);
+     149         145 :     setBoxDerivativesNoPbc(valuey);
+     150         145 :     setBoxDerivativesNoPbc(valuez);
+     151         145 :     valuex->set(dipje[0]);
+     152         145 :     valuey->set(dipje[1]);
+     153         145 :     valuez->set(dipje[2]);
+     154             :   }
+     155         923 : }
+     156             : 
+     157             : }
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func-sort-c.html b/coverage/colvar/Distance.cpp.func-sort-c.html new file mode 100644 index 0000000000..b46263814b --- /dev/null +++ b/coverage/colvar/Distance.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe1186createERKNS_13ActionOptionsE466
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE466
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118D2Ev4168
_ZN4PLMD6colvar8Distance9calculateEv42384
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func.html b/coverage/colvar/Distance.cpp.func.html new file mode 100644 index 0000000000..004d5857d3 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe1186createERKNS_13ActionOptionsE466
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_121DistanceRegisterMe118D2Ev4168
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar8Distance9calculateEv42384
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE466
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.gcov.html b/coverage/colvar/Distance.cpp.gcov.html new file mode 100644 index 0000000000..6e4cb2225f --- /dev/null +++ b/coverage/colvar/Distance.cpp.gcov.html @@ -0,0 +1,305 @@ + + + + + + + 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-05-27 13:05: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       13434 : PLUMED_REGISTER_ACTION(Distance,"DISTANCE")
+     119             : 
+     120         468 : void Distance::registerKeywords( Keywords& keys ) {
+     121         468 :   Colvar::registerKeywords( keys );
+     122         936 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+     123         936 :   keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the distance separately and store them as label.x, label.y and label.z");
+     124         936 :   keys.addFlag("SCALED_COMPONENTS",false,"calculate the a, b and c scaled components of the distance separately and store them as label.a, label.b and label.c");
+     125         936 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the vector connecting the two atoms");
+     126         936 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the vector connecting the two atoms");
+     127         936 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the vector connecting the two atoms");
+     128         936 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the vector connecting the two atoms");
+     129         936 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the vector connecting the two atoms");
+     130         936 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the vector connecting the two atoms");
+     131         468 : }
+     132             : 
+     133         466 : Distance::Distance(const ActionOptions&ao):
+     134             :   PLUMED_COLVAR_INIT(ao),
+     135         466 :   components(false),
+     136         466 :   scaled_components(false),
+     137         466 :   pbc(true)
+     138             : {
+     139             :   std::vector<AtomNumber> atoms;
+     140         932 :   parseAtomList("ATOMS",atoms);
+     141         466 :   if(atoms.size()!=2)
+     142           1 :     error("Number of specified atoms should be 2");
+     143         465 :   parseFlag("COMPONENTS",components);
+     144         465 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     145         465 :   bool nopbc=!pbc;
+     146         465 :   parseFlag("NOPBC",nopbc);
+     147         465 :   pbc=!nopbc;
+     148         465 :   checkRead();
+     149             : 
+     150         465 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     151         465 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     152           4 :   else    log.printf("  without periodic boundary conditions\n");
+     153             : 
+     154         465 :   if(components && scaled_components) error("COMPONENTS and SCALED_COMPONENTS are not compatible");
+     155             : 
+     156         464 :   if(components) {
+     157          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         433 :   } else if(scaled_components) {
+     162           6 :     addComponentWithDerivatives("a"); componentIsPeriodic("a","-0.5","+0.5");
+     163           6 :     addComponentWithDerivatives("b"); componentIsPeriodic("b","-0.5","+0.5");
+     164           8 :     addComponentWithDerivatives("c"); componentIsPeriodic("c","-0.5","+0.5");
+     165             :   } else {
+     166         431 :     addValueWithDerivatives(); setNotPeriodic();
+     167             :   }
+     168             : 
+     169             : 
+     170         464 :   requestAtoms(atoms);
+     171         468 : }
+     172             : 
+     173             : 
+     174             : // calculator
+     175       42384 : void Distance::calculate() {
+     176             : 
+     177       42384 :   if(pbc) makeWhole();
+     178             : 
+     179       42384 :   Vector distance=delta(getPosition(0),getPosition(1));
+     180       42384 :   const double value=distance.modulo();
+     181       42384 :   const double invvalue=1.0/value;
+     182             : 
+     183       42384 :   if(components) {
+     184         394 :     Value* valuex=getPntrToComponent("x");
+     185         394 :     Value* valuey=getPntrToComponent("y");
+     186         394 :     Value* valuez=getPntrToComponent("z");
+     187             : 
+     188         394 :     setAtomsDerivatives (valuex,0,Vector(-1,0,0));
+     189         394 :     setAtomsDerivatives (valuex,1,Vector(+1,0,0));
+     190         394 :     setBoxDerivativesNoPbc(valuex);
+     191         394 :     valuex->set(distance[0]);
+     192             : 
+     193         394 :     setAtomsDerivatives (valuey,0,Vector(0,-1,0));
+     194         394 :     setAtomsDerivatives (valuey,1,Vector(0,+1,0));
+     195         394 :     setBoxDerivativesNoPbc(valuey);
+     196         394 :     valuey->set(distance[1]);
+     197             : 
+     198         394 :     setAtomsDerivatives (valuez,0,Vector(0,0,-1));
+     199         394 :     setAtomsDerivatives (valuez,1,Vector(0,0,+1));
+     200         394 :     setBoxDerivativesNoPbc(valuez);
+     201         394 :     valuez->set(distance[2]);
+     202       41990 :   } else if(scaled_components) {
+     203          11 :     Value* valuea=getPntrToComponent("a");
+     204          11 :     Value* valueb=getPntrToComponent("b");
+     205          22 :     Value* valuec=getPntrToComponent("c");
+     206          11 :     Vector d=getPbc().realToScaled(distance);
+     207          11 :     setAtomsDerivatives (valuea,0,matmul(getPbc().getInvBox(),Vector(-1,0,0)));
+     208          11 :     setAtomsDerivatives (valuea,1,matmul(getPbc().getInvBox(),Vector(+1,0,0)));
+     209          11 :     valuea->set(Tools::pbc(d[0]));
+     210          11 :     setAtomsDerivatives (valueb,0,matmul(getPbc().getInvBox(),Vector(0,-1,0)));
+     211          11 :     setAtomsDerivatives (valueb,1,matmul(getPbc().getInvBox(),Vector(0,+1,0)));
+     212          11 :     valueb->set(Tools::pbc(d[1]));
+     213          11 :     setAtomsDerivatives (valuec,0,matmul(getPbc().getInvBox(),Vector(0,0,-1)));
+     214          11 :     setAtomsDerivatives (valuec,1,matmul(getPbc().getInvBox(),Vector(0,0,+1)));
+     215          11 :     valuec->set(Tools::pbc(d[2]));
+     216             :   } else {
+     217       41979 :     setAtomsDerivatives(0,-invvalue*distance);
+     218       41979 :     setAtomsDerivatives(1,invvalue*distance);
+     219       41979 :     setBoxDerivativesNoPbc();
+     220       41979 :     setValue           (value);
+     221             :   }
+     222             : 
+     223       42384 : }
+     224             : 
+     225             : }
+     226             : }
+     227             : 
+     228             : 
+     229             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func-sort-c.html b/coverage/colvar/EEFSolv.cpp.func-sort-c.html new file mode 100644 index 0000000000..bc5e7457ac --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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:23024494.3 %
Date:2024-05-27 13:05: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_8KeywordsE7
_ZN4PLMD6colvar7EEFSolv13update_neighbEv30
_ZN4PLMD6colvar7EEFSolv9calculateEv30
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func.html b/coverage/colvar/EEFSolv.cpp.func.html new file mode 100644 index 0000000000..01494850cb --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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:23024494.3 %
Date:2024-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe1026createERKNS_13ActionOptionsE5
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120EEFSolvRegisterMe102D2Ev4168
_ZN4PLMD6colvar7EEFSolv12setupTypeMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13setupValueMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13update_neighbEv30
_ZN4PLMD6colvar7EEFSolv14setupConstantsERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IdSaIdEESaIS9_EEb5
_ZN4PLMD6colvar7EEFSolv16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6colvar7EEFSolv9calculateEv30
_ZN4PLMD6colvar7EEFSolvC1ERKNS_13ActionOptionsE5
_ZN4PLMD6colvar7EEFSolvC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.gcov.html b/coverage/colvar/EEFSolv.cpp.gcov.html new file mode 100644 index 0000000000..551f7b8589 --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.gcov.html @@ -0,0 +1,1252 @@ + + + + + + + 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:23024494.3 %
Date:2024-05-27 13:05: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       12514 : PLUMED_REGISTER_ACTION(EEFSolv,"EEFSOLV")
+     103             : 
+     104           7 : void EEFSolv::registerKeywords(Keywords& keys) {
+     105           7 :   Colvar::registerKeywords(keys);
+     106          14 :   keys.add("atoms", "ATOMS", "The atoms to be included in the calculation, e.g. the whole protein.");
+     107          14 :   keys.add("compulsory", "NL_BUFFER", "0.1", "The buffer to the intrinsic cutoff used when calculating pairwise interactions.");
+     108          14 :   keys.add("compulsory", "NL_STRIDE", "40", "The frequency with which the neighbor list is updated.");
+     109          14 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     110          14 :   keys.addFlag("TEMP_CORRECTION", false, "Correct free energy of solvation constants for temperatures different from 298.15 K");
+     111           7 : }
+     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          10 :   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          40 :   typemap["ACE"] = {
+     400             :     {"CH3", "CT3"},
+     401             :     {"HH31","HA3"},
+     402             :     {"HH32","HA3"},
+     403             :     {"HH33","HA3"},
+     404             :     {"C",   "C"  },
+     405             :     {"O",   "O"  }
+     406          30 :   };
+     407          60 :   typemap["ALA"] = {
+     408             :     {"N",   "NH1"},
+     409             :     {"HN",  "H"  },
+     410             :     {"CA",  "CT1"},
+     411             :     {"HA",  "HB1"},
+     412             :     {"CB",  "CT3"},
+     413             :     {"HB1", "HA3"},
+     414             :     {"HB2", "HA3"},
+     415             :     {"HB3", "HA3"},
+     416             :     {"C",   "C"  },
+     417             :     {"O",   "O"  }
+     418          50 :   };
+     419         130 :   typemap["ARG"] = {
+     420             :     {"N",    "NH1"},
+     421             :     {"HN",   "H"  },
+     422             :     {"CA",   "CT1"},
+     423             :     {"HA",   "HB1"},
+     424             :     {"CB",   "CT2"},
+     425             :     {"HB1",  "HA2"},
+     426             :     {"HB2",  "HA2"},
+     427             :     {"CG",   "CT2"},
+     428             :     {"HG1",  "HA2"},
+     429             :     {"HG2",  "HA2"},
+     430             :     {"CD",   "CT2"},
+     431             :     {"HD1",  "HA2"},
+     432             :     {"HD2",  "HA2"},
+     433             :     {"NE",   "NC2"},
+     434             :     {"HE",   "HC" },
+     435             :     {"CZ",   "C"  },
+     436             :     {"NH1",  "NC2"},
+     437             :     {"HH11", "HC" },
+     438             :     {"HH12", "HC" },
+     439             :     {"NH2",  "NC2"},
+     440             :     {"HH21", "HC" },
+     441             :     {"HH22", "HC" },
+     442             :     {"C",    "C"  },
+     443             :     {"O",    "O"  }
+     444         120 :   };
+     445          80 :   typemap["ASN"] = {
+     446             :     {"N",    "NH1"},
+     447             :     {"HN",   "H"  },
+     448             :     {"CA",   "CT1"},
+     449             :     {"HA",   "HB1"},
+     450             :     {"CB",   "CT2"},
+     451             :     {"HB1",  "HA2"},
+     452             :     {"HB2",  "HA2"},
+     453             :     {"CG",   "CC" },
+     454             :     {"OD1",  "O"  },
+     455             :     {"ND2",  "NH2"},
+     456             :     {"HD21", "H"  },
+     457             :     {"HD22", "H"  },
+     458             :     {"C",    "C"  },
+     459             :     {"O",    "O"  }
+     460          70 :   };
+     461          75 :   typemap["ASPP"] = {
+     462             :     {"N",   "NH1"},
+     463             :     {"HN",  "H"  },
+     464             :     {"CA",  "CT1"},
+     465             :     {"HA",  "HB1"},
+     466             :     {"CB",  "CT2"},
+     467             :     {"HB1", "HA2"},
+     468             :     {"HB2", "HA2"},
+     469             :     {"CG",  "CD" },
+     470             :     {"OD1", "OB" },
+     471             :     {"OD2", "OH1"},
+     472             :     {"HD2", "H"  },
+     473             :     {"C",   "C"  },
+     474             :     {"O",   "O"  }
+     475          65 :   };
+     476          70 :   typemap["ASP"] = {
+     477             :     {"N",   "NH1"},
+     478             :     {"HN",  "H"  },
+     479             :     {"CA",  "CT1"},
+     480             :     {"HA",  "HB1"},
+     481             :     {"CB",  "CT2"},
+     482             :     {"HB1", "HA2"},
+     483             :     {"HB2", "HA2"},
+     484             :     {"CG",  "CC" },
+     485             :     {"OD1", "OC" },
+     486             :     {"OD2", "OC" },
+     487             :     {"C",   "C"  },
+     488             :     {"O",   "O"  }
+     489          60 :   };
+     490          65 :   typemap["CYS"] = {
+     491             :     {"N",   "NH1"},
+     492             :     {"HN",  "H"  },
+     493             :     {"CA",  "CT1"},
+     494             :     {"HA",  "HB1"},
+     495             :     {"CB",  "CT2"},
+     496             :     {"HB1", "HA2"},
+     497             :     {"HB2", "HA2"},
+     498             :     {"SG",  "S"  },
+     499             :     {"HG1", "HS" },
+     500             :     {"C",   "C"  },
+     501             :     {"O",   "O"  }
+     502          55 :   };
+     503          95 :   typemap["GLN"] = {
+     504             :     {"N",    "NH1" },
+     505             :     {"HN",   "H"   },
+     506             :     {"CA",   "CT1" },
+     507             :     {"HA",   "HB1" },
+     508             :     {"CB",   "CT2" },
+     509             :     {"HB1",  "HA2" },
+     510             :     {"HB2",  "HA2" },
+     511             :     {"CG",   "CT2" },
+     512             :     {"HG1",  "HA2" },
+     513             :     {"HG2",  "HA2" },
+     514             :     {"CD",   "CC"  },
+     515             :     {"OE1",  "O"   },
+     516             :     {"NE2",  "NH2" },
+     517             :     {"HE21", "H"   },
+     518             :     {"HE22", "H"   },
+     519             :     {"C",    "C"   },
+     520             :     {"O",    "O"   }
+     521          85 :   };
+     522          90 :   typemap["GLUP"] = {
+     523             :     {"N",   "NH1"},
+     524             :     {"HN",  "H"  },
+     525             :     {"CA",  "CT1"},
+     526             :     {"HA",  "HB1"},
+     527             :     {"CB",  "CT2"},
+     528             :     {"HB1", "HA2"},
+     529             :     {"HB2", "HA2"},
+     530             :     {"CG",  "CT2"},
+     531             :     {"HG1", "HA2"},
+     532             :     {"HG2", "HA2"},
+     533             :     {"CD",  "CD" },
+     534             :     {"OE1", "OB" },
+     535             :     {"OE2", "OH1"},
+     536             :     {"HE2", "H"  },
+     537             :     {"C",   "C"  },
+     538             :     {"O",   "O"  }
+     539          80 :   };
+     540          85 :   typemap["GLU"] = {
+     541             :     {"N",   "NH1"},
+     542             :     {"HN",  "H"  },
+     543             :     {"CA",  "CT1"},
+     544             :     {"HA",  "HB1"},
+     545             :     {"CB",  "CT2"},
+     546             :     {"HB1", "HA2"},
+     547             :     {"HB2", "HA2"},
+     548             :     {"CG",  "CT2"},
+     549             :     {"HG1", "HA2"},
+     550             :     {"HG2", "HA2"},
+     551             :     {"CD",  "CC" },
+     552             :     {"OE1", "OC" },
+     553             :     {"OE2", "OC" },
+     554             :     {"C",   "C"  },
+     555             :     {"O",   "O"  }
+     556          75 :   };
+     557          45 :   typemap["GLY"] = {
+     558             :     {"N",   "NH1"},
+     559             :     {"HN",  "H"  },
+     560             :     {"CA",  "CT2"},
+     561             :     {"HA1", "HB2"},
+     562             :     {"HA2", "HB2"},
+     563             :     {"C",   "C"  },
+     564             :     {"O",   "O"  }
+     565          35 :   };
+     566          95 :   typemap["HSD"] = {
+     567             :     {"N",   "NH1"},
+     568             :     {"HN",  "H"  },
+     569             :     {"CA",  "CT1"},
+     570             :     {"HA",  "HB1"},
+     571             :     {"CB",  "CT2"},
+     572             :     {"HB1", "HA2"},
+     573             :     {"HB2", "HA2"},
+     574             :     {"ND1", "NR1"},
+     575             :     {"HD1", "H"  },
+     576             :     {"CG",  "CPH1"},
+     577             :     {"CE1", "CPH2"},
+     578             :     {"HE1", "HR1"},
+     579             :     {"NE2", "NR2"},
+     580             :     {"CD2", "CPH1"},
+     581             :     {"HD2", "HR3"},
+     582             :     {"C",   "C"  },
+     583             :     {"O",   "O"  }
+     584          85 :   };
+     585          95 :   typemap["HIS"] = {
+     586             :     {"N",   "NH1"},
+     587             :     {"HN",  "H"  },
+     588             :     {"CA",  "CT1"},
+     589             :     {"HA",  "HB1"},
+     590             :     {"CB",  "CT2"},
+     591             :     {"HB1", "HA2"},
+     592             :     {"HB2", "HA2"},
+     593             :     {"ND1", "NR2"},
+     594             :     {"CG",  "CPH1"},
+     595             :     {"CE1", "CPH2"},
+     596             :     {"HE1", "HR1"},
+     597             :     {"NE2", "NR1"},
+     598             :     {"HE2", "H"  },
+     599             :     {"CD2", "CPH1"},
+     600             :     {"HD2", "HR3"},
+     601             :     {"C",   "C"  },
+     602             :     {"O",   "O"  }
+     603          85 :   };
+     604          95 :   typemap["HSE"] = {
+     605             :     {"N",   "NH1"},
+     606             :     {"HN",  "H"  },
+     607             :     {"CA",  "CT1"},
+     608             :     {"HA",  "HB1"},
+     609             :     {"CB",  "CT2"},
+     610             :     {"HB1", "HA2"},
+     611             :     {"HB2", "HA2"},
+     612             :     {"ND1", "NR2"},
+     613             :     {"CG",  "CPH1"},
+     614             :     {"CE1", "CPH2"},
+     615             :     {"HE1", "HR1"},
+     616             :     {"NE2", "NR1"},
+     617             :     {"HE2", "H"  },
+     618             :     {"CD2", "CPH1"},
+     619             :     {"HD2", "HR3"},
+     620             :     {"C",   "C"  },
+     621             :     {"O",   "O"  }
+     622          85 :   };
+     623         100 :   typemap["HSP"] = {
+     624             :     {"N",   "NH1"},
+     625             :     {"HN",  "H"  },
+     626             :     {"CA",  "CT1"},
+     627             :     {"HA",  "HB1"},
+     628             :     {"CB",  "CT2"},
+     629             :     {"HB1", "HA2"},
+     630             :     {"HB2", "HA2"},
+     631             :     {"CD2", "CPH1"},
+     632             :     {"HD2", "HR1"},
+     633             :     {"CG",  "CPH1"},
+     634             :     {"NE2", "NR3"},
+     635             :     {"HE2", "H"  },
+     636             :     {"ND1", "NR3"},
+     637             :     {"HD1", "H"  },
+     638             :     {"CE1", "CPH2"},
+     639             :     {"HE1", "HR2"},
+     640             :     {"C",   "C"  },
+     641             :     {"O",   "O"  }
+     642          90 :   };
+     643         105 :   typemap["ILE"] = {
+     644             :     {"N",    "NH1"},
+     645             :     {"HN",   "H"  },
+     646             :     {"CA",   "CT1"},
+     647             :     {"HA",   "HB1"},
+     648             :     {"CB",   "CT1"},
+     649             :     {"HB",   "HA1"},
+     650             :     {"CG2",  "CT3"},
+     651             :     {"HG21", "HA3"},
+     652             :     {"HG22", "HA3"},
+     653             :     {"HG23", "HA3"},
+     654             :     {"CG1",  "CT2"},
+     655             :     {"HG11", "HA2"},
+     656             :     {"HG12", "HA2"},
+     657             :     {"CD",   "CT3"},
+     658             :     {"HD1",  "HA3"},
+     659             :     {"HD2",  "HA3"},
+     660             :     {"HD3",  "HA3"},
+     661             :     {"C",    "C"  },
+     662             :     {"O",    "O"  }
+     663          95 :   };
+     664         105 :   typemap["LEU"] = {
+     665             :     {"N",    "NH1"},
+     666             :     {"HN",   "H"  },
+     667             :     {"CA",   "CT1"},
+     668             :     {"HA",   "HB1"},
+     669             :     {"CB",   "CT2"},
+     670             :     {"HB1",  "HA2"},
+     671             :     {"HB2",  "HA2"},
+     672             :     {"CG",   "CT1"},
+     673             :     {"HG",   "HA1"},
+     674             :     {"CD1",  "CT3"},
+     675             :     {"HD11", "HA3"},
+     676             :     {"HD12", "HA3"},
+     677             :     {"HD13", "HA3"},
+     678             :     {"CD2",  "CT3"},
+     679             :     {"HD21", "HA3"},
+     680             :     {"HD22", "HA3"},
+     681             :     {"HD23", "HA3"},
+     682             :     {"C",    "C"  },
+     683             :     {"O",    "O"  }
+     684          95 :   };
+     685         120 :   typemap["LYS"] = {
+     686             :     {"N",   "NH1"},
+     687             :     {"HN",  "H"  },
+     688             :     {"CA",  "CT1"},
+     689             :     {"HA",  "HB1"},
+     690             :     {"CB",  "CT2"},
+     691             :     {"HB1", "HA2"},
+     692             :     {"HB2", "HA2"},
+     693             :     {"CG",  "CT2"},
+     694             :     {"HG1", "HA2"},
+     695             :     {"HG2", "HA2"},
+     696             :     {"CD",  "CT2"},
+     697             :     {"HD1", "HA2"},
+     698             :     {"HD2", "HA2"},
+     699             :     {"CE",  "CT2"},
+     700             :     {"HE1", "HA2"},
+     701             :     {"HE2", "HA2"},
+     702             :     {"NZ",  "NH3"},
+     703             :     {"HZ1", "HC" },
+     704             :     {"HZ2", "HC" },
+     705             :     {"HZ3", "HC" },
+     706             :     {"C",   "C"  },
+     707             :     {"O",   "O"  }
+     708         110 :   };
+     709          95 :   typemap["MET"] = {
+     710             :     {"N",   "NH1"},
+     711             :     {"HN",  "H"  },
+     712             :     {"CA",  "CT1"},
+     713             :     {"HA",  "HB1"},
+     714             :     {"CB",  "CT2"},
+     715             :     {"HB1", "HA2"},
+     716             :     {"HB2", "HA2"},
+     717             :     {"CG",  "CT2"},
+     718             :     {"HG1", "HA2"},
+     719             :     {"HG2", "HA2"},
+     720             :     {"SD",  "S"  },
+     721             :     {"CE",  "CT3"},
+     722             :     {"HE1", "HA3"},
+     723             :     {"HE2", "HA3"},
+     724             :     {"HE3", "HA3"},
+     725             :     {"C",   "C"  },
+     726             :     {"O",   "O"  }
+     727          85 :   };
+     728          40 :   typemap["NMA"] = {
+     729             :     {"N",   "NH1"},
+     730             :     {"HN",  "H"  },
+     731             :     {"CH3", "CT3"},
+     732             :     {"HH31","HA3"},
+     733             :     {"HH32","HA3"},
+     734             :     {"HH33","HA3"},
+     735          30 :   };
+     736         110 :   typemap["PHE"] = {
+     737             :     {"N",   "NH1"},
+     738             :     {"HN",  "H"  },
+     739             :     {"CA",  "CT1"},
+     740             :     {"HA",  "HB1"},
+     741             :     {"CB",  "CT2"},
+     742             :     {"HB1", "HA2"},
+     743             :     {"HB2", "HA2"},
+     744             :     {"CG",  "CA" },
+     745             :     {"CD1", "CA" },
+     746             :     {"HD1", "HP" },
+     747             :     {"CE1", "CA" },
+     748             :     {"HE1", "HP" },
+     749             :     {"CZ",  "CA" },
+     750             :     {"HZ",  "HP" },
+     751             :     {"CD2", "CA" },
+     752             :     {"HD2", "HP" },
+     753             :     {"CE2", "CA" },
+     754             :     {"HE2", "HP" },
+     755             :     {"C",   "C"  },
+     756             :     {"O",   "O"  }
+     757         100 :   };
+     758          80 :   typemap["PRO"] = {
+     759             :     {"N",   "N"  },
+     760             :     {"CD",  "CP3"},
+     761             :     {"HD1", "HA2"},
+     762             :     {"HD2", "HA2"},
+     763             :     {"CA",  "CP1"},
+     764             :     {"HA",  "HB1"},
+     765             :     {"CB",  "CP2"},
+     766             :     {"HB1", "HA2"},
+     767             :     {"HB2", "HA2"},
+     768             :     {"CG",  "CP2"},
+     769             :     {"HG1", "HA2"},
+     770             :     {"HG2", "HA2"},
+     771             :     {"C",   "C"  },
+     772             :     {"O",   "O"  }
+     773          70 :   };
+     774          65 :   typemap["SER"] = {
+     775             :     {"N",   "NH1"},
+     776             :     {"HN",  "H"  },
+     777             :     {"CA",  "CT1"},
+     778             :     {"HA",  "HB1"},
+     779             :     {"CB",  "CT2"},
+     780             :     {"HB1", "HA2"},
+     781             :     {"HB2", "HA2"},
+     782             :     {"OG",  "OH1"},
+     783             :     {"HG1", "H"  },
+     784             :     {"C",   "C"  },
+     785             :     {"O",   "O"  }
+     786          55 :   };
+     787          80 :   typemap["THR"] = {
+     788             :     {"N",    "NH1"},
+     789             :     {"HN",   "H"  },
+     790             :     {"CA",   "CT1"},
+     791             :     {"HA",   "HB1"},
+     792             :     {"CB",   "CT1"},
+     793             :     {"HB",   "HA1"},
+     794             :     {"OG1",  "OH1"},
+     795             :     {"HG1",  "H"  },
+     796             :     {"CG2",  "CT3"},
+     797             :     {"HG21", "HA3"},
+     798             :     {"HG22", "HA3"},
+     799             :     {"HG23", "HA3"},
+     800             :     {"C",    "C"  },
+     801             :     {"O",    "O"  }
+     802          70 :   };
+     803         130 :   typemap["TRP"] = {
+     804             :     {"N",   "NH1"},
+     805             :     {"HN",  "H"  },
+     806             :     {"CA",  "CT1"},
+     807             :     {"HA",  "HB1"},
+     808             :     {"CB",  "CT2"},
+     809             :     {"HB1", "HA2"},
+     810             :     {"HB2", "HA2"},
+     811             :     {"CG",  "CY" },
+     812             :     {"CD1", "CA" },
+     813             :     {"HD1", "HP" },
+     814             :     {"NE1", "NY" },
+     815             :     {"HE1", "H"  },
+     816             :     {"CE2", "CPT"},
+     817             :     {"CD2", "CPT"},
+     818             :     {"CE3", "CAI"},
+     819             :     {"HE3", "HP" },
+     820             :     {"CZ3", "CA" },
+     821             :     {"HZ3", "HP" },
+     822             :     {"CZ2", "CAI"},
+     823             :     {"HZ2", "HP" },
+     824             :     {"CH2", "CA" },
+     825             :     {"HH2", "HP" },
+     826             :     {"C",   "C"  },
+     827             :     {"O",   "O"  }
+     828         120 :   };
+     829         115 :   typemap["TYR"] = {
+     830             :     {"N",   "NH1"},
+     831             :     {"HN",  "H"  },
+     832             :     {"CA",  "CT1"},
+     833             :     {"HA",  "HB1"},
+     834             :     {"CB",  "CT2"},
+     835             :     {"HB1", "HA2"},
+     836             :     {"HB2", "HA2"},
+     837             :     {"CG",  "CA" },
+     838             :     {"CD1", "CA" },
+     839             :     {"HD1", "HP" },
+     840             :     {"CE1", "CA" },
+     841             :     {"HE1", "HP" },
+     842             :     {"CZ",  "CA" },
+     843             :     {"OH",  "OH1"},
+     844             :     {"HH",  "H"  },
+     845             :     {"CD2", "CA" },
+     846             :     {"HD2", "HP" },
+     847             :     {"CE2", "CA" },
+     848             :     {"HE2", "HP" },
+     849             :     {"C",   "C"  },
+     850             :     {"O",   "O"  }
+     851         105 :   };
+     852          90 :   typemap["VAL"] = {
+     853             :     {"N",    "NH1"},
+     854             :     {"HN",   "H"  },
+     855             :     {"CA",   "CT1"},
+     856             :     {"HA",   "HB1"},
+     857             :     {"CB",   "CT1"},
+     858             :     {"HB",   "HA1"},
+     859             :     {"CG1",  "CT3"},
+     860             :     {"HG11", "HA3"},
+     861             :     {"HG12", "HA3"},
+     862             :     {"HG13", "HA3"},
+     863             :     {"CG2",  "CT3"},
+     864             :     {"HG21", "HA3"},
+     865             :     {"HG22", "HA3"},
+     866             :     {"HG23", "HA3"},
+     867             :     {"C",    "C"  },
+     868             :     {"O",    "O"  }
+     869          80 :   };
+     870           5 :   return typemap;
+     871             : }
+     872             : 
+     873           5 : std::map<std::string, std::vector<double> > EEFSolv::setupValueMap() {
+     874             :   // Volume ∆Gref ∆Gfree ∆H ∆Cp λ vdw_radius
+     875             :   std::map<std::string, std::vector<double> > valuemap;
+     876           5 :   valuemap["C"] = {
+     877             :     ANG3_TO_NM3 * 14.720,
+     878             :     KCAL_TO_KJ * 0.000,
+     879             :     KCAL_TO_KJ * 0.000,
+     880             :     KCAL_TO_KJ * 0.000,
+     881             :     KCAL_TO_KJ * 0.0,
+     882             :     1. / (ANG_TO_NM * 3.5),
+     883             :     0.20,
+     884           5 :   };
+     885           5 :   valuemap["CD"] = {
+     886             :     ANG3_TO_NM3 * 14.720,
+     887             :     KCAL_TO_KJ * 0.000,
+     888             :     KCAL_TO_KJ * 0.000,
+     889             :     KCAL_TO_KJ * 0.000,
+     890             :     KCAL_TO_KJ * 0.0,
+     891             :     1. / (ANG_TO_NM * 3.5),
+     892             :     0.20,
+     893           5 :   };
+     894           5 :   valuemap["CT1"] = {
+     895             :     ANG3_TO_NM3 * 11.507,
+     896             :     KCAL_TO_KJ * -0.187,
+     897             :     KCAL_TO_KJ * -0.187,
+     898             :     KCAL_TO_KJ * 0.876,
+     899             :     KCAL_TO_KJ * 0.0,
+     900             :     1. / (ANG_TO_NM * 3.5),
+     901             :     0.20,
+     902           5 :   };
+     903           5 :   valuemap["CT2"] = {
+     904             :     ANG3_TO_NM3 * 18.850,
+     905             :     KCAL_TO_KJ * 0.372,
+     906             :     KCAL_TO_KJ * 0.372,
+     907             :     KCAL_TO_KJ * -0.610,
+     908             :     KCAL_TO_KJ * 18.6,
+     909             :     1. / (ANG_TO_NM * 3.5),
+     910             :     0.20,
+     911           5 :   };
+     912           5 :   valuemap["CT2A"] = {
+     913             :     ANG3_TO_NM3 * 18.666,
+     914             :     KCAL_TO_KJ * 0.372,
+     915             :     KCAL_TO_KJ * 0.372,
+     916             :     KCAL_TO_KJ * -0.610,
+     917             :     KCAL_TO_KJ * 18.6,
+     918             :     1. / (ANG_TO_NM * 3.5),
+     919             :     0.20,
+     920           5 :   };
+     921           5 :   valuemap["CT3"] = {
+     922             :     ANG3_TO_NM3 * 27.941,
+     923             :     KCAL_TO_KJ * 1.089,
+     924             :     KCAL_TO_KJ * 1.089,
+     925             :     KCAL_TO_KJ * -1.779,
+     926             :     KCAL_TO_KJ * 35.6,
+     927             :     1. / (ANG_TO_NM * 3.5),
+     928             :     0.204,
+     929           5 :   };
+     930           5 :   valuemap["CPH1"] = {
+     931             :     ANG3_TO_NM3 * 5.275,
+     932             :     KCAL_TO_KJ * 0.057,
+     933             :     KCAL_TO_KJ * 0.080,
+     934             :     KCAL_TO_KJ * -0.973,
+     935             :     KCAL_TO_KJ * 6.9,
+     936             :     1. / (ANG_TO_NM * 3.5),
+     937             :     0.18,
+     938           5 :   };
+     939           5 :   valuemap["CPH2"] = {
+     940             :     ANG3_TO_NM3 * 11.796,
+     941             :     KCAL_TO_KJ * 0.057,
+     942             :     KCAL_TO_KJ * 0.080,
+     943             :     KCAL_TO_KJ * -0.973,
+     944             :     KCAL_TO_KJ * 6.9,
+     945             :     1. / (ANG_TO_NM * 3.5),
+     946             :     0.18,
+     947           5 :   };
+     948           5 :   valuemap["CPT"] = {
+     949             :     ANG3_TO_NM3 * 4.669,
+     950             :     KCAL_TO_KJ * -0.890,
+     951             :     KCAL_TO_KJ * -0.890,
+     952             :     KCAL_TO_KJ * 2.220,
+     953             :     KCAL_TO_KJ * 6.9,
+     954             :     1. / (ANG_TO_NM * 3.5),
+     955             :     0.186,
+     956           5 :   };
+     957           5 :   valuemap["CY"] = {
+     958             :     ANG3_TO_NM3 * 10.507,
+     959             :     KCAL_TO_KJ * -0.890,
+     960             :     KCAL_TO_KJ * -0.890,
+     961             :     KCAL_TO_KJ * 2.220,
+     962             :     KCAL_TO_KJ * 6.9,
+     963             :     1. / (ANG_TO_NM * 3.5),
+     964             :     0.199,
+     965           5 :   };
+     966           5 :   valuemap["CP1"] = {
+     967             :     ANG3_TO_NM3 * 25.458,
+     968             :     KCAL_TO_KJ * -0.187,
+     969             :     KCAL_TO_KJ * -0.187,
+     970             :     KCAL_TO_KJ * 0.876,
+     971             :     KCAL_TO_KJ * 0.0,
+     972             :     1. / (ANG_TO_NM * 3.5),
+     973             :     0.227,
+     974           5 :   };
+     975           5 :   valuemap["CP2"] = {
+     976             :     ANG3_TO_NM3 * 19.880,
+     977             :     KCAL_TO_KJ * 0.372,
+     978             :     KCAL_TO_KJ * 0.372,
+     979             :     KCAL_TO_KJ * -0.610,
+     980             :     KCAL_TO_KJ * 18.6,
+     981             :     1. / (ANG_TO_NM * 3.5),
+     982             :     0.217,
+     983           5 :   };
+     984           5 :   valuemap["CP3"] = {
+     985             :     ANG3_TO_NM3 * 26.731,
+     986             :     KCAL_TO_KJ * 0.372,
+     987             :     KCAL_TO_KJ * 0.372,
+     988             :     KCAL_TO_KJ * -0.610,
+     989             :     KCAL_TO_KJ * 18.6,
+     990             :     1. / (ANG_TO_NM * 3.5),
+     991             :     0.217,
+     992           5 :   };
+     993           5 :   valuemap["CC"] = {
+     994             :     ANG3_TO_NM3 * 16.539,
+     995             :     KCAL_TO_KJ * 0.000,
+     996             :     KCAL_TO_KJ * 0.000,
+     997             :     KCAL_TO_KJ * 0.000,
+     998             :     KCAL_TO_KJ * 0.0,
+     999             :     1. / (ANG_TO_NM * 3.5),
+    1000             :     0.20,
+    1001           5 :   };
+    1002           5 :   valuemap["CAI"] = {
+    1003             :     ANG3_TO_NM3 * 18.249,
+    1004             :     KCAL_TO_KJ * 0.057,
+    1005             :     KCAL_TO_KJ * 0.057,
+    1006             :     KCAL_TO_KJ * -0.973,
+    1007             :     KCAL_TO_KJ * 6.9,
+    1008             :     1. / (ANG_TO_NM * 3.5),
+    1009             :     0.199,
+    1010           5 :   };
+    1011           5 :   valuemap["CA"] = {
+    1012             :     ANG3_TO_NM3 * 18.249,
+    1013             :     KCAL_TO_KJ * 0.057,
+    1014             :     KCAL_TO_KJ * 0.057,
+    1015             :     KCAL_TO_KJ * -0.973,
+    1016             :     KCAL_TO_KJ * 6.9,
+    1017             :     1. / (ANG_TO_NM * 3.5),
+    1018             :     0.199,
+    1019           5 :   };
+    1020           5 :   valuemap["N"] = {
+    1021             :     ANG3_TO_NM3 * 0.000,
+    1022             :     KCAL_TO_KJ * -1.000,
+    1023             :     KCAL_TO_KJ * -1.000,
+    1024             :     KCAL_TO_KJ * -1.250,
+    1025             :     KCAL_TO_KJ * 8.8,
+    1026             :     1. / (ANG_TO_NM * 3.5),
+    1027             :     0.185,
+    1028           5 :   };
+    1029           5 :   valuemap["NR1"] = {
+    1030             :     ANG3_TO_NM3 * 15.273,
+    1031             :     KCAL_TO_KJ * -5.950,
+    1032             :     KCAL_TO_KJ * -5.950,
+    1033             :     KCAL_TO_KJ * -9.059,
+    1034             :     KCAL_TO_KJ * -8.8,
+    1035             :     1. / (ANG_TO_NM * 3.5),
+    1036             :     0.185,
+    1037           5 :   };
+    1038           5 :   valuemap["NR2"] = {
+    1039             :     ANG3_TO_NM3 * 15.111,
+    1040             :     KCAL_TO_KJ * -3.820,
+    1041             :     KCAL_TO_KJ * -3.820,
+    1042             :     KCAL_TO_KJ * -4.654,
+    1043             :     KCAL_TO_KJ * -8.8,
+    1044             :     1. / (ANG_TO_NM * 3.5),
+    1045             :     0.185,
+    1046           5 :   };
+    1047           5 :   valuemap["NR3"] = {
+    1048             :     ANG3_TO_NM3 * 15.071,
+    1049             :     KCAL_TO_KJ * -5.950,
+    1050             :     KCAL_TO_KJ * -5.950,
+    1051             :     KCAL_TO_KJ * -9.059,
+    1052             :     KCAL_TO_KJ * -8.8,
+    1053             :     1. / (ANG_TO_NM * 3.5),
+    1054             :     0.185,
+    1055           5 :   };
+    1056           5 :   valuemap["NH1"] = {
+    1057             :     ANG3_TO_NM3 * 10.197,
+    1058             :     KCAL_TO_KJ * -5.950,
+    1059             :     KCAL_TO_KJ * -5.950,
+    1060             :     KCAL_TO_KJ * -9.059,
+    1061             :     KCAL_TO_KJ * -8.8,
+    1062             :     1. / (ANG_TO_NM * 3.5),
+    1063             :     0.185,
+    1064           5 :   };
+    1065           5 :   valuemap["NH2"] = {
+    1066             :     ANG3_TO_NM3 * 18.182,
+    1067             :     KCAL_TO_KJ * -5.950,
+    1068             :     KCAL_TO_KJ * -5.950,
+    1069             :     KCAL_TO_KJ * -9.059,
+    1070             :     KCAL_TO_KJ * -8.8,
+    1071             :     1. / (ANG_TO_NM * 3.5),
+    1072             :     0.185,
+    1073           5 :   };
+    1074           5 :   valuemap["NH3"] = {
+    1075             :     ANG3_TO_NM3 * 18.817,
+    1076             :     KCAL_TO_KJ * -20.000,
+    1077             :     KCAL_TO_KJ * -20.000,
+    1078             :     KCAL_TO_KJ * -25.000,
+    1079             :     KCAL_TO_KJ * -18.0,
+    1080             :     1. / (ANG_TO_NM * 6.0),
+    1081             :     0.185,
+    1082           5 :   };
+    1083           5 :   valuemap["NC2"] = {
+    1084             :     ANG3_TO_NM3 * 18.215,
+    1085             :     KCAL_TO_KJ * -10.000,
+    1086             :     KCAL_TO_KJ * -10.000,
+    1087             :     KCAL_TO_KJ * -12.000,
+    1088             :     KCAL_TO_KJ * -7.0,
+    1089             :     1. / (ANG_TO_NM * 6.0),
+    1090             :     0.185,
+    1091           5 :   };
+    1092           5 :   valuemap["NY"] = {
+    1093             :     ANG3_TO_NM3 * 12.001,
+    1094             :     KCAL_TO_KJ * -5.950,
+    1095             :     KCAL_TO_KJ * -5.950,
+    1096             :     KCAL_TO_KJ * -9.059,
+    1097             :     KCAL_TO_KJ * -8.8,
+    1098             :     1. / (ANG_TO_NM * 3.5),
+    1099             :     0.185,
+    1100           5 :   };
+    1101           5 :   valuemap["NP"] = {
+    1102             :     ANG3_TO_NM3 * 4.993,
+    1103             :     KCAL_TO_KJ * -20.000,
+    1104             :     KCAL_TO_KJ * -20.000,
+    1105             :     KCAL_TO_KJ * -25.000,
+    1106             :     KCAL_TO_KJ * -18.0,
+    1107             :     1. / (ANG_TO_NM * 6.0),
+    1108             :     0.185,
+    1109           5 :   };
+    1110           5 :   valuemap["O"] = {
+    1111             :     ANG3_TO_NM3 * 11.772,
+    1112             :     KCAL_TO_KJ * -5.330,
+    1113             :     KCAL_TO_KJ * -5.330,
+    1114             :     KCAL_TO_KJ * -5.787,
+    1115             :     KCAL_TO_KJ * -8.8,
+    1116             :     1. / (ANG_TO_NM * 3.5),
+    1117             :     0.170,
+    1118           5 :   };
+    1119           5 :   valuemap["OB"] = {
+    1120             :     ANG3_TO_NM3 * 11.694,
+    1121             :     KCAL_TO_KJ * -5.330,
+    1122             :     KCAL_TO_KJ * -5.330,
+    1123             :     KCAL_TO_KJ * -5.787,
+    1124             :     KCAL_TO_KJ * -8.8,
+    1125             :     1. / (ANG_TO_NM * 3.5),
+    1126             :     0.170,
+    1127           5 :   };
+    1128           5 :   valuemap["OC"] = {
+    1129             :     ANG3_TO_NM3 * 12.003,
+    1130             :     KCAL_TO_KJ * -10.000,
+    1131             :     KCAL_TO_KJ * -10.000,
+    1132             :     KCAL_TO_KJ * -12.000,
+    1133             :     KCAL_TO_KJ * -9.4,
+    1134             :     1. / (ANG_TO_NM * 6.0),
+    1135             :     0.170,
+    1136           5 :   };
+    1137           5 :   valuemap["OH1"] = {
+    1138             :     ANG3_TO_NM3 * 15.528,
+    1139             :     KCAL_TO_KJ * -5.920,
+    1140             :     KCAL_TO_KJ * -5.920,
+    1141             :     KCAL_TO_KJ * -9.264,
+    1142             :     KCAL_TO_KJ * -11.2,
+    1143             :     1. / (ANG_TO_NM * 3.5),
+    1144             :     0.177,
+    1145           5 :   };
+    1146           5 :   valuemap["OS"] = {
+    1147             :     ANG3_TO_NM3 * 6.774,
+    1148             :     KCAL_TO_KJ * -2.900,
+    1149             :     KCAL_TO_KJ * -2.900,
+    1150             :     KCAL_TO_KJ * -3.150,
+    1151             :     KCAL_TO_KJ * -4.8,
+    1152             :     1. / (ANG_TO_NM * 3.5),
+    1153             :     0.177,
+    1154           5 :   };
+    1155           5 :   valuemap["S"] = {
+    1156             :     ANG3_TO_NM3 * 20.703,
+    1157             :     KCAL_TO_KJ * -3.240,
+    1158             :     KCAL_TO_KJ * -3.240,
+    1159             :     KCAL_TO_KJ * -4.475,
+    1160             :     KCAL_TO_KJ * -39.9,
+    1161             :     1. / (ANG_TO_NM * 3.5),
+    1162             :     0.20,
+    1163           5 :   };
+    1164           5 :   valuemap["SM"] = {
+    1165             :     ANG3_TO_NM3 * 21.306,
+    1166             :     KCAL_TO_KJ * -3.240,
+    1167             :     KCAL_TO_KJ * -3.240,
+    1168             :     KCAL_TO_KJ * -4.475,
+    1169             :     KCAL_TO_KJ * -39.9,
+    1170             :     1. / (ANG_TO_NM * 3.5),
+    1171             :     0.197,
+    1172           5 :   };
+    1173           5 :   return valuemap;
+    1174             : }
+    1175             : }
+    1176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.func-sort-c.html b/coverage/colvar/ERMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..542027afc4 --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe1166createERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6colvar5ERMSD9calculateEv222
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.func.html b/coverage/colvar/ERMSD.cpp.func.html new file mode 100644 index 0000000000..b539692fe6 --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe1166createERKNS_13ActionOptionsE4
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118ERMSDRegisterMe116D2Ev4168
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6colvar5ERMSD9calculateEv222
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.gcov.html b/coverage/colvar/ERMSD.cpp.gcov.html new file mode 100644 index 0000000000..91ddbd2bf1 --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + LCOV - plumed test coverage - colvar/ERMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(ERMSD,"ERMSD")
+     117             : 
+     118           6 : void ERMSD::registerKeywords(Keywords& keys) {
+     119           6 :   Colvar::registerKeywords(keys);
+     120             : 
+     121          12 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     122          12 :   keys.add("compulsory","CUTOFF","2.4","only pairs of atoms closer than CUTOFF are considered in the calculation.");
+     123          12 :   keys.add("atoms","ATOMS","the list of atoms (use lcs)");
+     124          12 :   keys.add("optional","PAIRS","List of pairs considered. All pairs are considered if this value is not specified.");
+     125             : 
+     126           6 : }
+     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           8 :      <<plumed.cite("Bottaro, Di Palma, and Bussi, Nucleic Acids Res. 42, 13306 (2014)")
+     188          12 :      <<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         222 :   Tools::set_to_zero(derivs);
+     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.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.func-sort-c.html b/coverage/colvar/Energy.cpp.func-sort-c.html new file mode 100644 index 0000000000..ae74424fc9 --- /dev/null +++ b/coverage/colvar/Energy.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE42
_ZN4PLMD6colvar6Energy7prepareEv3989
_ZN4PLMD6colvar6Energy9calculateEv3989
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.func.html b/coverage/colvar/Energy.cpp.func.html new file mode 100644 index 0000000000..0a874a9a40 --- /dev/null +++ b/coverage/colvar/Energy.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe756createERKNS_13ActionOptionsE40
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118EnergyRegisterMe75D2Ev4168
_ZN4PLMD6colvar6Energy16registerKeywordsERNS_8KeywordsE42
_ZN4PLMD6colvar6Energy22getNumberOfDerivativesEv2
_ZN4PLMD6colvar6Energy7prepareEv3989
_ZN4PLMD6colvar6Energy9calculateEv3989
_ZN4PLMD6colvar6EnergyC1ERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6EnergyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.gcov.html b/coverage/colvar/Energy.cpp.gcov.html new file mode 100644 index 0000000000..4d62da082a --- /dev/null +++ b/coverage/colvar/Energy.cpp.gcov.html @@ -0,0 +1,192 @@ + + + + + + + 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-05-27 13:05: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       12584 : 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          42 : void Energy::registerKeywords( Keywords& keys ) {
+      92          42 :   Action::registerKeywords( keys );
+      93          42 :   ActionAtomistic::registerKeywords( keys );
+      94          42 :   ActionWithValue::registerKeywords( keys );
+      95          42 :   keys.remove("NUMERICAL_DERIVATIVES");
+      96          42 : }
+      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.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.func-sort-c.html b/coverage/colvar/ExtraCV.cpp.func-sort-c.html new file mode 100644 index 0000000000..f20147e258 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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:2626100.0 %
Date:2024-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe646createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCV22getNumberOfDerivativesEv4
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar7ExtraCV7prepareEv72
_ZN4PLMD6colvar7ExtraCV9calculateEv72
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.func.html b/coverage/colvar/ExtraCV.cpp.func.html new file mode 100644 index 0000000000..b67c36d0bc --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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:2626100.0 %
Date:2024-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe646createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_119ExtraCVRegisterMe64D2Ev4168
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar7ExtraCV22getNumberOfDerivativesEv4
_ZN4PLMD6colvar7ExtraCV7prepareEv72
_ZN4PLMD6colvar7ExtraCV9calculateEv72
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.gcov.html b/coverage/colvar/ExtraCV.cpp.gcov.html new file mode 100644 index 0000000000..14fee2c121 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.gcov.html @@ -0,0 +1,180 @@ + + + + + + + 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:2626100.0 %
Date:2024-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(ExtraCV,"EXTRACV")
+      65             : 
+      66           3 : ExtraCV::ExtraCV(const ActionOptions&ao):
+      67           3 :   PLUMED_COLVAR_INIT(ao)
+      68             : {
+      69           3 :   addValueWithDerivatives(); setNotPeriodic();
+      70           3 :   getPntrToValue()->resizeDerivatives(1);
+      71           3 :   parse("NAME",name);
+      72           3 :   log<<"  name: "<<name<<"\n";
+      73           3 :   isExtraCV=true;
+      74             :   setExtraCV(name);
+      75           3 : }
+      76             : 
+      77           5 : void ExtraCV::registerKeywords( Keywords& keys ) {
+      78           5 :   Action::registerKeywords( keys );
+      79           5 :   ActionAtomistic::registerKeywords( keys );
+      80           5 :   ActionWithValue::registerKeywords( keys );
+      81           5 :   keys.remove("NUMERICAL_DERIVATIVES");
+      82          10 :   keys.add("compulsory","NAME","name of the CV as computed by the MD engine");
+      83           5 : }
+      84             : 
+      85           4 : unsigned ExtraCV::getNumberOfDerivatives() {
+      86           4 :   return 1;
+      87             : }
+      88             : 
+      89          72 : void ExtraCV::prepare() {
+      90          72 :   atoms.setExtraCVNeeded(name,true);
+      91          72 : }
+      92             : 
+      93             : // calculator
+      94          72 : void ExtraCV::calculate() {
+      95          72 :   double value=plumed.getAtoms().getExtraCV(name);
+      96          72 :   setValue( value );
+      97          72 :   getPntrToComponent(0)->addDerivative(0,1.0);
+      98          72 : }
+      99             : 
+     100             : }
+     101             : }
+     102             : 
+     103             : 
+     104             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.func-sort-c.html b/coverage/colvar/Fake.cpp.func-sort-c.html new file mode 100644 index 0000000000..c5dc4bedcd --- /dev/null +++ b/coverage/colvar/Fake.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE19
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.func.html b/coverage/colvar/Fake.cpp.func.html new file mode 100644 index 0000000000..ba69438815 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe506createERKNS_13ActionOptionsE17
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_122ColvarFakeRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.gcov.html b/coverage/colvar/Fake.cpp.gcov.html new file mode 100644 index 0000000000..85932b0112 --- /dev/null +++ b/coverage/colvar/Fake.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-05-27 13:05: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       12538 : PLUMED_REGISTER_ACTION(ColvarFake,"FAKE")
+      51             : 
+      52          19 : void ColvarFake::registerKeywords( Keywords& keys ) {
+      53          19 :   Colvar::registerKeywords( keys );
+      54          38 :   keys.add("atoms","ATOMS","the fake atom index, a number is enough");
+      55          38 :   keys.reserve("compulsory","PERIODIC","if the output of your function is periodic then you should specify the periodicity of the function.  If the output is not periodic you must state this using PERIODIC=NO,NO (one for the lower and the other for the upper boundary). For multicomponents then it is PERIODIC=mincomp1,maxcomp1,mincomp2,maxcomp2  etc ");
+      56          19 :   keys.use("PERIODIC");
+      57          38 :   keys.add("optional","COMPONENTS","additional components that this variable is supposed to have. Periodicity is ruled by PERIODIC keyword ");
+      58          19 :   useCustomisableComponents(keys);
+      59          19 : }
+      60             : 
+      61          17 : ColvarFake::ColvarFake(const ActionOptions&ao):
+      62          17 :   PLUMED_COLVAR_INIT(ao)
+      63             : {
+      64             :   std::vector<AtomNumber> atoms;
+      65          34 :   parseAtomList("ATOMS",atoms);
+      66             : 
+      67             :   std::vector<std::string> comps;
+      68             :   // multiple components for this variable
+      69          34 :   parseVector("COMPONENTS",comps);
+      70          17 :   if(comps.size()!=0) {
+      71           2 :     for(unsigned i=0; i<comps.size(); i++) {
+      72           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.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.func-sort-c.html b/coverage/colvar/GHBFIX.cpp.func-sort-c.html new file mode 100644 index 0000000000..a4ba4ddb3d --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.func.html b/coverage/colvar/GHBFIX.cpp.func.html new file mode 100644 index 0000000000..c27bf7f3b5 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118GHBFIXRegisterMe85D2Ev4168
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.gcov.html b/coverage/colvar/GHBFIX.cpp.gcov.html new file mode 100644 index 0000000000..9cb4fcb01e --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7777100.0 %
Date:2024-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(GHBFIX,"GHBFIX")
+      86             : 
+      87           3 : void GHBFIX::registerKeywords( Keywords& keys ) {
+      88           3 :   CoordinationBase::registerKeywords(keys);
+      89             : 
+      90           6 :   keys.add("optional","ENERGY_UNITS","the value of ENERGY_UNITS in the switching function");
+      91           6 :   keys.add("compulsory","TYPES","the value of TYPES in the switching function");
+      92           6 :   keys.add("compulsory","PARAMS","the value of PARAMS in the switching function");
+      93           6 :   keys.add("compulsory","D_MAX","the value of D_MAX in the switching function");
+      94           6 :   keys.add("compulsory","D_0","the value of D_0 in the switching function");
+      95           6 :   keys.add("compulsory","C","the value of C in the switching function");
+      96           3 : }
+      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.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func-sort-c.html b/coverage/colvar/Gyration.cpp.func-sort-c.html new file mode 100644 index 0000000000..2bbf9cdc95 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe926createERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6colvar8Gyration9calculateEv1195
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func.html b/coverage/colvar/Gyration.cpp.func.html new file mode 100644 index 0000000000..14a2326eac --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe926createERKNS_13ActionOptionsE33
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120GyrationRegisterMe92D2Ev4168
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6colvar8Gyration9calculateEv1195
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.gcov.html b/coverage/colvar/Gyration.cpp.gcov.html new file mode 100644 index 0000000000..4989d6842d --- /dev/null +++ b/coverage/colvar/Gyration.cpp.gcov.html @@ -0,0 +1,448 @@ + + + + + + + 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-05-27 13:05: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       12568 : PLUMED_REGISTER_ACTION(Gyration,"GYRATION")
+      93             : 
+      94          35 : void Gyration::registerKeywords(Keywords& keys) {
+      95          35 :   Colvar::registerKeywords(keys);
+      96          70 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      97          70 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      98          70 :   keys.addFlag("MASS_WEIGHTED",false,"set the masses of all the atoms equal to one");
+      99          35 : }
+     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          50 :   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.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func-sort-c.html b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..d76b1961bf --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe1436createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func.html b/coverage/colvar/MultiRMSD.cpp.func.html new file mode 100644 index 0000000000..86746976aa --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe1436createERKNS_13ActionOptionsE3
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_122MultiRMSDRegisterMe143D2Ev4168
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.gcov.html b/coverage/colvar/MultiRMSD.cpp.gcov.html new file mode 100644 index 0000000000..de26004339 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + LCOV - plumed test coverage - colvar/MultiRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424397.7 %
Date:2024-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(MultiRMSD,"MULTI_RMSD")
+     144             : 
+     145           5 : void MultiRMSD::registerKeywords(Keywords& keys) {
+     146           5 :   Colvar::registerKeywords(keys);
+     147          10 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     148          10 :   keys.add("compulsory","TYPE","MULTI-SIMPLE","the manner in which RMSD alignment is performed.  Should be MULTI-OPTIMAL, MULTI-OPTIMAL-FAST,  MULTI-SIMPLE or MULTI-DRMSD.");
+     149          10 :   keys.addFlag("SQUARED",false," This should be set if you want the mean squared displacement instead of the root mean squared displacement");
+     150           5 : }
+     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.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func-sort-c.html b/coverage/colvar/PCARMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..c9bf855552 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PCARMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe1036createERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7PCARMSDC1ERKNS_13ActionOptionsE2
_ZZN4PLMD6colvar7PCARMSDC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_2
_ZN4PLMD6colvar7PCARMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar7PCARMSD9calculateEv1092
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe103C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120PCARMSDRegisterMe103D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func.html b/coverage/colvar/PCARMSD.cpp.func.html new file mode 100644 index 0000000000..cd075c6d48 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe986createERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.func.html b/coverage/colvar/PathMSD.cpp.func.html new file mode 100644 index 0000000000..a4301da528 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe986createERKNS_13ActionOptionsE14
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_119PathMSDRegisterMe98D2Ev4168
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.gcov.html b/coverage/colvar/PathMSD.cpp.gcov.html new file mode 100644 index 0000000000..746feb3724 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.gcov.html @@ -0,0 +1,205 @@ + + + + + + + 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-05-27 13:05: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       12532 : PLUMED_REGISTER_ACTION(PathMSD,"PATHMSD")
+      99             : 
+     100          16 : void PathMSD::registerKeywords(Keywords& keys) {
+     101          16 :   PathMSDBase::registerKeywords(keys);
+     102          16 :   componentsAreNotOptional(keys);
+     103          32 :   keys.addOutputComponent("sss","default","the position on the path");
+     104          32 :   keys.addOutputComponent("zzz","default","the distance from the path");
+     105          16 : }
+     106             : 
+     107          14 : PathMSD::PathMSD(const ActionOptions&ao):
+     108          14 :   Action(ao),PathMSDBase(ao)
+     109             : {
+     110          14 :   checkRead();
+     111             : 
+     112          14 :   log<<"  Bibliography "
+     113          28 :      <<plumed.cite("Branduardi, Gervasio, Parrinello J. Chem. Phys. 126, 054103 (2007)")
+     114          28 :      <<"\n";
+     115             :   // no need to read anything
+     116          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.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.func-sort-c.html b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..bdc7284ef4 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PathMSDBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PathMSDBaseD0Ev0
_ZN4PLMD6colvar11PathMSDBaseD1Ev0
_ZN4PLMD6colvar11PathMSDBaseC2ERKNS_13ActionOptionsE25
_ZN4PLMD6colvar11PathMSDBaseD2Ev25
_ZZN4PLMD6colvar11PathMSDBaseC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_25
_ZN4PLMD6colvar11PathMSDBase16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6colvar11PathMSDBase9calculateEv11179
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.func.html b/coverage/colvar/PathMSDBase.cpp.func.html new file mode 100644 index 0000000000..a079cfc7da --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.func.html b/coverage/colvar/PathMSDBase.h.func.html new file mode 100644 index 0000000000..6d7a3bf05b --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.gcov.html b/coverage/colvar/PathMSDBase.h.gcov.html new file mode 100644 index 0000000000..9588032005 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.gcov.html @@ -0,0 +1,177 @@ + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-05-27 13:05: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      300920 :   class ImagePath {
+      37             :   public:
+      38             :     // cardinal indexing: needed to map over msd
+      39             :     unsigned index;
+      40             :     // spiwok indexing
+      41             :     std::vector<double> property;
+      42             :     // distance
+      43             :     double distance;
+      44             :     // similarity (exp - lambda distance) or other
+      45             :     double similarity;
+      46             :     // derivatives of the distance
+      47             :     std::vector<Vector> distder;
+      48             :     // here one can add a pointer to a value (hypothetically providing a distance from a point)
+      49             :   };
+      50             :   struct imgOrderByDist {
+      51             :     bool operator ()(ImagePath const& a, ImagePath const& b) {
+      52           0 :       return (a).distance < (b).distance;
+      53             :     }
+      54             :   };
+      55             :   struct imgOrderBySimilarity {
+      56             :     bool operator ()(ImagePath const& a, ImagePath const& b) {
+      57             :       return (a).similarity > (b).similarity;
+      58             :     }
+      59             :   };
+      60             : 
+      61             :   bool nopbc;
+      62             : 
+      63             :   double lambda;
+      64             :   int neigh_size;
+      65             :   int neigh_stride;
+      66             :   std::vector<RMSD> msdv;
+      67             :   std::string reference;
+      68             :   std::vector<Vector> derivs_s;
+      69             :   std::vector<Vector> derivs_z;
+      70             :   std::vector <ImagePath> imgVec; // this can be used for doing neighlist
+      71             : 
+      72             :   //variables used for the close structure method, i is the number of reference structures
+      73             :   double epsilonClose; //the maximal distance between the close and the current structure before reassignment
+      74             :   int debugClose; //turns on debug mode
+      75             :   int logClose; //turns on logging
+      76             :   RMSD rmsdPosClose; //rmsd between the current and the close structure
+      77             :   bool firstPosClose; //flag indicating the first time we need to calculate the distance between the close and the current structure
+      78             :   bool computeRefClose; //flag indicating necessity to recompute accurately all distances and rotation matrices between the close structure and reference str
+      79             :   std::vector<Tensor> rotationRefClose; //Tensor[i] saved rotation matrices between the close structure and reference structures
+      80             :   Tensor rotationPosClose; //rotation matrix between the close and the current structure
+      81             :   std::array<std::array<Tensor,3>,3> drotationPosCloseDrr01; //Tensor[3][3]; //derivation of the rotation matrix w.r.t rr01, necessary for calculation of derivations
+      82             :   std::vector<unsigned> savedIndices; //saved indices of imgVec from previous steps, used for recalculating after neighbourlist update
+      83             : protected:
+      84             :   std::vector<PDB> pdbv;
+      85             :   std::vector<std::string> labels;
+      86             :   std::vector< std::vector<double> > indexvec; // use double to allow isomaps
+      87             :   unsigned nframes;
+      88             : public:
+      89             :   explicit PathMSDBase(const ActionOptions&);
+      90             :   ~PathMSDBase();
+      91             : // active methods:
+      92             :   void calculate() override;
+      93             : //  virtual void prepare();
+      94             :   static void registerKeywords(Keywords& keys);
+      95             : };
+      96             : 
+      97             : }
+      98             : }
+      99             : 
+     100             : #endif
+     101             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func-sort-c.html b/coverage/colvar/Position.cpp.func-sort-c.html new file mode 100644 index 0000000000..21f52a280e --- /dev/null +++ b/coverage/colvar/Position.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe846createERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84D2Ev4168
_ZN4PLMD6colvar8Position9calculateEv8037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func.html b/coverage/colvar/Position.cpp.func.html new file mode 100644 index 0000000000..fb3c91f2c8 --- /dev/null +++ b/coverage/colvar/Position.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe846createERKNS_13ActionOptionsE87
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120PositionRegisterMe84D2Ev4168
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD6colvar8Position9calculateEv8037
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.gcov.html b/coverage/colvar/Position.cpp.gcov.html new file mode 100644 index 0000000000..dab030b044 --- /dev/null +++ b/coverage/colvar/Position.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + 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-05-27 13:05: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       12677 : PLUMED_REGISTER_ACTION(Position,"POSITION")
+      85             : 
+      86          89 : void Position::registerKeywords( Keywords& keys ) {
+      87          89 :   Colvar::registerKeywords( keys );
+      88          89 :   componentsAreNotOptional(keys);
+      89         178 :   keys.add("atoms","ATOM","the atom number");
+      90         178 :   keys.addFlag("SCALED_COMPONENTS",false,"calculate the a, b and c scaled components of the position separately and store them as label.a, label.b and label.c");
+      91         178 :   keys.addOutputComponent("x","default","the x-component of the atom position");
+      92         178 :   keys.addOutputComponent("y","default","the y-component of the atom position");
+      93         178 :   keys.addOutputComponent("z","default","the z-component of the atom position");
+      94         178 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the atom position");
+      95         178 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the atom position");
+      96         178 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the atom position");
+      97          89 : }
+      98             : 
+      99          87 : Position::Position(const ActionOptions&ao):
+     100             :   PLUMED_COLVAR_INIT(ao),
+     101          87 :   scaled_components(false),
+     102          87 :   pbc(true)
+     103             : {
+     104             :   std::vector<AtomNumber> atoms;
+     105         174 :   parseAtomList("ATOM",atoms);
+     106          87 :   if(atoms.size()!=1)
+     107           1 :     error("Number of specified atoms should be 1");
+     108          86 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     109          86 :   bool nopbc=!pbc;
+     110          86 :   parseFlag("NOPBC",nopbc);
+     111          86 :   pbc=!nopbc;
+     112          86 :   checkRead();
+     113             : 
+     114          86 :   log.printf("  for atom %d\n",atoms[0].serial());
+     115          86 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     116           4 :   else    log.printf("  without periodic boundary conditions\n");
+     117             : 
+     118          86 :   if(scaled_components) {
+     119          12 :     addComponentWithDerivatives("a"); componentIsPeriodic("a","-0.5","+0.5");
+     120          12 :     addComponentWithDerivatives("b"); componentIsPeriodic("b","-0.5","+0.5");
+     121          12 :     addComponentWithDerivatives("c"); componentIsPeriodic("c","-0.5","+0.5");
+     122             :   } else {
+     123         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.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html new file mode 100644 index 0000000000..60aacd80a4 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe796createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func.html b/coverage/colvar/ProjectionOnAxis.cpp.func.html new file mode 100644 index 0000000000..25da353d53 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe796createERKNS_13ActionOptionsE1
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_128ProjectionOnAxisRegisterMe79D2Ev4168
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.gcov.html b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html new file mode 100644 index 0000000000..7e2e9f5928 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(ProjectionOnAxis,"PROJECTION_ON_AXIS")
+      80             : 
+      81           3 : void ProjectionOnAxis::registerKeywords( Keywords& keys ) {
+      82           3 :   Colvar::registerKeywords(keys);
+      83           6 :   keys.add("atoms","AXIS_ATOMS","The atoms that define the direction of the axis of interest");
+      84           6 :   keys.add("atoms","ATOM","The atom whose position we want to project on the axis of interest");
+      85           6 :   keys.addOutputComponent("proj","COMPONENTS","The value of the projection along the axis");
+      86           6 :   keys.addOutputComponent("ext","COMPONENTS","The value of the extension from the axis");
+      87           3 : }
+      88             : 
+      89           1 : ProjectionOnAxis::ProjectionOnAxis(const ActionOptions&ao):
+      90             :   PLUMED_COLVAR_INIT(ao),
+      91           1 :   pbc(true)
+      92             : {
+      93             :   std::vector<AtomNumber> axis_atoms;
+      94           2 :   parseAtomList("AXIS_ATOMS",axis_atoms);
+      95           1 :   if( axis_atoms.size()!=2 ) error("There should only be two atoms specified to AXIS_ATOMS keyword");
+      96             :   std::vector<AtomNumber> atom;
+      97           2 :   parseAtomList("ATOM",atom);
+      98           1 :   if( atom.size()!=1 ) error("There should only be one atom specified to ATOM keyword");
+      99           1 :   log.printf("  calculating projection of vector connecting atom %d and atom %d on vector connecting atom %d and atom %d \n",
+     100             :              axis_atoms[0].serial(), atom[0].serial(), axis_atoms[0].serial(), axis_atoms[1].serial() );
+     101           1 :   bool nopbc=!pbc;
+     102           1 :   parseFlag("NOPBC",nopbc);
+     103           1 :   pbc=!nopbc;
+     104             : 
+     105           1 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     106           0 :   else    log.printf("  not using periodic boundary conditions\n");
+     107             : 
+     108             :   // Add values to store data
+     109           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.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.func-sort-c.html b/coverage/colvar/PropertyMap.cpp.func-sort-c.html new file mode 100644 index 0000000000..87da8f5b1d --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe976createERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.func.html b/coverage/colvar/PropertyMap.cpp.func.html new file mode 100644 index 0000000000..bcf5a4f525 --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe976createERKNS_13ActionOptionsE11
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_123PropertyMapRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.gcov.html b/coverage/colvar/PropertyMap.cpp.gcov.html new file mode 100644 index 0000000000..63147f4fdc --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + 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-05-27 13:05: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       12526 : PLUMED_REGISTER_ACTION(PropertyMap,"PROPERTYMAP")
+      98             : 
+      99          13 : void PropertyMap::registerKeywords(Keywords& keys) {
+     100          13 :   PathMSDBase::registerKeywords(keys);
+     101          26 :   keys.add("compulsory","PROPERTY","the property to be used in the indexing: this goes in the REMARK field of the reference");
+     102          13 :   ActionWithValue::useCustomisableComponents(keys);
+     103          26 :   keys.addOutputComponent("zzz","default","the minimum distance from the reference points");
+     104          13 : }
+     105             : 
+     106          11 : PropertyMap::PropertyMap(const ActionOptions&ao):
+     107             :   Action(ao),
+     108          11 :   PathMSDBase(ao)
+     109             : {
+     110             :   // this is the only additional keyword needed
+     111          11 :   parseVector("PROPERTY",labels);
+     112          11 :   checkRead();
+     113          11 :   log<<"  Bibliography "
+     114          22 :      <<plumed.cite("Spiwok V, Kralova B  J. Chem. Phys. 135,  224504 (2011)")
+     115          22 :      <<"\n";
+     116          11 :   if(labels.size()==0) {
+     117             :     const std::size_t buflen=500;
+     118             :     char buf[buflen];
+     119             :     std::snprintf(buf,buflen,"Need to specify PROPERTY with this action\n");
+     120           0 :     plumed_merror(buf);
+     121             :   } else {
+     122          33 :     for(unsigned i=0; i<labels.size(); i++) {
+     123          22 :       log<<" found custom propety to be found in the REMARK line: "<<labels[i].c_str()<<"\n";
+     124          22 :       addComponentWithDerivatives(labels[i]); componentIsNotPeriodic(labels[i]);
+     125             :     }
+     126             :     // add distance anyhow
+     127          22 :     addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     128             :     //reparse the REMARK field and pick the index
+     129         473 :     for(unsigned i=0; i<pdbv.size(); i++) {
+     130             :       // now look for X=1.34555 Y=5.6677
+     131             :       std::vector<double> labelvals;
+     132        1386 :       for(unsigned j=0; j<labels.size(); j++) {
+     133             :         double val;
+     134         924 :         if( pdbv[i].getArgumentValue(labels[j],val) ) {labelvals.push_back(val);}
+     135             :         else {
+     136             :           const std::size_t buflen=500;
+     137             :           char buf[buflen];
+     138             :           std::snprintf(buf,buflen,"PROPERTY LABEL \" %s \" NOT FOUND IN REMARK FOR FRAME %u \n",labels[j].c_str(),i);
+     139           0 :           plumed_merror(buf);
+     140             :         };
+     141             :       }
+     142         462 :       indexvec.push_back(labelvals);
+     143             :     }
+     144             :   }
+     145          11 :   requestAtoms(pdbv[0].getAtomNumbers());
+     146             : 
+     147          11 : }
+     148             : 
+     149             : }
+     150             : }
+     151             : 
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.func-sort-c.html b/coverage/colvar/Puckering.cpp.func-sort-c.html new file mode 100644 index 0000000000..48456dca32 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe816createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering9calculateEv397
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.func.html b/coverage/colvar/Puckering.cpp.func.html new file mode 100644 index 0000000000..a36a79c731 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe816createERKNS_13ActionOptionsE54
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_121PuckeringRegisterMe81D2Ev4168
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar9Puckering9calculateEv397
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.gcov.html b/coverage/colvar/Puckering.cpp.gcov.html new file mode 100644 index 0000000000..6a5366ab9f --- /dev/null +++ b/coverage/colvar/Puckering.cpp.gcov.html @@ -0,0 +1,496 @@ + + + + + + + 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-05-27 13:05: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       12611 : PLUMED_REGISTER_ACTION(Puckering,"PUCKERING")
+      82             : 
+      83          56 : void Puckering::registerKeywords(Keywords& keys) {
+      84          56 :   Colvar::registerKeywords( keys );
+      85          56 :   keys.remove("NOPBC");
+      86         112 :   keys.add("atoms","ATOMS","the five or six atoms of the sugar ring in the proper order");
+      87         112 :   keys.addOutputComponent("phs","default","Pseudorotation phase (5 membered rings)");
+      88         112 :   keys.addOutputComponent("amp","default","Pseudorotation amplitude (5 membered rings)");
+      89         112 :   keys.addOutputComponent("Zx","default","Pseudorotation x Cartesian component (5 membered rings)");
+      90         112 :   keys.addOutputComponent("Zy","default","Pseudorotation y Cartesian component (5 membered rings)");
+      91         112 :   keys.addOutputComponent("phi","default","Pseudorotation phase (6 membered rings)");
+      92         112 :   keys.addOutputComponent("theta","default","Theta angle (6 membered rings)");
+      93         112 :   keys.addOutputComponent("amplitude","default","Pseudorotation amplitude (6 membered rings)");
+      94         112 :   keys.addOutputComponent("qx","default","Cartesian component x (6 membered rings)");
+      95         112 :   keys.addOutputComponent("qy","default","Cartesian component y (6 membered rings)");
+      96         112 :   keys.addOutputComponent("qz","default","Cartesian component z (6 membered rings)");
+      97          56 : }
+      98             : 
+      99          54 : Puckering::Puckering(const ActionOptions&ao):
+     100          54 :   PLUMED_COLVAR_INIT(ao)
+     101             : {
+     102             :   std::vector<AtomNumber> atoms;
+     103         108 :   parseAtomList("ATOMS",atoms);
+     104          54 :   if(atoms.size()!=5 && atoms.size()!=6) error("only for 5 or 6-membered rings");
+     105          53 :   checkRead();
+     106             : 
+     107          53 :   if(atoms.size()==5) {
+     108          52 :     log.printf("  between atoms %d %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial(),atoms[4].serial());
+     109           1 :   } else if(atoms.size()==6) {
+     110           1 :     log.printf("  between atoms %d %d %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial(),atoms[4].serial(),atoms[5].serial());
+     111           0 :   } else error("ATOMS should specify 5 atoms");
+     112             : 
+     113          53 :   if(atoms.size()==5) {
+     114         156 :     addComponentWithDerivatives("phs"); componentIsPeriodic("phs","-pi","pi");
+     115         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         105 :   if(atoms.size()==5) log<<plumed.cite("Huang, Giese, Lee, York, J. Chem. Theory Comput. 10, 1538 (2014)");
+     129          55 :   if(atoms.size()==6) log<<plumed.cite("Cremer and Pople, J. Am. Chem. Soc. 97, 1354 (1975)");
+     130          53 :   log<<"\n";
+     131             : 
+     132          53 :   requestAtoms(atoms);
+     133          55 : }
+     134             : 
+     135             : // calculator
+     136         397 : void Puckering::calculate() {
+     137         397 :   makeWhole();
+     138         397 :   if(getNumberOfAtoms()==5) calculate5m();
+     139         103 :   else calculate6m();
+     140         397 : }
+     141             : 
+     142         294 : void Puckering::calculate5m() {
+     143             : 
+     144         294 :   Vector d0,d1,d2,d3,d4,d5;
+     145             : 
+     146         294 :   d0=delta(getPosition(2),getPosition(1));
+     147         294 :   d1=delta(getPosition(3),getPosition(2));
+     148         294 :   d2=delta(getPosition(4),getPosition(3));
+     149         294 :   d3=delta(getPosition(4),getPosition(3));
+     150         294 :   d4=delta(getPosition(0),getPosition(4));
+     151         294 :   d5=delta(getPosition(1),getPosition(0));
+     152             : 
+     153         294 :   Vector dd0,dd1,dd2,dd3,dd4,dd5;
+     154             : 
+     155             :   PLMD::Torsion t;
+     156             : 
+     157         294 :   double v1=t.compute(d0,d1,d2,dd0,dd1,dd2);
+     158         294 :   double v3=t.compute(d3,d4,d5,dd3,dd4,dd5);
+     159             : 
+     160         294 :   double Zx=(v1+v3)/(2.0*std::cos(4.0*pi/5.0));
+     161         294 :   double Zy=(v1-v3)/(2.0*std::sin(4.0*pi/5.0));
+     162         294 :   double phase=std::atan2(Zy,Zx);
+     163         294 :   double amplitude=std::sqrt(Zx*Zx+Zy*Zy);
+     164             : 
+     165        1764 :   Vector dZx_dR[5];
+     166        1764 :   Vector dZy_dR[5];
+     167             : 
+     168         294 :   dZx_dR[0]=(dd5-dd4);
+     169         294 :   dZx_dR[1]=(dd0-dd5);
+     170         294 :   dZx_dR[2]=(dd1-dd0);
+     171         294 :   dZx_dR[3]=(dd2+dd3-dd1);
+     172         294 :   dZx_dR[4]=(dd4-dd3-dd2);
+     173             : 
+     174         294 :   dZy_dR[0]=(dd4-dd5);
+     175         294 :   dZy_dR[1]=(dd0+dd5);
+     176         294 :   dZy_dR[2]=(dd1-dd0);
+     177         294 :   dZy_dR[3]=(dd2-dd3-dd1);
+     178         294 :   dZy_dR[4]=(dd3-dd4-dd2);
+     179             : 
+     180        1764 :   for(unsigned j=0; j<5; j++) dZx_dR[j]*=(1.0/(2.0*std::cos(4.0*pi/5.0)));
+     181        1764 :   for(unsigned j=0; j<5; j++) dZy_dR[j]*=(1.0/(2.0*std::sin(4.0*pi/5.0)));
+     182             : 
+     183        1764 :   Vector dphase_dR[5];
+     184        1764 :   for(unsigned j=0; j<5; j++) dphase_dR[j]=(1.0/(Zx*Zx+Zy*Zy))*(-Zy*dZx_dR[j] + Zx*dZy_dR[j]);
+     185             : 
+     186        1764 :   Vector damplitude_dR[5];
+     187        1764 :   for(unsigned j=0; j<5; j++) damplitude_dR[j]=(1.0/amplitude)*(Zx*dZx_dR[j] + Zy*dZy_dR[j]);
+     188             : 
+     189         588 :   Value* vzx=getPntrToComponent("Zx");
+     190             :   vzx->set(Zx);
+     191         294 :   setAtomsDerivatives (vzx,0, dZx_dR[0]);
+     192         294 :   setAtomsDerivatives (vzx,1, dZx_dR[1]);
+     193         294 :   setAtomsDerivatives (vzx,2, dZx_dR[2]);
+     194         294 :   setAtomsDerivatives (vzx,3, dZx_dR[3]);
+     195         294 :   setAtomsDerivatives (vzx,4, dZx_dR[4]);
+     196         294 :   setBoxDerivativesNoPbc(vzx);
+     197             : 
+     198         588 :   Value* vzy=getPntrToComponent("Zy");
+     199             :   vzy->set(Zy);
+     200         294 :   setAtomsDerivatives (vzy,0, dZy_dR[0]);
+     201         294 :   setAtomsDerivatives (vzy,1, dZy_dR[1]);
+     202         294 :   setAtomsDerivatives (vzy,2, dZy_dR[2]);
+     203         294 :   setAtomsDerivatives (vzy,3, dZy_dR[3]);
+     204         294 :   setAtomsDerivatives (vzy,4, dZy_dR[4]);
+     205         294 :   setBoxDerivativesNoPbc(vzy);
+     206             : 
+     207             : 
+     208         588 :   Value* vph=getPntrToComponent("phs");
+     209             :   vph->set(phase);
+     210         294 :   setAtomsDerivatives (vph,0, dphase_dR[0]);
+     211         294 :   setAtomsDerivatives (vph,1, dphase_dR[1]);
+     212         294 :   setAtomsDerivatives (vph,2, dphase_dR[2]);
+     213         294 :   setAtomsDerivatives (vph,3, dphase_dR[3]);
+     214         294 :   setAtomsDerivatives (vph,4, dphase_dR[4]);
+     215         294 :   setBoxDerivativesNoPbc(vph);
+     216             : 
+     217         588 :   Value* vam=getPntrToComponent("amp");
+     218             :   vam->set(amplitude);
+     219         294 :   setAtomsDerivatives (vam,0, damplitude_dR[0]);
+     220         294 :   setAtomsDerivatives (vam,1, damplitude_dR[1]);
+     221         294 :   setAtomsDerivatives (vam,2, damplitude_dR[2]);
+     222         294 :   setAtomsDerivatives (vam,3, damplitude_dR[3]);
+     223         294 :   setAtomsDerivatives (vam,4, damplitude_dR[4]);
+     224         294 :   setBoxDerivativesNoPbc(vam);
+     225             : 
+     226             : 
+     227         294 : }
+     228             : 
+     229         103 : void Puckering::calculate6m() {
+     230             : 
+     231         103 :   std::vector<Vector> r(6);
+     232         721 :   for(unsigned i=0; i<6; i++) r[i]=getPosition(i);
+     233             : 
+     234         103 :   std::vector<Vector> R(6);
+     235         103 :   Vector center;
+     236         721 :   for(unsigned j=0; j<6; j++) center+=r[j]/6.0;
+     237         721 :   for(unsigned j=0; j<6; j++) R[j]=(r[j]-center);
+     238             : 
+     239         103 :   Vector Rp,Rpp;
+     240         721 :   for(unsigned j=0; j<6; j++) Rp +=R[j]*std::sin(2.0/6.0*pi*j);
+     241         721 :   for(unsigned j=0; j<6; j++) Rpp+=R[j]*std::cos(2.0/6.0*pi*j);
+     242             : 
+     243         103 :   Vector n=crossProduct(Rp,Rpp);
+     244         103 :   Vector nhat=n/modulo(n);
+     245             : 
+     246         103 :   Tensor dn_dRp=dcrossDv1(Rp,Rpp);
+     247         103 :   Tensor dn_dRpp=dcrossDv2(Rp,Rpp);
+     248             : 
+     249         103 :   Tensor dnhat_dn= 1.0/modulo(n)*( Tensor::identity() - extProduct(nhat,nhat));
+     250         103 :   Tensor dnhat_dRp=matmul(dnhat_dn,dn_dRp);
+     251         103 :   Tensor dnhat_dRpp=matmul(dnhat_dn,dn_dRpp);
+     252             : 
+     253         103 :   std::vector<double> z(6);
+     254         721 :   for(unsigned j=0; j<6; j++) z[j]=dotProduct(R[j],nhat);
+     255             : 
+     256         103 :   std::vector<std::vector<Vector> > dz_dR(6);
+     257         721 :   for(unsigned j=0; j<6; j++) dz_dR[j].resize(6);
+     258             : 
+     259        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     260        3708 :       if(i==j) dz_dR[i][j]+=nhat;
+     261        3708 :       dz_dR[i][j]+=matmul(R[i],dnhat_dRp)*std::sin(2.0/6.0*pi*j);
+     262        3708 :       dz_dR[i][j]+=matmul(R[i],dnhat_dRpp)*std::cos(2.0/6.0*pi*j);
+     263             :     }
+     264             : 
+     265             :   double B=0.0;
+     266         721 :   for(unsigned j=0; j<6; j++) B+=z[j]*std::cos(4.0/6.0*pi*j);
+     267             : 
+     268         103 :   std::vector<Vector> dB_dR(6);
+     269        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     270        3708 :       dB_dR[i]+=dz_dR[j][i]*std::cos(4.0/6.0*pi*j);
+     271             :     }
+     272         103 :   Vector Bsum;
+     273         721 :   for(unsigned j=0; j<6; j++) Bsum+=dB_dR[j];
+     274         721 :   for(unsigned j=0; j<6; j++) dB_dR[j]-=Bsum/6.0;;
+     275             : 
+     276             :   double A=0.0;
+     277         721 :   for(unsigned j=0; j<6; j++) A+=z[j]*std::sin(4.0/6.0*pi*j);
+     278             : 
+     279         103 :   std::vector<Vector> dA_dR(6);
+     280        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     281        3708 :       dA_dR[i]+=dz_dR[j][i]*std::sin(4.0/6.0*pi*j);
+     282             :     }
+     283         103 :   Vector Asum;
+     284         721 :   for(unsigned j=0; j<6; j++) Asum+=dA_dR[j];
+     285         721 :   for(unsigned j=0; j<6; j++) dA_dR[j]-=Asum/6.0;;
+     286             : 
+     287             :   double C=0.0;
+     288         721 :   for(unsigned j=0; j<6; j++) C+=z[j]*Tools::fastpow(-1.0,(j));
+     289             : 
+     290         103 :   std::vector<Vector> dC_dR(6);
+     291        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     292        3708 :       dC_dR[i]+=dz_dR[j][i]*Tools::fastpow(-1.0,(j));
+     293             :     }
+     294             : 
+     295         103 :   Vector Csum;
+     296         721 :   for(unsigned j=0; j<6; j++) Csum+=dC_dR[j];
+     297         721 :   for(unsigned j=0; j<6; j++) dC_dR[j]-=Csum/6.0;;
+     298             : 
+     299             : 
+     300             : // qx
+     301         103 :   double qx = -A/std::sqrt(3);
+     302             : 
+     303             : // qx derivaties
+     304         103 :   std::vector<Vector> dqx_dR(6);
+     305         721 :   for(unsigned j=0; j<6; j++) {
+     306         618 :     dqx_dR[j]=-1/std::sqrt(3) * dA_dR[j];
+     307             :   }
+     308             : 
+     309         206 :   Value* vqx=getPntrToComponent("qx");
+     310             :   vqx->set(qx);
+     311         103 :   setAtomsDerivatives (vqx,0, dqx_dR[0] );
+     312         103 :   setAtomsDerivatives (vqx,1, dqx_dR[1] );
+     313         103 :   setAtomsDerivatives (vqx,2, dqx_dR[2] );
+     314         103 :   setAtomsDerivatives (vqx,3, dqx_dR[3] );
+     315         103 :   setAtomsDerivatives (vqx,4, dqx_dR[4] );
+     316         103 :   setAtomsDerivatives (vqx,5, dqx_dR[5] );
+     317         103 :   setBoxDerivativesNoPbc(vqx);
+     318             : 
+     319             : // qy
+     320         103 :   double qy = B/std::sqrt(3);
+     321             : 
+     322             : // qy derivatives
+     323         103 :   std::vector<Vector> dqy_dR(6);
+     324         721 :   for(unsigned j=0; j<6; j++) {
+     325         618 :     dqy_dR[j]=1/std::sqrt(3) * dB_dR[j];
+     326             :   }
+     327             : 
+     328         206 :   Value* vqy=getPntrToComponent("qy");
+     329             :   vqy->set(qy);
+     330         103 :   setAtomsDerivatives (vqy,0, dqy_dR[0] );
+     331         103 :   setAtomsDerivatives (vqy,1, dqy_dR[1] );
+     332         103 :   setAtomsDerivatives (vqy,2, dqy_dR[2] );
+     333         103 :   setAtomsDerivatives (vqy,3, dqy_dR[3] );
+     334         103 :   setAtomsDerivatives (vqy,4, dqy_dR[4] );
+     335         103 :   setAtomsDerivatives (vqy,5, dqy_dR[5] );
+     336         103 :   setBoxDerivativesNoPbc(vqy);
+     337             : 
+     338             : // qz
+     339         103 :   double qz = C/std::sqrt(6);
+     340             : 
+     341             : // qz derivatives
+     342         103 :   std::vector<Vector> dqz_dR(6);
+     343         721 :   for(unsigned j=0; j<6; j++) {
+     344         618 :     dqz_dR[j]=1/std::sqrt(6) * dC_dR[j];
+     345             :   }
+     346             : 
+     347         206 :   Value* vqz=getPntrToComponent("qz");
+     348             :   vqz->set(qz);
+     349         103 :   setAtomsDerivatives (vqz,0, dqz_dR[0] );
+     350         103 :   setAtomsDerivatives (vqz,1, dqz_dR[1] );
+     351         103 :   setAtomsDerivatives (vqz,2, dqz_dR[2] );
+     352         103 :   setAtomsDerivatives (vqz,3, dqz_dR[3] );
+     353         103 :   setAtomsDerivatives (vqz,4, dqz_dR[4] );
+     354         103 :   setAtomsDerivatives (vqz,5, dqz_dR[5] );
+     355         103 :   setBoxDerivativesNoPbc(vqz);
+     356             : 
+     357             : 
+     358             : // PHASE
+     359         103 :   double phi=std::atan2(-A,B);
+     360             : 
+     361             : // PHASE DERIVATIVES
+     362         103 :   std::vector<Vector> dphi_dR(6);
+     363         721 :   for(unsigned j=0; j<6; j++) {
+     364         618 :     dphi_dR[j]=1.0/(A*A+B*B) * (-B*dA_dR[j] + A*dB_dR[j]);
+     365             :   }
+     366             : 
+     367         206 :   Value* vphi=getPntrToComponent("phi");
+     368             :   vphi->set(phi);
+     369         103 :   setAtomsDerivatives (vphi,0, dphi_dR[0] );
+     370         103 :   setAtomsDerivatives (vphi,1, dphi_dR[1] );
+     371         103 :   setAtomsDerivatives (vphi,2, dphi_dR[2] );
+     372         103 :   setAtomsDerivatives (vphi,3, dphi_dR[3] );
+     373         103 :   setAtomsDerivatives (vphi,4, dphi_dR[4] );
+     374         103 :   setAtomsDerivatives (vphi,5, dphi_dR[5] );
+     375         103 :   setBoxDerivativesNoPbc(vphi);
+     376             : 
+     377             : //  AMPLITUDE
+     378         103 :   double amplitude=std::sqrt((2*(A*A+B*B)+C*C)/6);
+     379             : 
+     380             : //  AMPLITUDE DERIVATIES
+     381         103 :   std::vector<Vector> damplitude_dR(6);
+     382         721 :   for (unsigned j=0; j<6; j++) {
+     383         618 :     damplitude_dR[j]=0.5*std::sqrt(2.0/6.0)/(std::sqrt(A*A+B*B+0.5*C*C)) * (2*A*dA_dR[j] + 2*B*dB_dR[j] + C*dC_dR[j]);
+     384             :   }
+     385             : 
+     386         206 :   Value* vamplitude=getPntrToComponent("amplitude");
+     387             :   vamplitude->set(amplitude);
+     388         103 :   setAtomsDerivatives (vamplitude,0, damplitude_dR[0] );
+     389         103 :   setAtomsDerivatives (vamplitude,1, damplitude_dR[1] );
+     390         103 :   setAtomsDerivatives (vamplitude,2, damplitude_dR[2] );
+     391         103 :   setAtomsDerivatives (vamplitude,3, damplitude_dR[3] );
+     392         103 :   setAtomsDerivatives (vamplitude,4, damplitude_dR[4] );
+     393         103 :   setAtomsDerivatives (vamplitude,5, damplitude_dR[5] );
+     394         103 :   setBoxDerivativesNoPbc(vamplitude);
+     395             : 
+     396             : //  THETA
+     397         103 :   double theta=std::acos( C / std::sqrt(2.*(A*A+B*B) +C*C ) );
+     398             : 
+     399             : //  THETA DERIVATIVES
+     400         103 :   std::vector<Vector> dtheta_dR(6);
+     401         721 :   for(unsigned j=0; j<6; j++) {
+     402         618 :     dtheta_dR[j]=1.0/(3.0*std::sqrt(2)*amplitude*amplitude) * (C/(std::sqrt(A*A+B*B)) * (A*dA_dR[j] + B*dB_dR[j]) - std::sqrt(A*A+B*B)*dC_dR[j]);
+     403             :   }
+     404         206 :   Value* vtheta=getPntrToComponent("theta");
+     405             :   vtheta->set(theta);
+     406         103 :   setAtomsDerivatives (vtheta,0, dtheta_dR[0] );
+     407         103 :   setAtomsDerivatives (vtheta,1, dtheta_dR[1] );
+     408         103 :   setAtomsDerivatives (vtheta,2, dtheta_dR[2] );
+     409         103 :   setAtomsDerivatives (vtheta,3, dtheta_dR[3] );
+     410         103 :   setAtomsDerivatives (vtheta,4, dtheta_dR[4] );
+     411         103 :   setAtomsDerivatives (vtheta,5, dtheta_dR[5] );
+     412         103 :   setBoxDerivativesNoPbc(vtheta);
+     413         206 : }
+     414             : 
+     415             : 
+     416             : }
+     417             : }
+     418             : 
+     419             : 
+     420             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func-sort-c.html b/coverage/colvar/RMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..11cbde71ff --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe1626createERKNS_13ActionOptionsE78
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE78
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162D2Ev4168
_ZN4PLMD6colvar4RMSD9calculateEv40496
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func.html b/coverage/colvar/RMSD.cpp.func.html new file mode 100644 index 0000000000..26292e56ce --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe1626createERKNS_13ActionOptionsE78
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_117RMSDRegisterMe162D2Ev4168
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD6colvar4RMSD9calculateEv40496
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE78
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.gcov.html b/coverage/colvar/RMSD.cpp.gcov.html new file mode 100644 index 0000000000..e21f0fb2e2 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + LCOV - plumed test coverage - colvar/RMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-05-27 13:05: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       12658 : PLUMED_REGISTER_ACTION(RMSD,"RMSD")
+     163             : 
+     164          80 : void RMSD::registerKeywords(Keywords& keys) {
+     165          80 :   Colvar::registerKeywords(keys);
+     166         160 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     167         160 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     168         160 :   keys.addFlag("SQUARED",false," This should be set if you want mean squared displacement instead of RMSD ");
+     169          80 : }
+     170             : 
+     171          78 : RMSD::RMSD(const ActionOptions&ao):
+     172             :   PLUMED_COLVAR_INIT(ao),
+     173         158 :   myvals(1,0),
+     174          78 :   mypack(0,0,myvals),
+     175          78 :   squared(false),
+     176         156 :   nopbc(false)
+     177             : {
+     178             :   std::string reference;
+     179         158 :   parse("REFERENCE",reference);
+     180             :   std::string type;
+     181          78 :   type.assign("SIMPLE");
+     182          78 :   parse("TYPE",type);
+     183          78 :   parseFlag("SQUARED",squared);
+     184          80 :   parseFlag("NOPBC",nopbc);
+     185             : 
+     186          78 :   checkRead();
+     187             : 
+     188             : 
+     189          78 :   addValueWithDerivatives(); setNotPeriodic();
+     190          78 :   PDB pdb;
+     191             : 
+     192             :   // read everything in ang and transform to nm if we are not in natural units
+     193         156 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength()) )
+     194           1 :     error("missing input file " + reference );
+     195             : 
+     196         154 :   rmsd=metricRegister().create<RMSDBase>(type,pdb);
+     197             : 
+     198             :   std::vector<AtomNumber> atoms;
+     199          77 :   rmsd->getAtomRequests( atoms );
+     200             : //  rmsd->setNumberOfAtoms( atoms.size() );
+     201          77 :   requestAtoms( atoms );
+     202             : 
+     203             :   // Setup the derivative pack
+     204          77 :   myvals.resize( 1, 3*atoms.size()+9 ); mypack.resize( 0, atoms.size() );
+     205        3833 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     206             : 
+     207          76 :   log.printf("  reference from file %s\n",reference.c_str());
+     208          76 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     209          76 :   log.printf("  with indices : ");
+     210        3833 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     211        3757 :     if(i%25==0) log<<"\n";
+     212        3757 :     log.printf("%d ",atoms[i].serial());
+     213             :   }
+     214          76 :   log.printf("\n");
+     215          76 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     216          76 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     217          76 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     218          19 :   else      log.printf("  using periodic boundary conditions\n");
+     219         164 : }
+     220             : 
+     221             : 
+     222             : // calculator
+     223       40496 : void RMSD::calculate() {
+     224       40496 :   if(!nopbc) makeWhole();
+     225       40496 :   double r=rmsd->calculate( getPositions(), mypack, squared );
+     226             : 
+     227       40496 :   setValue(r);
+     228    14617727 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives( i, mypack.getAtomDerivative(i) );
+     229             : 
+     230       40496 :   Tensor virial; plumed_dbg_assert( !mypack.virialWasSet() );
+     231       40496 :   setBoxDerivativesNoPbc();
+     232       40496 : }
+     233             : 
+     234             : }
+     235             : }
+     236             : 
+     237             : 
+     238             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.func-sort-c.html b/coverage/colvar/Template.cpp.func-sort-c.html new file mode 100644 index 0000000000..14b53afb9b --- /dev/null +++ b/coverage/colvar/Template.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.func.html b/coverage/colvar/Template.cpp.func.html new file mode 100644 index 0000000000..a83b7033fa --- /dev/null +++ b/coverage/colvar/Template.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe596createERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120TemplateRegisterMe59D2Ev4168
_ZN4PLMD6colvar8Template16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6colvar8Template9calculateEv0
_ZN4PLMD6colvar8TemplateC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8TemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.gcov.html b/coverage/colvar/Template.cpp.gcov.html new file mode 100644 index 0000000000..c2c3e722cb --- /dev/null +++ b/coverage/colvar/Template.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(Template,"TEMPLATE")
+      60             : 
+      61           2 : void Template::registerKeywords(Keywords& keys) {
+      62           2 :   Colvar::registerKeywords(keys);
+      63           4 :   keys.addFlag("TEMPLATE_DEFAULT_OFF_FLAG",false,"flags that are by default not performed should be specified like this");
+      64           4 :   keys.add("compulsory","TEMPLATE_COMPULSORY","all compulsory keywords should be added like this with a description here");
+      65           4 :   keys.add("optional","TEMPLATE_OPTIONAL","all optional keywords that have input should be added like a description here");
+      66           4 :   keys.add("atoms","ATOMS","the keyword with which you specify what atoms to use should be added like this");
+      67           2 : }
+      68             : 
+      69           0 : Template::Template(const ActionOptions&ao):
+      70             :   PLUMED_COLVAR_INIT(ao),
+      71           0 :   pbc(true)
+      72             : {
+      73             :   std::vector<AtomNumber> atoms;
+      74           0 :   parseAtomList("ATOMS",atoms);
+      75           0 :   if(atoms.size()!=2)
+      76           0 :     error("Number of specified atoms should be 2");
+      77           0 :   bool nopbc=!pbc;
+      78           0 :   parseFlag("NOPBC",nopbc);
+      79           0 :   pbc=!nopbc;
+      80           0 :   checkRead();
+      81             : 
+      82           0 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+      83           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      84           0 :   else    log.printf("  without periodic boundary conditions\n");
+      85             : 
+      86           0 :   addValueWithDerivatives(); setNotPeriodic();
+      87             : 
+      88           0 :   requestAtoms(atoms);
+      89           0 : }
+      90             : 
+      91             : 
+      92             : // calculator
+      93           0 : void Template::calculate() {
+      94             : 
+      95           0 :   Vector distance;
+      96           0 :   if(pbc) {
+      97           0 :     distance=pbcDistance(getPosition(0),getPosition(1));
+      98             :   } else {
+      99           0 :     distance=delta(getPosition(0),getPosition(1));
+     100             :   }
+     101           0 :   const double value=distance.modulo();
+     102           0 :   const double invvalue=1.0/value;
+     103             : 
+     104           0 :   setAtomsDerivatives(0,-invvalue*distance);
+     105           0 :   setAtomsDerivatives(1,invvalue*distance);
+     106           0 :   setBoxDerivatives  (-invvalue*Tensor(distance,distance));
+     107           0 :   setValue           (value);
+     108           0 : }
+     109             : 
+     110             : }
+     111             : }
+     112             : 
+     113             : 
+     114             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func-sort-c.html b/coverage/colvar/Torsion.cpp.func-sort-c.html new file mode 100644 index 0000000000..9e27750c7d --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe1006createERKNS_13ActionOptionsE657
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE657
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE659
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_120TorsionRegisterMe100D2Ev4168
_ZN4PLMD6colvar7Torsion9calculateEv34591
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func.html b/coverage/colvar/Torsion.cpp.func.html new file mode 100644 index 0000000000..602d612476 --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe546createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar6Volume9calculateEv148
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func.html b/coverage/colvar/Volume.cpp.func.html new file mode 100644 index 0000000000..777d1a9021 --- /dev/null +++ b/coverage/colvar/Volume.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe546createERKNS_13ActionOptionsE9
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54C2Ev4168
_ZN4PLMD6colvar12_GLOBAL__N_118VolumeRegisterMe54D2Ev4168
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar6Volume9calculateEv148
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.gcov.html b/coverage/colvar/Volume.cpp.gcov.html new file mode 100644 index 0000000000..5b2b355280 --- /dev/null +++ b/coverage/colvar/Volume.cpp.gcov.html @@ -0,0 +1,161 @@ + + + + + + + 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-05-27 13:05: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       12522 : 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          11 : void Volume::registerKeywords( Keywords& keys ) {
+      67          11 :   Action::registerKeywords( keys );
+      68          11 :   ActionWithValue::registerKeywords( keys );
+      69          11 :   ActionAtomistic::registerKeywords( keys );
+      70          11 : }
+      71             : 
+      72             : 
+      73             : // calculator
+      74         148 : void Volume::calculate() {
+      75             : 
+      76         148 :   double v=getBox().determinant();
+      77         148 :   setBoxDerivatives(-v*Tensor::identity());
+      78         148 :   setValue         (v);
+      79         148 : }
+      80             : 
+      81             : }
+      82             : }
+      83             : 
+      84             : 
+      85             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index-sort-f.html b/coverage/colvar/index-sort-f.html new file mode 100644 index 0000000000..1b7332dd89 --- /dev/null +++ b/coverage/colvar/index-sort-f.html @@ -0,0 +1,393 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2098223294.0 %
Date:2024-05-27 13:05:14Functions:18422382.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %178 / 18262.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
PropertyMap.cpp +
92.6%92.6%
+
92.6 %25 / 2783.3 %5 / 6
PathMSD.cpp +
100.0%
+
100.0 %21 / 2183.3 %5 / 6
GHBFIX.cpp +
100.0%
+
100.0 %77 / 7785.7 %6 / 7
ERMSD.cpp +
98.1%98.1%
+
98.1 %51 / 5285.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
Torsion.cpp +
91.7%91.7%
+
91.7 %66 / 7285.7 %6 / 7
Angle.cpp +
97.4%97.4%
+
97.4 %38 / 3985.7 %6 / 7
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %60 / 6385.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
Distance.cpp +
100.0%
+
100.0 %82 / 8285.7 %6 / 7
Dipole.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
Gyration.cpp +
77.4%77.4%
+
77.4 %144 / 18685.7 %6 / 7
RMSD.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
Position.cpp +
100.0%
+
100.0 %66 / 6685.7 %6 / 7
DHEnergy.cpp +
94.1%94.1%
+
94.1 %32 / 3485.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
Dimer.cpp +
92.2%92.2%
+
92.2 %83 / 9087.5 %7 / 8
PCARMSD.cpp +
98.9%98.9%
+
98.9 %94 / 9587.5 %7 / 8
Puckering.cpp +
99.6%99.6%
+
99.6 %229 / 23088.9 %8 / 9
Energy.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
ExtraCV.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
EEFSolv.cpp +
94.3%94.3%
+
94.3 %230 / 24490.9 %10 / 11
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index-sort-l.html b/coverage/colvar/index-sort-l.html new file mode 100644 index 0000000000..708fbd7629 --- /dev/null +++ b/coverage/colvar/index-sort-l.html @@ -0,0 +1,393 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2098223294.0 %
Date:2024-05-27 13:05:14Functions:18422382.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
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
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
EEFSolv.cpp +
94.3%94.3%
+
94.3 %230 / 24490.9 %10 / 11
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 / 18262.5 %5 / 8
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 / 9587.5 %7 / 8
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
Energy.cpp +
100.0%
+
100.0 %26 / 2688.9 %8 / 9
ExtraCV.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.16
+
+ + + diff --git a/coverage/colvar/index.html b/coverage/colvar/index.html new file mode 100644 index 0000000000..2d54cb4971 --- /dev/null +++ b/coverage/colvar/index.html @@ -0,0 +1,393 @@ + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2098223294.0 %
Date:2024-05-27 13:05:14Functions:18422382.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 +
94.3%94.3%
+
94.3 %230 / 24490.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 %26 / 2688.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 / 9587.5 %7 / 8
PathMSD.cpp +
100.0%
+
100.0 %21 / 2183.3 %5 / 6
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %178 / 18262.5 %5 / 8
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-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.16
+
+ + + diff --git a/coverage/config/Config.inc.func-sort-c.html b/coverage/config/Config.inc.func-sort-c.html new file mode 100644 index 0000000000..32c2880c01 --- /dev/null +++ b/coverage/config/Config.inc.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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:106914.5 %
Date:2024-05-27 13:05:14Functions:42516.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getVersionGitB5cxx11Ev0
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev0
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config10getVersionB5cxx11Ev1
_ZN4PLMD6config14getVersionLongB5cxx11Ev1
_ZN4PLMD6config11plumed_rootEv294
_ZN4PLMD6config13getPlumedRootB5cxx11Ev294
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.func.html b/coverage/config/Config.inc.func.html new file mode 100644 index 0000000000..7d9d7dad0c --- /dev/null +++ b/coverage/config/Config.inc.func.html @@ -0,0 +1,172 @@ + + + + + + + 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:106914.5 %
Date:2024-05-27 13:05:14Functions:42516.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev1
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config11plumed_rootEv294
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getPlumedRootB5cxx11Ev294
_ZN4PLMD6config13getVersionGitB5cxx11Ev0
_ZN4PLMD6config14getVersionLongB5cxx11Ev1
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev0
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.gcov.html b/coverage/config/Config.inc.gcov.html new file mode 100644 index 0000000000..5694500fbb --- /dev/null +++ b/coverage/config/Config.inc.gcov.html @@ -0,0 +1,276 @@ + + + + + + + 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:106914.5 %
Date:2024-05-27 13:05:14Functions:42516.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           0 :   std::string escapeForSingleQuote(const std::string& input) {
+      36             :     std::string escaped;
+      37           0 :     for (char c : input) {
+      38           0 :         if (c == '\'') {
+      39             :             escaped += "'\\''";
+      40             :         } else {
+      41           0 :             escaped += c;
+      42             :         }
+      43             :     }
+      44           0 :     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         294 : 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           0 : bool isInstalled() {
+      61           0 :   return false;
+      62             : }
+      63             : 
+      64         294 : std::string getPlumedRoot() {
+      65         294 :   char *env = std::getenv("PLUMED_ROOT");
+      66             :   std::string ss;
+      67         294 :   if( env == NULL) {
+      68         294 :     ss=plumed_root();
+      69             :   } else {
+      70           0 :     ss=std::string( env );
+      71             :   }
+      72         294 :   return ss;
+      73             : }
+      74             : 
+      75           0 : std::string getPlumedHtmldir() {
+      76           0 :   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           0 : std::string getPlumedIncludedir() {
+      88           0 :   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           0 : std::string getPlumedProgramName() {
+     100           0 :   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           0 : std::string getEnvCommand() {
+     112           0 :   return "env PLUMED_ROOT="+escapeForSingleQuote(getPlumedRoot())+
+     113           0 :          " PLUMED_VERSION="+escapeForSingleQuote(getVersionLong())+
+     114           0 :          " PLUMED_HTMLDIR="+escapeForSingleQuote(getPlumedHtmldir())+
+     115           0 :          " PLUMED_INCLUDEDIR="+escapeForSingleQuote(getPlumedIncludedir())+
+     116           0 :          " PLUMED_PROGRAM_NAME="+escapeForSingleQuote(getPlumedProgramName())+
+     117           0 :          " PLUMED_IS_INSTALLED='"+(false?"yes":"no")+"'";
+     118             : }
+     119             : 
+     120           1 : std::string getVersion() {
+     121           1 :   return PLUMED_VERSION_SHORT;
+     122             : }
+     123             : 
+     124           1 : std::string getVersionLong() {
+     125           1 :   return PLUMED_VERSION_LONG;
+     126             : }
+     127             : 
+     128           0 : std::string getVersionGit() {
+     129           0 :   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           0 : std::string getCompilationDate() {
+     190           0 :   return __DATE__;
+     191             : }
+     192             : 
+     193           0 : std::string getCompilationTime() {
+     194           0 :   return __TIME__;
+     195             : }
+     196             : 
+     197             : 
+     198             : }
+     199             : }
+     200             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func-sort-c.html b/coverage/config/ConfigInstall.inc.func-sort-c.html new file mode 100644 index 0000000000..5f51b47079 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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:546978.3 %
Date:2024-05-27 13:05:14Functions:192576.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config10getVersionB5cxx11Ev4
_ZN4PLMD6config11getMakefileB5cxx11Ev31
_ZN4PLMD6config17plumed_includedirEv667
_ZN4PLMD6config13getEnvCommandB5cxx11Ev668
_ZN4PLMD6config14plumed_htmldirEv668
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev668
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev668
_ZN4PLMD6config19plumed_program_nameEv668
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev668
_ZN4PLMD6config13getVersionGitB5cxx11Ev1007
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1007
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1007
_ZN4PLMD6config12plumed_soextEv1215
_ZN4PLMD6config8getSoExtB5cxx11Ev1215
_ZN4PLMD6config14getVersionLongB5cxx11Ev1679
_ZN4PLMD6config11isInstalledEv2642
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3340
_ZN4PLMD6config11plumed_rootEv7217
_ZN4PLMD6config13getPlumedRootB5cxx11Ev7217
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func.html b/coverage/config/ConfigInstall.inc.func.html new file mode 100644 index 0000000000..acaa231163 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func.html @@ -0,0 +1,172 @@ + + + + + + + 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:546978.3 %
Date:2024-05-27 13:05:14Functions:192576.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev4
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev31
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv2642
_ZN4PLMD6config11plumed_rootEv7217
_ZN4PLMD6config12_GLOBAL__N_120escapeForSingleQuoteERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3340
_ZN4PLMD6config12plumed_soextEv1215
_ZN4PLMD6config13getEnvCommandB5cxx11Ev668
_ZN4PLMD6config13getPlumedRootB5cxx11Ev7217
_ZN4PLMD6config13getVersionGitB5cxx11Ev1007
_ZN4PLMD6config14getVersionLongB5cxx11Ev1679
_ZN4PLMD6config14plumed_htmldirEv668
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev668
_ZN4PLMD6config17plumed_includedirEv667
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1007
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1007
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev668
_ZN4PLMD6config19plumed_program_nameEv668
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev668
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev1215
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.gcov.html b/coverage/config/ConfigInstall.inc.gcov.html new file mode 100644 index 0000000000..8f90660a1d --- /dev/null +++ b/coverage/config/ConfigInstall.inc.gcov.html @@ -0,0 +1,276 @@ + + + + + + + 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:546978.3 %
Date:2024-05-27 13:05:14Functions:192576.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        3340 :   std::string escapeForSingleQuote(const std::string& input) {
+      36             :     std::string escaped;
+      37       66805 :     for (char c : input) {
+      38       63465 :         if (c == '\'') {
+      39             :             escaped += "'\\''";
+      40             :         } else {
+      41       63465 :             escaped += c;
+      42             :         }
+      43             :     }
+      44        6680 :     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        7217 : const char* plumed_root() {return "/home/runner/opt/lib/plumed";}
+      51        1215 : const char* plumed_soext() {return "so";}
+      52         668 : const char* plumed_htmldir() {return "/home/runner/opt/share/doc/plumed";}
+      53         667 : const char* plumed_includedir() {return "/home/runner/opt/include";}
+      54         668 : const char* plumed_program_name() {return "plumed";}
+      55             : 
+      56        1215 : std::string getSoExt() {
+      57        1215 :   return plumed_soext();
+      58             : }
+      59             : 
+      60        2642 : bool isInstalled() {
+      61        2642 :   return true;
+      62             : }
+      63             : 
+      64        7217 : std::string getPlumedRoot() {
+      65        7217 :   char *env = std::getenv("PLUMED_ROOT");
+      66             :   std::string ss;
+      67        7217 :   if( env == NULL) {
+      68        7217 :     ss=plumed_root();
+      69             :   } else {
+      70           0 :     ss=std::string( env );
+      71             :   }
+      72        7217 :   return ss;
+      73             : }
+      74             : 
+      75         668 : std::string getPlumedHtmldir() {
+      76         668 :   if(!isInstalled()) return getPlumedRoot();
+      77         668 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      78             :   std::string ss;
+      79         668 :   if( env == NULL) {
+      80         668 :     ss=plumed_htmldir();
+      81             :   } else {
+      82           0 :     ss=std::string( env );
+      83             :   }
+      84             :   return ss;
+      85             : }
+      86             : 
+      87         668 : std::string getPlumedIncludedir() {
+      88         668 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      89         668 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      90             :   std::string ss;
+      91         668 :   if( env == NULL) {
+      92         667 :     ss=plumed_includedir();
+      93             :   } else {
+      94           2 :     ss=std::string( env );
+      95             :   }
+      96             :   return ss;
+      97             : }
+      98             : 
+      99         668 : std::string getPlumedProgramName() {
+     100         668 :   if(!isInstalled()) return "plumed";
+     101         668 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+     102             :   std::string ss;
+     103         668 :   if( env == NULL) {
+     104         668 :     ss=plumed_program_name();
+     105             :   } else {
+     106           0 :     ss=std::string( env );
+     107             :   }
+     108             :   return ss;
+     109             : }
+     110             : 
+     111         668 : std::string getEnvCommand() {
+     112        1336 :   return "env PLUMED_ROOT="+escapeForSingleQuote(getPlumedRoot())+
+     113        2672 :          " PLUMED_VERSION="+escapeForSingleQuote(getVersionLong())+
+     114        2672 :          " PLUMED_HTMLDIR="+escapeForSingleQuote(getPlumedHtmldir())+
+     115        2672 :          " PLUMED_INCLUDEDIR="+escapeForSingleQuote(getPlumedIncludedir())+
+     116        2672 :          " PLUMED_PROGRAM_NAME="+escapeForSingleQuote(getPlumedProgramName())+
+     117        2004 :          " PLUMED_IS_INSTALLED='"+(true?"yes":"no")+"'";
+     118             : }
+     119             : 
+     120           4 : std::string getVersion() {
+     121           4 :   return PLUMED_VERSION_SHORT;
+     122             : }
+     123             : 
+     124        1679 : std::string getVersionLong() {
+     125        1679 :   return PLUMED_VERSION_LONG;
+     126             : }
+     127             : 
+     128        1007 : std::string getVersionGit() {
+     129        1007 :   return PLUMED_VERSION_GIT;
+     130             : }
+     131             : 
+     132          31 : std::string getMakefile() {
+     133             :   static const unsigned char confu [] = {
+     134             : #include "Makefile.conf.xxd"
+     135             :     , 0x00
+     136             :   };
+     137             :   auto conf=(char*)confu;
+     138          31 :   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        1007 : std::string getCompilationDate() {
+     190        1007 :   return __DATE__;
+     191             : }
+     192             : 
+     193        1007 : std::string getCompilationTime() {
+     194        1007 :   return __TIME__;
+     195             : }
+     196             : 
+     197             : 
+     198             : }
+     199             : }
+     200             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index-sort-f.html b/coverage/config/index-sort-f.html new file mode 100644 index 0000000000..567a194229 --- /dev/null +++ b/coverage/config/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6413846.4 %
Date:2024-05-27 13:05:14Functions:235046.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
14.5%14.5%
+
14.5 %10 / 6916.0 %4 / 25
ConfigInstall.inc +
78.3%78.3%
+
78.3 %54 / 6976.0 %19 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index-sort-l.html b/coverage/config/index-sort-l.html new file mode 100644 index 0000000000..9e907d8298 --- /dev/null +++ b/coverage/config/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6413846.4 %
Date:2024-05-27 13:05:14Functions:235046.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
14.5%14.5%
+
14.5 %10 / 6916.0 %4 / 25
ConfigInstall.inc +
78.3%78.3%
+
78.3 %54 / 6976.0 %19 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index.html b/coverage/config/index.html new file mode 100644 index 0000000000..1a603282e0 --- /dev/null +++ b/coverage/config/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:6413846.4 %
Date:2024-05-27 13:05:14Functions:235046.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
14.5%14.5%
+
14.5 %10 / 6916.0 %4 / 25
ConfigInstall.inc +
78.3%78.3%
+
78.3 %54 / 6976.0 %19 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func-sort-c.html b/coverage/core/Action.cpp.func-sort-c.html new file mode 100644 index 0000000000..f0fc126dca --- /dev/null +++ b/coverage/core/Action.cpp.func-sort-c.html @@ -0,0 +1,192 @@ + + + + + + + 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:12215479.2 %
Date:2024-05-27 13:05:14Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6ActionD0Ev0
_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
_ZNK4PLMD6Action6getCPTEv1095
_ZN4PLMD6ActionD2Ev14301
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE14302
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE14302
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE14304
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE14881
_ZNK4PLMD6Action11getTimeStepEv16292
_ZN4PLMD6Action6fflushEv18057
_ZN4PLMD6Action9checkReadEv27861
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb40900
_ZN4PLMD6Action17clearDependenciesEv189162
_ZN4PLMD6Action7prepareEv325089
_ZN4PLMD6Action13addDependencyEPS0_1084028
_ZNK4PLMD6Action11checkUpdateEv1642986
_ZNK4PLMD6Action7getTimeEv2991243
_ZN4PLMD6Action8activateEv3214026
_ZNK4PLMD6Action7getStepEv4557159
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func.html b/coverage/core/Action.cpp.func.html new file mode 100644 index 0000000000..c38e89de73 --- /dev/null +++ b/coverage/core/Action.cpp.func.html @@ -0,0 +1,192 @@ + + + + + + + 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:12215479.2 %
Date:2024-05-27 13:05:14Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE14302
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE14304
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action13addDependencyEPS0_1084028
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE14881
_ZN4PLMD6Action17clearDependenciesEv189162
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6Action5fopenEPKcS2_73
_ZN4PLMD6Action6fcloseEP8_IO_FILE91
_ZN4PLMD6Action6fflushEv18057
_ZN4PLMD6Action7prepareEv325089
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE129
_ZN4PLMD6Action8activateEv3214026
_ZN4PLMD6Action9checkReadEv27861
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb40900
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE267
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE14302
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6ActionD2Ev14301
_ZNK4PLMD6Action11checkUpdateEv1642986
_ZNK4PLMD6Action11getTimeStepEv16292
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action7getStepEv4557159
_ZNK4PLMD6Action7getTimeEv2991243
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.gcov.html b/coverage/core/Action.cpp.gcov.html new file mode 100644 index 0000000000..b52321807b --- /dev/null +++ b/coverage/core/Action.cpp.gcov.html @@ -0,0 +1,355 @@ + + + + + + + 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:12215479.2 %
Date:2024-05-27 13:05: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 "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       14304 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
+      36       14304 :   plumed(p),
+      37       14304 :   line(l),
+      38       14304 :   keys(emptyKeys)
+      39             : {
+      40       14304 : }
+      41             : 
+      42       14302 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
+      43       14302 :   plumed(ao.plumed),
+      44       14302 :   line(ao.line),
+      45       14302 :   keys(keys)
+      46             : {
+      47       14302 : }
+      48             : 
+      49       14881 : void Action::registerKeywords( Keywords& keys ) {
+      50       14881 :   plumed_assert( keys.size()==0 );
+      51       29762 :   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       29762 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
+      53       29762 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
+      54       29762 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
+      55       14881 : }
+      56             : 
+      57       14302 : Action::Action(const ActionOptions&ao):
+      58       14302 :   name(ao.line[0]),
+      59       14302 :   line(ao.line),
+      60       14302 :   update_from(std::numeric_limits<double>::max()),
+      61       14302 :   update_until(std::numeric_limits<double>::max()),
+      62       14302 :   active(false),
+      63       14302 :   restart(ao.plumed.getRestart()),
+      64       14302 :   doCheckPoint(ao.plumed.getCPT()),
+      65       14302 :   plumed(ao.plumed),
+      66       14302 :   log(plumed.getLog()),
+      67       14302 :   comm(plumed.comm),
+      68       14302 :   multi_sim_comm(plumed.multi_sim_comm),
+      69       14302 :   keywords(ao.keys)
+      70             : {
+      71             :   line.erase(line.begin());
+      72       14302 :   log.printf("Action %s\n",name.c_str());
+      73             : 
+      74       14302 :   if(comm.Get_rank()==0) {
+      75        7867 :     replica_index=multi_sim_comm.Get_rank();
+      76             :   }
+      77       14302 :   comm.Bcast(replica_index,0);
+      78             : 
+      79       42715 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
+      80             : 
+      81       14302 :   if(label.length()==0) {
+      82        2421 :     std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      83        4842 :     label="@"+s;
+      84             :   }
+      85       14302 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
+      86       14302 :   log.printf("  with label %s\n",label.c_str());
+      87       30365 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
+      88       14302 :   if(update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
+      89       30365 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
+      90       14302 :   if(update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
+      91       28604 :   if ( keywords.exists("RESTART") ) {
+      92        1821 :     std::string srestart="AUTO";
+      93        1820 :     parse("RESTART",srestart);
+      94        1820 :     if( plumed.parseOnlyMode() ) restart=false;
+      95        1820 :     else if(srestart=="YES") restart=true;
+      96        1738 :     else if(srestart=="NO")  restart=false;
+      97        1716 :     else if(srestart=="AUTO") {
+      98             :       // do nothing, this is the default
+      99           2 :     } else error("RESTART should be either YES, NO, or AUTO");
+     100             :   }
+     101       14302 : }
+     102             : 
+     103       28602 : Action::~Action() {
+     104       14301 :   if(files.size()!=0) {
+     105           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
+     106             :   }
+     107       28602 : }
+     108             : 
+     109          73 : FILE* Action::fopen(const char *path, const char *mode) {
+     110             :   bool write(false);
+     111         146 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
+     112             :   FILE* fp;
+     113          73 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
+     114          73 :   else      fp=plumed.fopen(path,mode);
+     115          73 :   files.insert(fp);
+     116          73 :   return fp;
+     117             : }
+     118             : 
+     119          91 : int Action::fclose(FILE*fp) {
+     120             :   files.erase(fp);
+     121          91 :   return plumed.fclose(fp);
+     122             : }
+     123             : 
+     124       18057 : void Action::fflush() {
+     125       18057 :   for(const auto & p : files) {
+     126           0 :     std::fflush(p);
+     127             :   }
+     128       18057 : }
+     129             : 
+     130          33 : std::string Action::getKeyword(const std::string& key) {
+     131             :   // Check keyword has been registered
+     132          33 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     133             : 
+     134             :   std::string outkey;
+     135          33 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
+     136             : 
+     137           0 :   if( keywords.style(key,"compulsory") ) {
+     138           0 :     if( keywords.getDefaultValue(key,outkey) ) {
+     139           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
+     140           0 :       return key + "=" +  outkey;
+     141             :     } else {
+     142           0 :       error("keyword " + key + " is compulsory for this action");
+     143             :     }
+     144             :   }
+     145           0 :   return "";
+     146             : }
+     147             : 
+     148       40900 : void Action::parseFlag(const std::string&key,bool & t) {
+     149             :   // Check keyword has been registered
+     150       40900 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     151             :   // Check keyword is a flag
+     152       81800 :   if(!keywords.style(key,"nohtml")) {
+     153       79255 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
+     154             :   }
+     155             : 
+     156             :   // Read in the flag otherwise get the default value from the keywords object
+     157       40900 :   if(!Tools::parseFlag(line,key,t)) {
+     158       81530 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
+     159        2644 :       t=false;
+     160       36799 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     161           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
+     162           0 :       plumed_error();
+     163             :     }
+     164             :   }
+     165       40900 : }
+     166             : 
+     167     1084028 : void Action::addDependency(Action*action) {
+     168     1084028 :   after.push_back(action);
+     169     1084028 : }
+     170             : 
+     171     3214026 : void Action::activate() {
+     172             : // preparation step is called only the first time an Action is activated.
+     173             : // since it could change its dependences (e.g. in an ActionAtomistic which is
+     174             : // accessing to a virtual atom), this is done just before dependencies are
+     175             : // activated
+     176     3214026 :   if(!active) {
+     177     1650947 :     this->unlockRequests();
+     178     1650947 :     prepare();
+     179     1650947 :     this->lockRequests();
+     180             :   } else return;
+     181     3586596 :   for(const auto & p : after) p->activate();
+     182     1650947 :   active=true;
+     183             : }
+     184             : 
+     185         267 : void Action::setOption(const std::string &s) {
+     186             : // This overloads the action and activate some options
+     187         267 :   options.insert(s);
+     188         448 :   for(const auto & p : after) p->setOption(s);
+     189         267 : }
+     190             : 
+     191           0 : void Action::clearOptions() {
+     192             : // This overloads the action and activate some options
+     193             :   options.clear();
+     194           0 : }
+     195             : 
+     196             : 
+     197      189162 : void Action::clearDependencies() {
+     198             :   after.clear();
+     199      189162 : }
+     200             : 
+     201       27861 : void Action::checkRead() {
+     202       27861 :   if(!line.empty()) {
+     203           0 :     std::string msg="cannot understand the following words from the input line : ";
+     204           0 :     for(unsigned i=0; i<line.size(); i++) {
+     205           0 :       if(i>0) msg = msg + ", ";
+     206           0 :       msg = msg + line[i];
+     207             :     }
+     208           0 :     error(msg);
+     209             :   }
+     210       27861 : }
+     211             : 
+     212     4557159 : long long int Action::getStep()const {
+     213     4557159 :   return plumed.getStep();
+     214             : }
+     215             : 
+     216     2991243 : double Action::getTime()const {
+     217     2991243 :   return plumed.getAtoms().getTimeStep()*getStep();
+     218             : }
+     219             : 
+     220       16292 : double Action::getTimeStep()const {
+     221       16292 :   return plumed.getAtoms().getTimeStep();
+     222             : }
+     223             : 
+     224             : 
+     225             : 
+     226           0 : void Action::exit(int c) {
+     227           0 :   plumed.exit(c);
+     228           0 : }
+     229             : 
+     230           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
+     231           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");
+     232             : }
+     233             : 
+     234      325089 : void Action::prepare() {
+     235      325089 :   return;
+     236             : }
+     237             : 
+     238          30 : [[noreturn]] void Action::error( const std::string & msg ) const {
+     239          30 :   log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
+     240          90 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
+     241             : }
+     242             : 
+     243         129 : void Action::warning( const std::string & msg ) {
+     244         129 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
+     245         129 : }
+     246             : 
+     247           0 : void Action::calculateFromPDB( const PDB& pdb ) {
+     248           0 :   activate();
+     249           0 :   for(const auto & p : after) {
+     250           0 :     ActionWithValue*av=dynamic_cast<ActionWithValue*>(p);
+     251           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
+     252           0 :     p->readAtomsFromPDB( pdb );
+     253           0 :     p->calculate();
+     254             :   }
+     255           0 :   readAtomsFromPDB( pdb );
+     256           0 :   calculate();
+     257           0 : }
+     258             : 
+     259       28109 : bool Action::getExchangeStep()const {
+     260       28109 :   return plumed.getExchangeStep();
+     261             : }
+     262             : 
+     263          40 : std::string Action::cite(const std::string&s) {
+     264          40 :   return plumed.cite(s);
+     265             : }
+     266             : 
+     267             : /// Check if action should be updated.
+     268     1642986 : bool Action::checkUpdate()const {
+     269     1642986 :   double t=getTime();
+     270     1642986 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
+     271         510 :   else return false;
+     272             : }
+     273             : 
+     274        1095 : bool Action::getCPT()const {
+     275        1095 :   return plumed.getCPT();
+     276             : }
+     277             : 
+     278             : }
+     279             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func-sort-c.html b/coverage/core/Action.h.func-sort-c.html new file mode 100644 index 0000000000..a48bcd84e6 --- /dev/null +++ b/coverage/core/Action.h.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + 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:697394.5 %
Date:2024-05-27 13:05:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE520
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1164
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2144
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_3628
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3647
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5296
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11179
_ZN4PLMD6Action12runFinalJobsEv13508
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE18608
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_22509
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_29674
_ZNK4PLMD6Action25checkNumericalDerivativesEv260031
_ZN4PLMD6Action6updateEv412363
_ZN4PLMD6Action12lockRequestsEv945438
_ZN4PLMD6Action14unlockRequestsEv945438
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1404474
_ZNK4PLMD6Action19checkNeedsGradientsEv1642172
_ZN4PLMD6Action12beforeUpdateEv1815324
_ZN4PLMD6Action10deactivateEv1833169
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func.html b/coverage/core/Action.h.func.html new file mode 100644 index 0000000000..31c18fb73d --- /dev/null +++ b/coverage/core/Action.h.func.html @@ -0,0 +1,176 @@ + + + + + + + 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:697394.5 %
Date:2024-05-27 13:05:14Functions:252696.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10deactivateEv1833169
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE18608
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11179
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE520
_ZN4PLMD6Action12beforeUpdateEv1815324
_ZN4PLMD6Action12lockRequestsEv945438
_ZN4PLMD6Action12runFinalJobsEv13508
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_3628
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1164
_ZN4PLMD6Action14unlockRequestsEv945438
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2144
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_29674
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_22509
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_5296
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3647
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action6updateEv412363
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1404474
_ZNK4PLMD6Action19checkNeedsGradientsEv1642172
_ZNK4PLMD6Action25checkNumericalDerivativesEv260031
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.gcov.html b/coverage/core/Action.h.gcov.html new file mode 100644 index 0000000000..657e16f1c5 --- /dev/null +++ b/coverage/core/Action.h.gcov.html @@ -0,0 +1,506 @@ + + + + + + + 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:697394.5 %
Date:2024-05-27 13:05: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       28606 : 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             : /// The set of default arguments that we are using
+     103             :   std::string defaults;
+     104             : public:
+     105             : 
+     106             : /// Reference to main plumed object
+     107             :   PlumedMain& plumed;
+     108             : 
+     109             : /// Reference to the log stream
+     110             :   Log& log;
+     111             : 
+     112             : /// Specify that this Action depends on another one
+     113             :   void addDependency(Action*);
+     114             : 
+     115             : /// Clear the dependence list for this Action
+     116             :   void clearDependencies();
+     117             : 
+     118             : /// Return the present timestep
+     119             :   long long int getStep()const;
+     120             : 
+     121             : /// Return the present time
+     122             :   double getTime()const;
+     123             : 
+     124             : /// Return the timestep
+     125             :   double getTimeStep()const;
+     126             : 
+     127             : /// Return true if we are doing a restart
+     128             :   bool getRestart()const;
+     129             : 
+     130             : /// Return true if we are doing at a checkpoint step
+     131             :   bool getCPT()const;
+     132             : 
+     133             : /// Just read one of the keywords and return the whole thing as a string
+     134             :   std::string getKeyword(const std::string& key);
+     135             : 
+     136             : /// Parse one keyword as generic type
+     137             :   template<class T>
+     138             :   void parse(const std::string&key,T&t);
+     139             : 
+     140             : /// Parse one numbered keyword as generic type
+     141             :   template<class T>
+     142             :   bool parseNumbered(const std::string&key, const int no, T&t);
+     143             : 
+     144             : /// Parse one keyword as std::vector
+     145             :   template<class T>
+     146             :   void parseVector(const std::string&key,std::vector<T>&t);
+     147             : 
+     148             : /// Parse a vector with a number
+     149             :   template<class T>
+     150             :   bool parseNumberedVector(const std::string& key, const int no, std::vector<T>&t);
+     151             : 
+     152             : /// Parse one keyword as boolean flag
+     153             :   void parseFlag(const std::string&key,bool&t);
+     154             : 
+     155             : /// Crash calculation and print documentation
+     156             :   [[noreturn]] void error( const std::string & msg ) const;
+     157             : 
+     158             : /// Issue a warning
+     159             :   void warning( const std::string & msg );
+     160             : 
+     161             : /// Exit with error code c
+     162             :   void exit(int c=0);
+     163             : 
+     164             : ///
+     165             :   std::set<FILE*> files;
+     166             : 
+     167             : public:
+     168             : /// Standard constructor from ActionOptions
+     169             :   explicit Action(const ActionOptions&);
+     170             : /// Destructor
+     171             :   virtual ~Action();
+     172             : private:
+     173             : /// Copy constructor is deleted
+     174             :   Action(const Action&a) = delete;
+     175             : /// Assignment operator is deleted
+     176             :   Action& operator=(const Action&a) = delete;
+     177             :   int replica_index;
+     178             : public:
+     179             : /// Check if Action was properly read.
+     180             : /// This checks if Action::line is empty. It must be called after
+     181             : /// a final Action has been initialized
+     182             :   void checkRead();
+     183             : 
+     184             :   Communicator& comm;
+     185             :   Communicator& multi_sim_comm;
+     186             : 
+     187             :   const Keywords& keywords;
+     188             : /// Prepare an Action for calculation
+     189             : /// This can be used by Action if they need some special preparation
+     190             : /// before calculation. Typical case is for collective variables
+     191             : /// which would like to change their list of requested atoms.
+     192             : /// By default (if not overridden) does nothing.
+     193             :   virtual void prepare();
+     194             : 
+     195             : /// Register all the relevant keywords for the action
+     196             :   static void registerKeywords( Keywords& keys );
+     197             : 
+     198      945438 :   virtual void lockRequests() {}
+     199      945438 :   virtual void unlockRequests() {}
+     200             : 
+     201             : /// Calculate an Action.
+     202             : /// This method is called one or more times per step.
+     203             : /// The set of all Actions is calculated in forward order.
+     204             :   virtual void calculate()=0;
+     205             : 
+     206             : /// Apply an Action.
+     207             : /// This method is called one time per step.
+     208             : /// The set of all Actions is applied in backward order.
+     209             :   virtual void apply()=0;
+     210             : 
+     211             : /// Before Update.
+     212             : /// This is a special method that is called just
+     213             : /// before the update() method. It can be used by
+     214             : /// actions that want to do something irrespectively
+     215             : /// of the fact that update() is active or not.
+     216             : /// In other words, this is *always* called, even when action
+     217             : /// is not active.
+     218     1815324 :   virtual void beforeUpdate() {}
+     219             : 
+     220             : /// Update.
+     221             : /// This method is called one time per step.
+     222             : /// The set of all Actions is updated in forward order.
+     223      412363 :   virtual void update() {}
+     224             : 
+     225             : /// RunFinalJobs
+     226             : /// This method is called once at the very end of the calculation.
+     227             : /// The set of all Actions in run for the final time in forward order.
+     228       13508 :   virtual void runFinalJobs() {}
+     229             : 
+     230             : /// Tell to the Action to flush open files
+     231             :   void fflush();
+     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      260031 :   virtual bool checkNumericalDerivatives()const {return false;}
+     261             : 
+     262             : /// Check if the action needs gradient
+     263     1642172 :   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             : /// Get the defaults
+     292             :   std::string getDefaultString() const ;
+     293             : };
+     294             : 
+     295             : /////////////////////
+     296             : // FAST INLINE METHODS
+     297             : 
+     298             : inline
+     299             : const std::string & Action::getLabel()const {
+     300    60597121 :   return label;
+     301             : }
+     302             : 
+     303             : inline
+     304             : const std::string & Action::getName()const {
+     305        7743 :   return name;
+     306             : }
+     307             : 
+     308             : template<class T>
+     309       61251 : void Action::parse(const std::string&key,T&t) {
+     310             :   // Check keyword has been registered
+     311       61251 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     312             : 
+     313             :   // Now try to read the keyword
+     314             :   std::string def;
+     315       61251 :   bool present=Tools::findKeyword(line,key);
+     316       61251 :   bool found=Tools::parse(line,key,t,replica_index);
+     317       61254 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     318             : 
+     319             :   // If it isn't read and it is compulsory see if a default value was specified
+     320      140268 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     321        8134 :     if( keywords.getDefaultValue(key,def) ) {
+     322        2851 :       if( def.length()==0 || !Tools::convertNoexcept(def,t) ) {
+     323           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     324             :       }
+     325        5702 :       defaults += " " + key + "=" + def;
+     326       10566 :     } else if( keywords.style(key,"compulsory") ) {
+     327           3 :       error("keyword " + key + " is compulsory for this action");
+     328             :     }
+     329             :   }
+     330       61248 : }
+     331             : 
+     332             : template<class T>
+     333        4792 : bool Action::parseNumbered(const std::string&key, const int no, T&t) {
+     334             :   // Check keyword has been registered
+     335        4792 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     336        4792 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     337             : 
+     338             :   // Now try to read the keyword
+     339        4792 :   std::string num; Tools::convert(no,num);
+     340        9584 :   return Tools::parse(line,key+num,t,replica_index);
+     341             : }
+     342             : 
+     343             : template<class T>
+     344       30338 : void Action::parseVector(const std::string&key,std::vector<T>&t) {
+     345             :   // Check keyword has been registered
+     346       30338 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     347       30338 :   unsigned size=t.size(); bool skipcheck=false;
+     348       30338 :   if(size==0) skipcheck=true;
+     349             : 
+     350             :   // Now try to read the keyword
+     351             :   std::string def; T val;
+     352       30338 :   bool present=Tools::findKeyword(line,key);
+     353       30338 :   bool found=Tools::parseVector(line,key,t,replica_index);
+     354       30339 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     355             : 
+     356             :   // Check vectors size is correct (not if this is atoms or ARG)
+     357       60674 :   if( !keywords.style(key,"atoms") && found ) {
+     358             : //     bool skipcheck=false;
+     359             : //     if( keywords.style(key,"compulsory") ){ keywords.getDefaultValue(key,def); skipcheck=(def=="nosize"); }
+     360       13567 :     if( !skipcheck && t.size()!=size ) error("vector read in for keyword " + key + " has the wrong size");
+     361             :   }
+     362             : 
+     363             :   // If it isn't read and it is compulsory see if a default value was specified
+     364       43628 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     365         980 :     if( keywords.getDefaultValue(key,def) ) {
+     366         878 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     367           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     368             :       } else {
+     369         878 :         if(t.size()>0) {
+     370        1586 :           for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     371        1586 :           defaults += " " + key + "=" + def; for(unsigned i=1; i<t.size(); ++i) defaults += "," + def;
+     372         556 :         } else { t.push_back(val); defaults += " " + key + "=" + def; }
+     373             :       }
+     374         204 :     } else if( keywords.style(key,"compulsory") ) {
+     375           4 :       error("keyword " + key + " is compulsory for this action");
+     376             :     }
+     377       29354 :   } else if ( !found ) {
+     378        6055 :     t.resize(0);
+     379             :   }
+     380       30334 : }
+     381             : 
+     382             : template<class T>
+     383        3503 : bool Action::parseNumberedVector(const std::string&key, const int no, std::vector<T>&t) {
+     384        3503 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     385        3503 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     386             : 
+     387        3503 :   unsigned size=t.size(); bool skipcheck=false;
+     388        3503 :   if(size==0) skipcheck=true;
+     389        3503 :   std::string num; Tools::convert(no,num);
+     390        3503 :   bool present=Tools::findKeyword(line,key);
+     391        3503 :   bool found=Tools::parseVector(line,key+num,t,replica_index);
+     392        3503 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     393             : 
+     394        7006 :   if(  keywords.style(key,"compulsory") ) {
+     395          90 :     if (!skipcheck && found && t.size()!=size ) error("vector read in for keyword " + key + num + " has the wrong size");
+     396        3413 :   } else if ( !found ) {
+     397        1039 :     t.resize(0);
+     398             :   }
+     399        3503 :   return found;
+     400             : }
+     401             : 
+     402             : inline
+     403     1833169 : void Action::deactivate() {
+     404             :   options.clear();
+     405     1833169 :   active=false;
+     406     1833169 : }
+     407             : 
+     408             : inline
+     409             : bool Action::isActive()const {
+     410     7867463 :   return active;
+     411             : }
+     412             : 
+     413             : inline
+     414     1404474 : bool Action::isOptionOn(const std::string &s)const {
+     415     1404474 :   return options.count(s);
+     416             : }
+     417             : 
+     418             : inline
+     419             : bool Action::getRestart()const {
+     420        3651 :   return restart;
+     421             : }
+     422             : 
+     423             : inline
+     424             : std::string Action::getDefaultString() const {
+     425           0 :   return defaults;
+     426             : }
+     427             : 
+     428             : }
+     429             : #endif
+     430             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func-sort-c.html b/coverage/core/ActionAnyorder.cpp.func-sort-c.html new file mode 100644 index 0000000000..9f5cbd9b90 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE105
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func.html b/coverage/core/ActionAnyorder.cpp.func.html new file mode 100644 index 0000000000..d102ec08b4 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE105
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.gcov.html b/coverage/core/ActionAnyorder.cpp.gcov.html new file mode 100644 index 0000000000..f91d15e108 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.gcov.html @@ -0,0 +1,114 @@ + + + + + + + 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-05-27 13:05: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         105 : ActionAnyorder::ActionAnyorder(const ActionOptions&ao):
+      30         105 :   Action(ao)
+      31             : {
+      32         105 : }
+      33             : 
+      34           0 : void ActionAnyorder::registerKeywords( Keywords& keys ) {
+      35           0 :   Action::registerKeywords(keys);
+      36           0 : }
+      37             : 
+      38             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func-sort-c.html b/coverage/core/ActionAnyorder.h.func-sort-c.html new file mode 100644 index 0000000000..09a735c6f5 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func.html b/coverage/core/ActionAnyorder.h.func.html new file mode 100644 index 0000000000..e0e40615c6 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.gcov.html b/coverage/core/ActionAnyorder.h.gcov.html new file mode 100644 index 0000000000..65ddc8f4c9 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.gcov.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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          87 : class ActionAnyorder :
+      34             :   public virtual Action {
+      35             : public:
+      36             : /// Constructor
+      37             :   explicit ActionAnyorder(const ActionOptions&ao);
+      38             : /// Creator of keywords
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Do nothing.
+      41           0 :   void calculate() override {}
+      42             : /// Do nothing.
+      43           0 :   void apply() override {}
+      44             : };
+      45             : 
+      46             : }
+      47             : 
+      48             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func-sort-c.html b/coverage/core/ActionAtomistic.cpp.func-sort-c.html new file mode 100644 index 0000000000..1c856d1b10 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + 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:17118691.9 %
Date:2024-05-27 13:05: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_13ActionOptionsE10255
_ZN4PLMD15ActionAtomisticD2Ev10255
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb10274
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE10524
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE11421
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE11774
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE13759
_ZN4PLMD15ActionAtomistic17updateUniqueLocalEv19923
_ZN4PLMD15ActionAtomistic9makeWholeEv106316
_ZN4PLMD15ActionAtomistic11applyForcesEv166117
_ZN4PLMD15ActionAtomistic13retrieveAtomsEv166580
_ZN4PLMD15ActionAtomistic17clearOutputForcesEv166580
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220663
_ZNK4PLMD15ActionAtomistic11pbcDistanceERKNS_13VectorGenericILj3EEES4_182208717
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func.html b/coverage/core/ActionAtomistic.cpp.func.html new file mode 100644 index 0000000000..55d8f97385 --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func.html @@ -0,0 +1,160 @@ + + + + + + + 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:17118691.9 %
Date:2024-05-27 13:05:14Functions:172277.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv160
_ZNK4PLMD15ActionAtomistic9getChargeEi63884
_ZN4PLMD15ActionAtomistic12lockRequestsEv152576
_ZN4PLMD15ActionAtomistic14unlockRequestsEv152576
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func.html b/coverage/core/ActionAtomistic.h.func.html new file mode 100644 index 0000000000..ce9d1d0a48 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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:3434100.0 %
Date:2024-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2637
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2704
_ZNK4PLMD11ActionPilot9getStrideEv81233
_ZNK4PLMD11ActionPilot6onStepEv1448395
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.func.html b/coverage/core/ActionPilot.cpp.func.html new file mode 100644 index 0000000000..2479f7d7d8 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2704
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2637
_ZNK4PLMD11ActionPilot6onStepEv1448395
_ZNK4PLMD11ActionPilot9getStrideEv81233
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.gcov.html b/coverage/core/ActionPilot.cpp.gcov.html new file mode 100644 index 0000000000..1f4b20bef5 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.gcov.html @@ -0,0 +1,131 @@ + + + + + + + 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-05-27 13:05: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        2704 : void ActionPilot::registerKeywords(Keywords& keys) {}
+      27             : 
+      28        2637 : ActionPilot::ActionPilot(const ActionOptions&ao):
+      29             :   Action(ao),
+      30        2637 :   stride(1)
+      31             : {
+      32        5274 :   if( keywords.exists("STRIDE") ) {
+      33        2579 :     parse("STRIDE",stride);
+      34        5158 :     if( !keywords.style("STRIDE","hidden") ) log.printf("  with stride %d\n",stride);
+      35             :   } else {
+      36          58 :     stride=0;
+      37             :   }
+      38        2637 : }
+      39             : 
+      40     1448395 : bool ActionPilot::onStep()const {
+      41     1448395 :   if( stride>0 ) return getStep()%stride==0;
+      42             :   return false;
+      43             : }
+      44             : 
+      45       81233 : int ActionPilot::getStride()const {
+      46       81233 :   return stride;
+      47             : }
+      48             : 
+      49          17 : void ActionPilot::setStride(const int& n) {
+      50          17 :   stride=n;
+      51          17 : }
+      52             : 
+      53             : }
+      54             : 
+      55             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.func-sort-c.html b/coverage/core/ActionPilot.h.func-sort-c.html new file mode 100644 index 0000000000..382ee00f81 --- /dev/null +++ b/coverage/core/ActionPilot.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.func.html b/coverage/core/ActionPilot.h.func.html new file mode 100644 index 0000000000..cd96c48388 --- /dev/null +++ b/coverage/core/ActionPilot.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.gcov.html b/coverage/core/ActionPilot.h.gcov.html new file mode 100644 index 0000000000..2372c6c32d --- /dev/null +++ b/coverage/core/ActionPilot.h.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-05-27 13:05: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        1523 : class ActionPilot:
+      40             :   public virtual Action
+      41             : {
+      42             :   int stride; // multiple time step
+      43             : public:
+      44             :   explicit ActionPilot(const ActionOptions&);
+      45             : /// Create the keywords for actionPilot
+      46             :   static void registerKeywords(Keywords& keys);
+      47             : /// Check if the action is active on this step
+      48             :   virtual bool onStep()const;
+      49             : /// Set the value of the stride
+      50             :   void setStride( const int& n );
+      51             : /// Get the stride
+      52             :   int getStride()const;
+      53             : };
+      54             : 
+      55             : }
+      56             : 
+      57             : #endif
+      58             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func-sort-c.html b/coverage/core/ActionRegister.cpp.func-sort-c.html new file mode 100644 index 0000000000..06e03b0405 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_293
_ZN4PLMDlsERSoRKNS_14ActionRegisterE294
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev296
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE584
_ZN4PLMD14ActionRegisterD2Ev4168
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE14304
_ZN4PLMD14ActionRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15183
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE1217057
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE1217057
_ZN4PLMD14actionRegisterEv2449301
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func.html b/coverage/core/ActionRegister.cpp.func.html new file mode 100644 index 0000000000..39df19d01b --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE584
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_293
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE1217057
_ZN4PLMD14ActionRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15183
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE14304
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE1217057
_ZN4PLMD14ActionRegisterD2Ev4168
_ZN4PLMD14actionRegisterEv2449301
_ZN4PLMDlsERSoRKNS_14ActionRegisterE294
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev296
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.gcov.html b/coverage/core/ActionRegister.cpp.gcov.html new file mode 100644 index 0000000000..0e9ab137a3 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.gcov.html @@ -0,0 +1,218 @@ + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-05-27 13:05:14Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionRegister.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "Action.h"
+      25             : #include <algorithm>
+      26             : #include <iostream>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30        4168 : ActionRegister::~ActionRegister() {
+      31        4168 :   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        4168 : }
+      37             : 
+      38     2449301 : ActionRegister& actionRegister() {
+      39     2449301 :   static ActionRegister ans;
+      40     2449301 :   return ans;
+      41             : }
+      42             : 
+      43     1217057 : void ActionRegister::remove(creator_pointer f) {
+      44   103699898 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      45   103699898 :     if((*p).second==f) {
+      46     1217057 :       m.erase(p); break;
+      47             :     }
+      48             :   }
+      49     1217057 : }
+      50             : 
+      51     1217057 : 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     6160308 :   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     1217057 :     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     1217057 :     mk.insert(std::pair<std::string,keywords_pointer>(key,k));
+      63             :   };
+      64     1217057 : }
+      65             : 
+      66       15183 : bool ActionRegister::check(const std::string & key) {
+      67       15179 :   if(m.count(key)>0 && mk.count(key)>0) return true;
+      68             :   return false;
+      69             : }
+      70             : 
+      71       14304 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
+      72       14304 :   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       14304 :   std::unique_ptr<Action> action;
+      80       14304 :   if( check(ao.line[0]) ) {
+      81       14302 :     Keywords keys; mk[ao.line[0]](keys);
+      82       14302 :     ActionOptions nao( ao,keys );
+      83       28566 :     action=m[ao.line[0]](nao);
+      84       14302 :   }
+      85             :   return action;
+      86       14304 : }
+      87             : 
+      88         584 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
+      89         584 :   if ( check(action) ) {  mk[action](keys); return true; }
+      90             :   return false;
+      91             : }
+      92             : 
+      93         293 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
+      94         293 :   if ( check(action) ) {
+      95         292 :     Keywords keys; getKeywords( action, keys );
+      96         292 :     if( vimout ) {
+      97         292 :       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         292 :   } 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         296 : std::vector<std::string> ActionRegister::getActionNames() const {
+     120             :   std::vector<std::string> s;
+     121       86729 :   for(const auto & it : m) s.push_back(it.first);
+     122         296 :   std::sort(s.begin(),s.end());
+     123         296 :   return s;
+     124           0 : }
+     125             : 
+     126         294 : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar) {
+     127         294 :   std::vector<std::string> s(ar.getActionNames());
+     128       86143 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+     129         294 :   if(!ar.disabled.empty()) {
+     130           0 :     s.assign(ar.disabled.size(),"");
+     131           0 :     std::copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
+     132           0 :     std::sort(s.begin(),s.end());
+     133           0 :     log<<"+++++++ WARNING +++++++\n";
+     134           0 :     log<<"The following keywords have been registered more than once and will be disabled:\n";
+     135           0 :     for(unsigned i=0; i<s.size(); i++) log<<"  - "<<s[i]<<"\n";
+     136           0 :     log<<"+++++++ END WARNING +++++++\n";
+     137             :   };
+     138         294 :   return log;
+     139         294 : }
+     140             : 
+     141             : 
+     142             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func-sort-c.html b/coverage/core/ActionSet.cpp.func-sort-c.html new file mode 100644 index 0000000000..9e6153b9db --- /dev/null +++ b/coverage/core/ActionSet.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE805268
_ZN4PLMD9ActionSetD2Ev805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func.html b/coverage/core/ActionSet.cpp.func.html new file mode 100644 index 0000000000..a152afac9c --- /dev/null +++ b/coverage/core/ActionSet.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE805268
_ZN4PLMD9ActionSetD2Ev805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.gcov.html b/coverage/core/ActionSet.cpp.gcov.html new file mode 100644 index 0000000000..f702647fd7 --- /dev/null +++ b/coverage/core/ActionSet.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + 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-05-27 13:05: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      805268 : ActionSet::ActionSet(PlumedMain&p):
+      27      805268 :   plumed(p) {
+      28             :   (void) plumed; // to suppress warning about "unused plumed"
+      29      805268 : }
+      30             : 
+      31      805268 : ActionSet::~ActionSet()
+      32             : {
+      33             : // required in order to deallocate in reverse order:
+      34      819530 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      35      805268 : }
+      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.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func-sort-c.html b/coverage/core/ActionSet.h.func-sort-c.html new file mode 100644 index 0000000000..45040a05b8 --- /dev/null +++ b/coverage/core/ActionSet.h.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05:14Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze9OptimizerEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_8analysis21LandmarkSelectionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6dimred27DimensionalityReductionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD9ActionSet6selectIPNS_11ActionSetupEEESt6vectorIT_SaIS5_EEv2
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat19AdjacencyMatrixBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze4LossEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat14ClusteringBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_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_EEv321
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE386
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE993
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14302
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv15151
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1081659
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func.html b/coverage/core/ActionSet.h.func.html new file mode 100644 index 0000000000..1e4dd6b018 --- /dev/null +++ b/coverage/core/ActionSet.h.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05:14Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE993
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_10vesselbase16ActionWithVesselEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE118
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE386
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1081659
_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_traitsIcESaIcEEE14302
_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_EEv15151
_ZNK4PLMD9ActionSet6selectIPNS_11ActionSetupEEESt6vectorIT_SaIS5_EEv2
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv321
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.gcov.html b/coverage/core/ActionSet.h.gcov.html new file mode 100644 index 0000000000..87adde3fc9 --- /dev/null +++ b/coverage/core/ActionSet.h.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05:14Functions:222588.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_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       15590 : std::vector<T> ActionSet::select()const {
+      85             :   std::vector<T> ret;
+      86     6253504 :   for(const auto & p : (*this)) {
+      87     6237914 :     T t=dynamic_cast<T>(p.get());
+      88     6237914 :     if(t) ret.push_back(t);
+      89             :   };
+      90       15590 :   return ret;
+      91             : }
+      92             : 
+      93             : template <class T>
+      94     1097301 : T ActionSet::selectWithLabel(const std::string&s)const {
+      95     9461825 :   for(const auto & p : (*this)) {
+      96     3276047 :     T t=dynamic_cast<T>(p.get());
+      97     9447321 :     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        1005 : T ActionSet::selectLatest(const Action*action) const {
+     133             :   T t=nullptr;
+     134       13074 :   for(const auto & p : (*this)) {
+     135       12109 :     if(p.get()==action) return t;
+     136       12069 :     T r=dynamic_cast<T>(p.get());
+     137       12069 :     if(r) t=r;
+     138             :   }
+     139             :   return t;
+     140             : }
+     141             : 
+     142             : 
+     143             : 
+     144             : }
+     145             : 
+     146             : #endif
+     147             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func-sort-c.html b/coverage/core/ActionSetup.cpp.func-sort-c.html new file mode 100644 index 0000000000..7845fc9f4d --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE78
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE173
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func.html b/coverage/core/ActionSetup.cpp.func.html new file mode 100644 index 0000000000..dbbfc6e468 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE173
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE78
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.gcov.html b/coverage/core/ActionSetup.cpp.gcov.html new file mode 100644 index 0000000000..307df1be52 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.gcov.html @@ -0,0 +1,121 @@ + + + + + + + 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-05-27 13:05: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          78 : ActionSetup::ActionSetup(const ActionOptions&ao):
+      31          78 :   Action(ao)
+      32             : {
+      33          78 :   const ActionSet& actionset(plumed.getActionSet());
+      34          81 :   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          78 : }
+      39             : 
+      40         173 : void ActionSetup::registerKeywords( Keywords& keys ) {
+      41         173 :   Action::registerKeywords(keys);
+      42         173 :   keys.remove("LABEL");
+      43         173 : }
+      44             : 
+      45             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.func-sort-c.html b/coverage/core/ActionSetup.h.func-sort-c.html new file mode 100644 index 0000000000..c64f56a510 --- /dev/null +++ b/coverage/core/ActionSetup.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.func.html b/coverage/core/ActionSetup.h.func.html new file mode 100644 index 0000000000..9222281ef4 --- /dev/null +++ b/coverage/core/ActionSetup.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.gcov.html b/coverage/core/ActionSetup.h.gcov.html new file mode 100644 index 0000000000..5e2d08895c --- /dev/null +++ b/coverage/core/ActionSetup.h.gcov.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func-sort-c.html b/coverage/core/ActionShortcut.cpp.func-sort-c.html new file mode 100644 index 0000000000..65e813eec6 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE12
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev54
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func.html b/coverage/core/ActionShortcut.cpp.func.html new file mode 100644 index 0000000000..9345225ba6 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE12
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev54
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.gcov.html b/coverage/core/ActionShortcut.cpp.gcov.html new file mode 100644 index 0000000000..22814f4d88 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.gcov.html @@ -0,0 +1,143 @@ + + + + + + + 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-05-27 13:05: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          18 : void ActionShortcut::registerKeywords( Keywords& keys ) {
+      29          18 :   Action::registerKeywords( keys );
+      30          36 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      31          18 : }
+      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.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func-sort-c.html b/coverage/core/ActionShortcut.h.func-sort-c.html new file mode 100644 index 0000000000..1c8751ad2f --- /dev/null +++ b/coverage/core/ActionShortcut.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func.html b/coverage/core/ActionShortcut.h.func.html new file mode 100644 index 0000000000..6206eb394d --- /dev/null +++ b/coverage/core/ActionShortcut.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE53
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKSt6vectorIdSaIdEE350
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2868
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2908
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE3016
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE3067
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE178984
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.func.html b/coverage/core/ActionWithArguments.cpp.func.html new file mode 100644 index 0000000000..391de4a1a9 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE3067
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE178984
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2908
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE53
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKSt6vectorIdSaIdEE350
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE3016
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2868
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.gcov.html b/coverage/core/ActionWithArguments.cpp.gcov.html new file mode 100644 index 0000000000..8d261fb202 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.gcov.html @@ -0,0 +1,386 @@ + + + + + + + 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-05-27 13:05: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        3067 : void ActionWithArguments::registerKeywords(Keywords& keys) {
+      36        6134 :   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        3067 : }
+      47             : 
+      48        2908 : void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
+      49        2908 :   std::string def; std::vector<std::string> c; arg.clear(); parseVector(key,c);
+      50        3394 :   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        2908 :   interpretArgumentList(c,arg);
+      55        2908 : }
+      56             : 
+      57          53 : bool ActionWithArguments::parseArgumentList(const std::string&key,int i,std::vector<Value*>&arg) {
+      58             :   std::vector<std::string> c;
+      59             :   arg.clear();
+      60          53 :   if(parseNumberedVector(key,i,c)) {
+      61          12 :     interpretArgumentList(c,arg);
+      62             :     return true;
+      63             :   } else return false;
+      64          53 : }
+      65             : 
+      66        3016 : void ActionWithArguments::interpretArgumentList(const std::vector<std::string>& c, std::vector<Value*>&arg) {
+      67        8499 :   for(unsigned i=0; i<c.size(); i++) {
+      68             :     // is a regex? then just interpret it. The signal is ()
+      69        5486 :     if(!c[i].compare(0,1,"(")) {
+      70         201 :       unsigned l=c[i].length();
+      71         201 :       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         200 :         std::string myregex=c[i];
+      76             :         //log<<"  Evaluating regexp for this action: "<<myregex<<"\n";
+      77             : 
+      78             :         regex_t reg; // regular expression
+      79             : 
+      80         200 :         int errcode=regcomp(&reg, myregex.c_str(),REG_EXTENDED|REG_NEWLINE); // compile the regular expression
+      81         200 :         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         199 :         auto deleter=[](regex_t* r) { regfree(r); };
+      91             :         std::unique_ptr<regex_t,decltype(deleter)> reg_deleter(&reg,deleter);
+      92             : 
+      93         199 :         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         199 :         std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+      97         199 :         if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+      98             :         bool found_something=false;
+      99        1522 :         for(unsigned j=0; j<all.size(); j++) {
+     100        1323 :           std::vector<std::string> ss=all[j]->getComponentsVector();
+     101      220386 :           for(unsigned  k=0; k<ss.size(); ++k) {
+     102      219063 :             unsigned ll=std::strlen(ss[k].c_str())+1;
+     103      219063 :             std::vector<char> str(ll);
+     104             :             std::strcpy(&str[0],ss[k].c_str());
+     105             :             const char *ppstr=&str[0];
+     106      219063 :             if(!regexec(&reg, ppstr, reg.re_nsub, &match, 0)) {
+     107             :               //log.printf("  Something matched with \"%s\" : ",ss[k].c_str());
+     108             :               do {
+     109       27856 :                 if (match.rm_so != -1) {        /* The regex is matching part of a string */
+     110       27856 :                   size_t matchlen = match.rm_eo - match.rm_so;
+     111       27856 :                   std::vector<char> submatch(matchlen+1);
+     112       27856 :                   std::strncpy(submatch.data(), ppstr+match.rm_so, matchlen+1);
+     113       27856 :                   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       27856 :                   std::string putativeVal(submatch.data());
+     117       27856 :                   if( all[j]->exists(putativeVal) ) {
+     118       21369 :                     arg.push_back(all[j]->copyOutput(putativeVal));
+     119             :                     found_something=true;
+     120             :                     //log.printf("  Action %s added! \n",putativeVal.c_str());
+     121             :                   }
+     122             :                 }
+     123       27856 :                 ppstr += match.rm_eo;   /* Restart from last match */
+     124       27856 :               } while(!regexec(&reg,ppstr,reg.re_nsub,&match,0));
+     125             :             }
+     126             :           }
+     127        1323 :         }
+     128         199 :         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        5285 :       std::string a=c[i].substr(0,dot);
+     138        5285 :       std::string name=c[i].substr(dot+1);
+     139        5285 :       if(c[i].find(".")!=std::string::npos) {   // if it contains a dot:
+     140        1877 :         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        1867 :         } else if ( name=="*") {
+     148             :           // Take all the values from an action with a specific name
+     149         532 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     150         532 :           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         532 :           if( action->getNumberOfComponents()==0 ) error("found " + a +".* indicating use all components calculated by action with label " + a + " but this action has no components");
+     156        5592 :           for(int k=0; k<action->getNumberOfComponents(); ++k) arg.push_back(action->copyOutput(k));
+     157        1335 :         } 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        1327 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     170        1327 :           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        1327 :           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        1327 :           arg.push_back(action->copyOutput(c[i]));
+     181             :         }
+     182             :       } else {    // if it doesn't contain a dot
+     183        3417 :         if(c[i]=="*") {
+     184             :           // Take all values from all actions
+     185         104 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     186         104 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     187         700 :           for(unsigned j=0; j<all.size(); j++) {
+     188        1281 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     189             :           }
+     190             :         } else {
+     191        3313 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(c[i]);
+     192        3313 :           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        3312 :           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        3313 :           arg.push_back(action->copyOutput(c[i]));
+     203             :         }
+     204             :       }
+     205             :     }
+     206             :   }
+     207        3013 : }
+     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      178984 : void ActionWithArguments::requestArguments(const std::vector<Value*> &arg) {
+     218      178984 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     219      178984 :   arguments=arg;
+     220      178984 :   clearDependencies();
+     221             :   std::string fullname;
+     222             :   std::string name;
+     223     1255318 :   for(unsigned i=0; i<arguments.size(); i++) {
+     224     1076334 :     fullname=arguments[i]->getName();
+     225     1076334 :     if(fullname.find(".")!=std::string::npos) {
+     226             :       std::size_t dot=fullname.find_first_of('.');
+     227      738706 :       name=fullname.substr(0,dot);
+     228             :     } else {
+     229             :       name=fullname;
+     230             :     }
+     231     1076334 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     232     1076334 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     233     1076334 :     addDependency(action);
+     234             :   }
+     235      178984 : }
+     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        2868 : ActionWithArguments::ActionWithArguments(const ActionOptions&ao):
+     256             :   Action(ao),
+     257        2868 :   lockRequestArguments(false)
+     258             : {
+     259        5739 :   if( keywords.exists("ARG") ) {
+     260             :     std::vector<Value*> arg;
+     261        5550 :     parseArgumentList("ARG",arg);
+     262             : 
+     263        2772 :     if(!arg.empty()) {
+     264        2629 :       log.printf("  with arguments");
+     265       25943 :       for(unsigned i=0; i<arg.size(); i++) log.printf(" %s",arg[i]->getName().c_str());
+     266        2629 :       log.printf("\n");
+     267             :     }
+     268        2772 :     requestArguments(arg);
+     269             :   }
+     270        2865 : }
+     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.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func-sort-c.html b/coverage/core/ActionWithArguments.h.func-sort-c.html new file mode 100644 index 0000000000..2e3ecc8daf --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsD2Ev2865
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458199
_ZN4PLMD19ActionWithArguments12lockRequestsEv538344
_ZN4PLMD19ActionWithArguments14unlockRequestsEv538344
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4121297989
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func.html b/coverage/core/ActionWithArguments.h.func.html new file mode 100644 index 0000000000..d339a1f6af --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments12lockRequestsEv538344
_ZN4PLMD19ActionWithArguments14unlockRequestsEv538344
_ZN4PLMD19ActionWithArgumentsD2Ev2865
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458199
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4121297989
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.gcov.html b/coverage/core/ActionWithArguments.h.gcov.html new file mode 100644 index 0000000000..90cda53bf6 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.gcov.html @@ -0,0 +1,208 @@ + + + + + + + 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-05-27 13:05: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        2865 :   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     4560935 :   return arguments[n];
+      93             : }
+      94             : 
+      95             : inline
+      96             : double ActionWithArguments::getArgument(const unsigned n) const {
+      97      824185 :   return arguments[n]->get();
+      98             : }
+      99             : 
+     100             : inline
+     101  4121297989 : unsigned ActionWithArguments::getNumberOfArguments()const {
+     102  4121315827 :   return arguments.size();
+     103             : }
+     104             : 
+     105             : inline
+     106             : double ActionWithArguments::difference(int i,double d1,double d2)const {
+     107     4859004 :   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      538344 : void ActionWithArguments::lockRequests() {
+     117      552931 :   lockRequestArguments=true;
+     118      538344 : }
+     119             : 
+     120             : inline
+     121      538344 : void ActionWithArguments::unlockRequests() {
+     122      552931 :   lockRequestArguments=false;
+     123      538344 : }
+     124             : 
+     125             : inline
+     126      458199 : const std::vector<Value*> & ActionWithArguments::getArguments() const {
+     127      462013 :   return arguments;
+     128             : }
+     129             : 
+     130             : }
+     131             : 
+     132             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func-sort-c.html b/coverage/core/ActionWithValue.cpp.func-sort-c.html new file mode 100644 index 0000000000..2cae04a180 --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func-sort-c.html @@ -0,0 +1,192 @@ + + + + + + + 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:11212589.6 %
Date:2024-05-27 13:05: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_8KeywordsE256
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_681
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1293
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev1376
_ZN4PLMD15ActionWithValue14setNotPeriodicEv1720
_ZN4PLMD15ActionWithValue23addValueWithDerivativesEv2345
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE4183
_ZN4PLMD15ActionWithValueD2Ev4183
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE4607
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10848
_ZNK4PLMD15ActionWithValue10copyOutputERKj10913
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22633
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26186
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30290
_ZN4PLMD15ActionWithValue16clearInputForcesEv1390052
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1390052
_ZN4PLMD15ActionWithValue16clearDerivativesEv1392832
_ZN4PLMD15ActionWithValue18getPntrToComponentEi2139583
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv3493159
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10598447
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10628829
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10661669
_ZN4PLMD15ActionWithValue14getPntrToValueEv16586097
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func.html b/coverage/core/ActionWithValue.cpp.func.html new file mode 100644 index 0000000000..088b8a7a32 --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func.html @@ -0,0 +1,192 @@ + + + + + + + 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:11212589.6 %
Date:2024-05-27 13:05:14Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_681
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22633
_ZN4PLMD15ActionWithValue14getPntrToValueEv16586097
_ZN4PLMD15ActionWithValue14setNotPeriodicEv1720
_ZN4PLMD15ActionWithValue16clearDerivativesEv1392832
_ZN4PLMD15ActionWithValue16clearInputForcesEv1390052
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE4607
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv3493159
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10598447
_ZN4PLMD15ActionWithValue18getPntrToComponentEi2139583
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_92
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1390052
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30290
_ZN4PLMD15ActionWithValue23addValueWithDerivativesEv2345
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1293
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE256
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10848
_ZN4PLMD15ActionWithValue8addValueEv56
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE4183
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZN4PLMD15ActionWithValueD2Ev4183
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE26186
_ZNK4PLMD15ActionWithValue10copyOutputERKj10913
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10628829
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev1376
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10661669
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.gcov.html b/coverage/core/ActionWithValue.cpp.gcov.html new file mode 100644 index 0000000000..5317bc9439 --- /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:11212589.6 %
Date:2024-05-27 13:05: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        4607 : void ActionWithValue::registerKeywords(Keywords& keys) {
+      29        4607 :   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        9214 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      35        9214 :   keys.add("hidden","HAS_VALUES","this is used in json output to determine those actions that have values");
+      36        4607 : }
+      37             : 
+      38           0 : void ActionWithValue::noAnalyticalDerivatives(Keywords& keys) {
+      39           0 :   keys.remove("NUMERICAL_DERIVATIVES");
+      40           0 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
+      41           0 : }
+      42             : 
+      43        1293 : void ActionWithValue::componentsAreNotOptional(Keywords& keys) {
+      44        1293 :   keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quantities can "
+      45             :                                  "be referenced elsewhere in the input by using this Action's label followed by a "
+      46             :                                  "dot and the name of the quantity required from the list below.");
+      47        1293 : }
+      48             : 
+      49         256 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
+      50         256 :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
+      51             :                                  "actions input file.  However, in addition to the components that can be customized the "
+      52             :                                  "following quantities will always be output");
+      53         256 : }
+      54             : 
+      55        4183 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
+      56             :   Action(ao),
+      57        4183 :   noderiv(true),
+      58        4183 :   numericalDerivatives(false)
+      59             : {
+      60       12079 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+      61        4183 :   if(numericalDerivatives) log.printf("  using numerical derivatives\n");
+      62        4183 : }
+      63             : 
+      64        4183 : ActionWithValue::~ActionWithValue() {
+      65             : // empty destructor to delete unique_ptr
+      66        4183 : }
+      67             : 
+      68     1390052 : void ActionWithValue::clearInputForces() {
+      69     3471459 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
+      70     1390052 : }
+      71             : 
+      72     1392832 : void ActionWithValue::clearDerivatives() {
+      73     1392832 :   unsigned nt = OpenMP::getNumThreads();
+      74     1392832 :   #pragma omp parallel num_threads(nt)
+      75             :   {
+      76             :     #pragma omp for
+      77             :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
+      78             :   }
+      79     1392832 : }
+      80             : 
+      81             : // -- These are the routine for copying the value pointers to other classes -- //
+      82             : 
+      83    10661669 : bool ActionWithValue::exists( const std::string& name ) const {
+      84   116536953 :   for(unsigned i=0; i<values.size(); ++i) {
+      85   105901311 :     if (values[i]->name==name) return true;
+      86             :   }
+      87             :   return false;
+      88             : }
+      89             : 
+      90       26186 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
+      91    11307989 :   for(unsigned i=0; i<values.size(); ++i) {
+      92    11307989 :     if (values[i]->name==name) return values[i].get();
+      93             :   }
+      94           0 :   plumed_merror("there is no pointer with name " + name);
+      95             : }
+      96             : 
+      97       10913 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
+      98       10913 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+      99       10913 :   return values[n].get();
+     100             : }
+     101             : 
+     102             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
+     103             : 
+     104          56 : void ActionWithValue::addValue() {
+     105          56 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     106          56 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), false ) );
+     107          56 : }
+     108             : 
+     109        2345 : void ActionWithValue::addValueWithDerivatives() {
+     110        2345 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     111        2345 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), true ) );
+     112        2345 : }
+     113             : 
+     114        1720 : void ActionWithValue::setNotPeriodic() {
+     115        1720 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     116        1720 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     117        1720 :   values[0]->min=0; values[0]->max=0;
+     118        1720 :   values[0]->setupPeriodicity();
+     119        1720 : }
+     120             : 
+     121         681 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
+     122         681 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     123         681 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     124         681 :   values[0]->setDomain( min, max );
+     125         681 : }
+     126             : 
+     127    16586097 : Value* ActionWithValue::getPntrToValue() {
+     128             :   plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
+     129             :   plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
+     130    16586097 :   return values[0].get();
+     131             : }
+     132             : 
+     133             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
+     134             : 
+     135       22633 : void ActionWithValue::addComponent( const std::string& name ) {
+     136       22633 :   if( !keywords.outputComponentExists(name,true) ) {
+     137           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     138             :                   "registerKeywords as described in the developer docs.");
+     139             :   }
+     140       45266 :   std::string thename; thename=getLabel() + "." + name;
+     141    18683668 :   for(unsigned i=0; i<values.size(); ++i) {
+     142    18661035 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     143    18661035 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     144    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"
+     145             :                    "Remove the line addComponent(\"bias\") from your bias.");
+     146             :   }
+     147       22633 :   values.emplace_back(Tools::make_unique<Value>(this,thename, false ) );
+     148       22633 :   std::string msg="  added component to this action:  "+thename+" \n";
+     149       22633 :   log.printf(msg.c_str());
+     150       22633 : }
+     151             : 
+     152       10848 : void ActionWithValue::addComponentWithDerivatives( const std::string& name ) {
+     153       10848 :   if( !keywords.outputComponentExists(name,true) ) {
+     154           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     155             :                   "registerKeywords as described in the developer doc.");
+     156             :   }
+     157       21696 :   std::string thename; thename=getLabel() + "." + name;
+     158     2442051 :   for(unsigned i=0; i<values.size(); ++i) {
+     159     2431203 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     160     2431203 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     161     2431203 :     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"
+     162             :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
+     163             :   }
+     164       10848 :   values.emplace_back(Tools::make_unique<Value>(this,thename, true ) );
+     165       10848 :   std::string msg="  added component to this action:  "+thename+" \n";
+     166       10848 :   log.printf(msg.c_str());
+     167       10848 : }
+     168             : 
+     169    10628829 : int ActionWithValue::getComponent( const std::string& name ) const {
+     170    10628829 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
+     171    21257658 :   std::string thename; thename=getLabel() + "." + name;
+     172    64113392 :   for(unsigned i=0; i<values.size(); ++i) {
+     173    10628829 :     if (values[i]->name==thename) return i;
+     174             :   }
+     175           0 :   plumed_merror("there is no component with name " + name);
+     176             : }
+     177             : 
+     178           0 : std::string ActionWithValue::getComponentsList( ) const {
+     179             :   std::string complist;
+     180           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     181           0 :     complist+=values[i]->name+" ";
+     182             :   }
+     183           0 :   return complist;
+     184             : }
+     185             : 
+     186        1376 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
+     187             :   std::vector<std::string> complist;
+     188      220524 :   for(unsigned i=0; i<values.size(); ++i) {
+     189      219148 :     complist.push_back(values[i]->name);
+     190             :   }
+     191        1376 :   return complist;
+     192           0 : }
+     193             : 
+     194       30290 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
+     195       30290 :   int kk=getComponent(name);
+     196       30290 :   values[kk]->min=0; values[kk]->max=0;
+     197       30290 :   values[kk]->setupPeriodicity();
+     198       30290 : }
+     199             : 
+     200          92 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
+     201          92 :   int kk=getComponent(name);
+     202          92 :   values[kk]->setDomain(min,max);
+     203          92 : }
+     204             : 
+     205     1390052 : void ActionWithValue::setGradientsIfNeeded() {
+     206     2780104 :   if(isOptionOn("GRADIENTS")) {
+     207         366 :     for(unsigned i=0; i<values.size(); i++) values[i]->setGradients();
+     208             :   }
+     209     1390052 : }
+     210             : 
+     211     3493159 : void ActionWithValue::turnOnDerivatives() {
+     212             :   // Turn on the derivatives
+     213     3493159 :   noderiv=false;
+     214             :   // Resize the derivatives
+     215  4106212557 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
+     216             :   // And turn on the derivatives in all actions on which we are dependent
+     217     7085676 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     218     3592517 :     ActionWithValue* vv=dynamic_cast<ActionWithValue*>( getDependencies()[i] );
+     219     3592517 :     if(vv) vv->turnOnDerivatives();
+     220             :   }
+     221     3493159 : }
+     222             : 
+     223    10598447 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
+     224    10598447 :   int kk=getComponent(name);
+     225    10598447 :   return values[kk].get();
+     226             : }
+     227             : 
+     228     2139583 : Value* ActionWithValue::getPntrToComponent( int n ) {
+     229             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     230     2139583 :   return values[n].get();
+     231             : }
+     232             : 
+     233             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func-sort-c.html b/coverage/core/ActionWithValue.h.func-sort-c.html new file mode 100644 index 0000000000..7a5e3ba34b --- /dev/null +++ b/coverage/core/ActionWithValue.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZN4PLMD15ActionWithValue8setValueERKd194218
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv1634139
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2780554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func.html b/coverage/core/ActionWithValue.h.func.html new file mode 100644 index 0000000000..1100cc3a92 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZN4PLMD15ActionWithValue8setValueERKd194218
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2780554
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv1634139
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.gcov.html b/coverage/core/ActionWithValue.h.gcov.html new file mode 100644 index 0000000000..3e4e1f0ea6 --- /dev/null +++ b/coverage/core/ActionWithValue.h.gcov.html @@ -0,0 +1,296 @@ + + + + + + + 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-05-27 13:05: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     2780554 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
+     181     5561108 :   std::string thename; thename=getLabel() + "." + name;
+     182     6469144 :   for(unsigned i=0; i<values.size(); ++i) {
+     183     3775975 :     if( values[i]->name==thename ) return values[i]->value;
+     184             :   }
+     185             :   return 0.0;
+     186             : }
+     187             : 
+     188             : inline
+     189      194218 : void ActionWithValue::setValue(const double& d) {
+     190      194218 :   plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
+     191      194218 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     192      194218 :   values[0]->set(d);
+     193      194218 : }
+     194             : 
+     195             : inline
+     196             : int ActionWithValue::getNumberOfComponents() const {
+     197      142732 :   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     1634139 : bool ActionWithValue::checkNumericalDerivatives() const {
+     208     1634183 :   return numericalDerivatives;
+     209             : }
+     210             : 
+     211             : inline
+     212        5924 : bool ActionWithValue::doNotCalculateDerivatives() const {
+     213    68373610 :   return noderiv;
+     214             : }
+     215             : 
+     216             : 
+     217             : 
+     218             : }
+     219             : 
+     220             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html new file mode 100644 index 0000000000..3f22fd9e73 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomD0Ev0
_ZN4PLMD21ActionWithVirtualAtomD1Ev0
_ZN4PLMD21ActionWithVirtualAtom12setGradientsEv9
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt5arrayINS_13TensorGenericILj3ELj3EEELm3EE605
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7167
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7178
_ZN4PLMD21ActionWithVirtualAtomD2Ev7178
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7188
_ZN4PLMD21ActionWithVirtualAtom5applyEv14338
_ZN4PLMD21ActionWithVirtualAtom20setGradientsIfNeededEv14422
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func.html b/coverage/core/ActionWithVirtualAtom.cpp.func.html new file mode 100644 index 0000000000..b5ef915f60 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7167
_ZN4PLMD21ActionWithVirtualAtom12setGradientsEv9
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7188
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt5arrayINS_13TensorGenericILj3ELj3EEELm3EE605
_ZN4PLMD21ActionWithVirtualAtom20setGradientsIfNeededEv14422
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom5applyEv14338
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7178
_ZN4PLMD21ActionWithVirtualAtomD0Ev0
_ZN4PLMD21ActionWithVirtualAtomD1Ev0
_ZN4PLMD21ActionWithVirtualAtomD2Ev7178
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.gcov.html b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html new file mode 100644 index 0000000000..3a65c43df9 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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        7188 : void ActionWithVirtualAtom::registerKeywords(Keywords& keys) {
+      28        7188 :   Action::registerKeywords(keys);
+      29        7188 :   ActionAtomistic::registerKeywords(keys);
+      30       14376 :   keys.add("atoms","ATOMS","the list of atoms which are involved the virtual atom's definition");
+      31        7188 : }
+      32             : 
+      33        7178 : ActionWithVirtualAtom::ActionWithVirtualAtom(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionAtomistic(ao),
+      36        7178 :   index(atoms.addVirtualAtom(this))
+      37             : {
+      38        7178 :   log<<"  serial associated to this virtual atom is "<<index.serial()<<"\n";
+      39        7178 : }
+      40             : 
+      41        7178 : ActionWithVirtualAtom::~ActionWithVirtualAtom() {
+      42        7178 :   atoms.removeVirtualAtom(this);
+      43        7178 : }
+      44             : 
+      45       14338 : void ActionWithVirtualAtom::apply() {
+      46       14338 :   Vector & f(atoms.forces[index.index()]);
+      47       94976 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) modifyForces()[i]=matmul(derivatives[i],f);
+      48             :   Tensor & v(modifyVirial());
+      49       57352 :   for(unsigned i=0; i<3; i++) v+=boxDerivatives[i]*f[i];
+      50       14338 :   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       14338 : }
+      54             : 
+      55        7167 : void ActionWithVirtualAtom::requestAtoms(const std::vector<AtomNumber> & a) {
+      56        7167 :   ActionAtomistic::requestAtoms(a);
+      57        7167 :   derivatives.resize(a.size());
+      58        7167 : }
+      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       14422 : void ActionWithVirtualAtom::setGradientsIfNeeded() {
+     103       28844 :   if(isOptionOn("GRADIENTS")) {
+     104           9 :     setGradients() ;
+     105             :   }
+     106       14422 : }
+     107             : 
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html new file mode 100644 index 0000000000..5180c6865c --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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:99100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func.html b/coverage/core/ActionWithVirtualAtom.h.func.html new file mode 100644 index 0000000000..10ea2b6e46 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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:99100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.gcov.html b/coverage/core/ActionWithVirtualAtom.h.gcov.html new file mode 100644 index 0000000000..cdc3d6d620 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + 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:99100.0 %
Date:2024-05-27 13:05: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        7219 :   return index;
+      91             : }
+      92             : 
+      93             : inline
+      94             : void ActionWithVirtualAtom::setPosition(const Vector & pos) {
+      95       14422 :   atoms.positions[index.index()]=pos;
+      96         598 : }
+      97             : 
+      98             : inline
+      99             : void ActionWithVirtualAtom::setMass(double m) {
+     100       14422 :   atoms.masses[index.index()]=m;
+     101       13808 : }
+     102             : 
+     103             : inline
+     104             : void ActionWithVirtualAtom::setCharge(double c) {
+     105       14418 :   atoms.charges[index.index()]=c;
+     106       13808 : }
+     107             : 
+     108             : inline
+     109             : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) {
+     110       14422 :   derivatives=d;
+     111       14422 : }
+     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.16
+
+ + + 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..e9fe081b9c --- /dev/null +++ b/coverage/core/Atoms.cpp.func-sort-c.html @@ -0,0 +1,312 @@ + + + + + + + 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:40442894.4 %
Date:2024-05-27 13:05:14Functions:576095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms14getLocalMassesERSt6vectorIdSaIdEE0
_ZN4PLMD5Atoms16getLocalMDForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZNK4PLMD5Atoms15getMDKBoltzmannEv0
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrEi3
_ZNK4PLMD5Atoms15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10
_ZN4PLMD5Atoms10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD5Atoms15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD5Atoms18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd48
_ZN4PLMD5Atoms6setKbTERKNS_11TypesafePtrE59
_ZN4PLMD5Atoms10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE72
_ZN4PLMD5Atoms16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb72
_ZN4PLMD5Atoms10readBinaryERSi114
_ZNK4PLMD5Atoms11writeBinaryERSo114
_ZN4PLMD5Atoms11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms13clearFullListEv116
_ZN4PLMD5Atoms14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms11insertGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISA_EE132
_ZN4PLMD5Atoms11removeGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE132
_ZN4PLMD5Atoms19DomainDecomposition6enableERNS_12CommunicatorE339
_ZN4PLMD5Atoms22setDomainDecompositionERNS_12CommunicatorE339
_ZN4PLMD5Atoms14getLocalForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms18setAtomsContiguousEi491
_ZNK4PLMD5Atoms13getKBoltzmannEv596
_ZN4PLMD5Atoms11setTimeStepERKNS_11TypesafePtrE866
_ZN4PLMD5Atoms16setRealPrecisionEi877
_ZN4PLMD5Atoms9setNatomsEi986
_ZN4PLMD5Atoms16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZN4PLMD5Atoms8shareAllEv990
_ZN4PLMD5Atoms4initEv1007
_ZN4PLMD5Atoms11updateUnitsEv1027
_ZNK4PLMD5Atoms6getKbTEv1294
_ZN4PLMD5Atoms14setAtomsNlocalEi1479
_ZNK4PLMD5Atoms16getRealPrecisionEv1873
_ZNK4PLMD5Atoms9double2MDERKdRKNS_11TypesafePtrE2390
_ZN4PLMD5Atoms14addVirtualAtomEPNS_21ActionWithVirtualAtomE7178
_ZN4PLMD5Atoms17removeVirtualAtomEPNS_21ActionWithVirtualAtomE7178
_ZN4PLMD5Atoms9setEnergyERKNS_11TypesafePtrE9792
_ZN4PLMD5Atoms3addEPNS_15ActionAtomisticE10255
_ZN4PLMD5Atoms6removeEPNS_15ActionAtomisticE10255
_ZNK4PLMD5Atoms9MD2doubleERKNS_11TypesafePtrERd13198
_ZN4PLMD5Atoms13resizeVectorsEj14356
_ZN4PLMDL31getenvMergeVectorsPriorityQueueEv27123
_ZN4PLMD5Atoms10setChargesERKNS_11TypesafePtrE45883
_ZN4PLMD5Atoms9setVirialERKNS_11TypesafePtrE45989
_ZN4PLMD5Atoms6setBoxERKNS_11TypesafePtrE51647
_ZN4PLMDL17getenvForceUniqueEv53319
_ZN4PLMD5Atoms12updateForcesEv54185
_ZN4PLMD5Atoms5shareEv54195
_ZN4PLMD5Atoms4waitEv54309
_ZN4PLMD5Atoms5shareERKSt6vectorINS_10AtomNumberESaIS2_EE54309
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrE55788
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrE55788
_ZN4PLMD5Atoms9setMassesERKNS_11TypesafePtrE55792
_ZN4PLMD5Atoms18resetExtraCVNeededEv256144
_ZN4PLMD5Atoms9startStepEv256144
_ZN4PLMD5AtomsC2ERNS_10PlumedMainE805268
_ZN4PLMD5AtomsD2Ev805268
_ZNK4PLMD5Atoms11getTimeStepEv3210555
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Atoms.cpp.func.html b/coverage/core/Atoms.cpp.func.html new file mode 100644 index 0000000000..c6a8490a89 --- /dev/null +++ b/coverage/core/Atoms.cpp.func.html @@ -0,0 +1,312 @@ + + + + + + + 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:40442894.4 %
Date:2024-05-27 13:05:14Functions:576095.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE72
_ZN4PLMD5Atoms10readBinaryERSi114
_ZN4PLMD5Atoms10setChargesERKNS_11TypesafePtrE45883
_ZN4PLMD5Atoms10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD5Atoms11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms11insertGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISA_EE132
_ZN4PLMD5Atoms11removeGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE132
_ZN4PLMD5Atoms11setTimeStepERKNS_11TypesafePtrE866
_ZN4PLMD5Atoms11updateUnitsEv1027
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrE55788
_ZN4PLMD5Atoms12setPositionsERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms12updateForcesEv54185
_ZN4PLMD5Atoms13clearFullListEv116
_ZN4PLMD5Atoms13resizeVectorsEj14356
_ZN4PLMD5Atoms14addVirtualAtomEPNS_21ActionWithVirtualAtomE7178
_ZN4PLMD5Atoms14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD5Atoms14getLocalForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms14getLocalMassesERSt6vectorIdSaIdEE0
_ZN4PLMD5Atoms14setAtomsNlocalEi1479
_ZN4PLMD5Atoms15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD5Atoms16getLocalMDForcesERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD5Atoms16setAtomsGatindexERKNS_11TypesafePtrEb988
_ZN4PLMD5Atoms16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb72
_ZN4PLMD5Atoms16setRealPrecisionEi877
_ZN4PLMD5Atoms17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS3_EE450
_ZN4PLMD5Atoms17removeVirtualAtomEPNS_21ActionWithVirtualAtomE7178
_ZN4PLMD5Atoms18resetExtraCVNeededEv256144
_ZN4PLMD5Atoms18setAtomsContiguousEi491
_ZN4PLMD5Atoms18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd48
_ZN4PLMD5Atoms19DomainDecomposition6enableERNS_12CommunicatorE339
_ZN4PLMD5Atoms22setDomainDecompositionERNS_12CommunicatorE339
_ZN4PLMD5Atoms3addEPNS_15ActionAtomisticE10255
_ZN4PLMD5Atoms4initEv1007
_ZN4PLMD5Atoms4waitEv54309
_ZN4PLMD5Atoms5shareERKSt6vectorINS_10AtomNumberESaIS2_EE54309
_ZN4PLMD5Atoms5shareEv54195
_ZN4PLMD5Atoms6removeEPNS_15ActionAtomisticE10255
_ZN4PLMD5Atoms6setBoxERKNS_11TypesafePtrE51647
_ZN4PLMD5Atoms6setKbTERKNS_11TypesafePtrE59
_ZN4PLMD5Atoms8shareAllEv990
_ZN4PLMD5Atoms9setEnergyERKNS_11TypesafePtrE9792
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrE55788
_ZN4PLMD5Atoms9setForcesERKNS_11TypesafePtrEi3
_ZN4PLMD5Atoms9setMassesERKNS_11TypesafePtrE55792
_ZN4PLMD5Atoms9setNatomsEi986
_ZN4PLMD5Atoms9setVirialERKNS_11TypesafePtrE45989
_ZN4PLMD5Atoms9startStepEv256144
_ZN4PLMD5AtomsC2ERNS_10PlumedMainE805268
_ZN4PLMD5AtomsD2Ev805268
_ZN4PLMDL17getenvForceUniqueEv53319
_ZN4PLMDL31getenvMergeVectorsPriorityQueueEv27123
_ZNK4PLMD5Atoms11getTimeStepEv3210555
_ZNK4PLMD5Atoms11writeBinaryERSo114
_ZNK4PLMD5Atoms13getKBoltzmannEv596
_ZNK4PLMD5Atoms15getMDKBoltzmannEv0
_ZNK4PLMD5Atoms15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10
_ZNK4PLMD5Atoms16getRealPrecisionEv1873
_ZNK4PLMD5Atoms6getKbTEv1294
_ZNK4PLMD5Atoms9MD2doubleERKNS_11TypesafePtrERd13198
_ZNK4PLMD5Atoms9double2MDERKdRKNS_11TypesafePtrE2390
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Atoms.cpp.gcov.html b/coverage/core/Atoms.cpp.gcov.html new file mode 100644 index 0000000000..9f0e45a784 --- /dev/null +++ b/coverage/core/Atoms.cpp.gcov.html @@ -0,0 +1,748 @@ + + + + + + + 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:40442894.4 %
Date:2024-05-27 13:05:14Functions:576095.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 "Atoms.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "MDAtoms.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "tools/Tools.h"
+      28             : #include <algorithm>
+      29             : #include <iostream>
+      30             : #include <string>
+      31             : #include <cmath>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : /// We assume that charges and masses are constant along the simulation
+      36             : /// Set this to false if you want to revert to the original (expensive) behavior
+      37             : static const bool shareMassAndChargeOnlyAtFirstStep=true;
+      38             : 
+      39             : /// Use a priority_queue to merge unique vectors.
+      40             : /// export PLUMED_MERGE_VECTORS_PRIORITY_QUEUE=yes to use a priority_queue.
+      41             : /// Might be faster with some settings, but appears to not be in practice.
+      42             : /// This option is for testing and might be removed.
+      43       27123 : static bool getenvMergeVectorsPriorityQueue() noexcept {
+      44       27123 :   static const auto* res=std::getenv("PLUMED_MERGE_VECTORS_PRIORITY_QUEUE");
+      45       27123 :   return res;
+      46             : }
+      47             : 
+      48             : /// Use unique list of atoms to manipulate forces and positions.
+      49             : /// A unique list of atoms is used to manipulate forces and positions in MPI parallel runs.
+      50             : /// In serial runs, this is done if convenient. The code currently contain
+      51             : /// some heuristic to decide if the unique list should be used or not.
+      52             : /// An env var can be used to override this decision.
+      53             : /// export PLUMED_FORCE_UNIQUE=yes  # enforce using the unique list in serial runs
+      54             : /// export PLUMED_FORCE_UNIQUE=no   # enforce not using the unique list in serial runs
+      55             : /// export PLUMED_FORCE_UNIQUE=auto # choose heuristically
+      56             : /// default: auto
+      57       53319 : static const char* getenvForceUnique() noexcept {
+      58       53319 :   static const auto* res=std::getenv("PLUMED_FORCE_UNIQUE");
+      59       53319 :   return res;
+      60             : }
+      61             : 
+      62             : class PlumedMain;
+      63             : 
+      64      805268 : Atoms::Atoms(PlumedMain&plumed):
+      65      805268 :   natoms(0),
+      66      805268 :   md_energy(0.0),
+      67      805268 :   energy(0.0),
+      68      805268 :   dataCanBeSet(false),
+      69      805268 :   collectEnergy(false),
+      70      805268 :   energyHasBeenSet(false),
+      71      805268 :   positionsHaveBeenSet(0),
+      72      805268 :   massesHaveBeenSet(false),
+      73      805268 :   chargesHaveBeenSet(false),
+      74      805268 :   boxHasBeenSet(false),
+      75      805268 :   forcesHaveBeenSet(0),
+      76      805268 :   virialHasBeenSet(false),
+      77      805268 :   massAndChargeOK(false),
+      78      805268 :   shuffledAtoms(0),
+      79      805268 :   mdatoms(MDAtomsBase::create(sizeof(double))),
+      80      805268 :   plumed(plumed),
+      81      805268 :   naturalUnits(false),
+      82      805268 :   MDnaturalUnits(false),
+      83      805268 :   timestep(0.0),
+      84      805268 :   forceOnEnergy(0.0),
+      85      805268 :   zeroallforces(false),
+      86      805268 :   kbT(0.0),
+      87      805268 :   asyncSent(false),
+      88      805268 :   atomsNeeded(false),
+      89     1610536 :   ddStep(0)
+      90             : {
+      91      805268 : }
+      92             : 
+      93      805268 : Atoms::~Atoms() {
+      94      805268 :   if(actions.size()>0) {
+      95           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";
+      96             :   }
+      97     1610536 : }
+      98             : 
+      99      256144 : void Atoms::startStep() {
+     100      256144 :   collectEnergy=false; energyHasBeenSet=false; positionsHaveBeenSet=0;
+     101      256144 :   massesHaveBeenSet=false; chargesHaveBeenSet=false; boxHasBeenSet=false;
+     102      256144 :   forcesHaveBeenSet=0; virialHasBeenSet=false; dataCanBeSet=true;
+     103      256144 :   resetExtraCVNeeded();
+     104      256144 : }
+     105             : 
+     106       51647 : void Atoms::setBox(const TypesafePtr & p) {
+     107       51647 :   mdatoms->setBox(p);
+     108       51647 :   Tensor b; mdatoms->getBox(b); boxHasBeenSet=true;
+     109       51647 : }
+     110             : 
+     111       55788 : void Atoms::setPositions(const TypesafePtr & p) {
+     112       55788 :   plumed_massert( dataCanBeSet,"setPositions must be called after setStep in MD code interface");
+     113       55788 :   plumed_massert( p || gatindex.size()==0, "NULL position pointer with non-zero local atoms");
+     114       55788 :   mdatoms->setp(p); positionsHaveBeenSet=3;
+     115       55788 : }
+     116             : 
+     117       55792 : void Atoms::setMasses(const TypesafePtr & p) {
+     118       55795 :   plumed_massert( dataCanBeSet,"setMasses must be called after setStep in MD code interface");
+     119       55789 :   plumed_massert( p || gatindex.size()==0, "NULL mass pointer with non-zero local atoms");
+     120       55789 :   mdatoms->setm(p); massesHaveBeenSet=true;
+     121             : 
+     122       55789 : }
+     123             : 
+     124       45883 : void Atoms::setCharges(const TypesafePtr & p) {
+     125       45883 :   plumed_massert( dataCanBeSet, "setCharges must be called after setStep in MD code interface");
+     126       45883 :   plumed_massert( p || gatindex.size()==0, "NULL charges pointer with non-zero local atoms");
+     127       45883 :   mdatoms->setc(p); chargesHaveBeenSet=true;
+     128       45883 : }
+     129             : 
+     130       45989 : void Atoms::setVirial(const TypesafePtr & p) {
+     131       45989 :   plumed_massert( dataCanBeSet,"setVirial must be called after setStep in MD code interface");
+     132       45989 :   mdatoms->setVirial(p); virialHasBeenSet=true;
+     133       45987 : }
+     134             : 
+     135        9792 : void Atoms::setEnergy(const TypesafePtr & p) {
+     136        9792 :   plumed_massert( dataCanBeSet,"setEnergy must be called after setStep in MD code interface");
+     137        9792 :   MD2double(p,md_energy);
+     138        9792 :   md_energy*=MDUnits.getEnergy()/units.getEnergy();
+     139        9792 :   energyHasBeenSet=true;
+     140        9792 : }
+     141             : 
+     142       55788 : void Atoms::setForces(const TypesafePtr & p) {
+     143       55788 :   plumed_massert( dataCanBeSet,"setForces must be called after setStep in MD code interface");
+     144       55788 :   plumed_massert( p || gatindex.size()==0, "NULL force pointer with non-zero local atoms");
+     145       55788 :   forcesHaveBeenSet=3;
+     146       55788 :   mdatoms->setf(p);
+     147       55788 : }
+     148             : 
+     149           3 : void Atoms::setPositions(const TypesafePtr & p,int i) {
+     150           3 :   plumed_massert( dataCanBeSet,"setPositions must be called after setStep in MD code interface");
+     151           3 :   plumed_massert( p || gatindex.size()==0, "NULL positions pointer with non-zero local atoms");
+     152           3 :   mdatoms->setp(p,i); positionsHaveBeenSet++;
+     153           3 : }
+     154             : 
+     155           3 : void Atoms::setForces(const TypesafePtr & p,int i) {
+     156           3 :   plumed_massert( dataCanBeSet,"setForces must be called after setStep in MD code interface");
+     157           3 :   plumed_massert( p || gatindex.size()==0, "NULL force pointer with non-zero local atoms");
+     158           3 :   mdatoms->setf(p,i); forcesHaveBeenSet++;
+     159           3 : }
+     160             : 
+     161       54195 : void Atoms::share() {
+     162             : // At first step I scatter all the atoms so as to store their mass and charge
+     163             : // Notice that this works with the assumption that charges and masses are
+     164             : // not changing during the simulation!
+     165       54195 :   if(!massAndChargeOK && shareMassAndChargeOnlyAtFirstStep) {
+     166         876 :     shareAll();
+     167         876 :     return;
+     168             :   }
+     169             : 
+     170       53319 :   if(!getenvForceUnique() || !std::strcmp(getenvForceUnique(),"auto")) {
+     171             :     unsigned largest=0;
+     172      256701 :     for(unsigned i=0; i<actions.size(); i++) {
+     173      203382 :       if(actions[i]->isActive()) {
+     174             :         auto l=actions[i]->getUnique().size();
+     175      154014 :         if(l>largest) largest=l;
+     176             :       }
+     177             :     }
+     178       53319 :     if(largest*2<natoms) unique_serial=true;
+     179       26693 :     else unique_serial=false;
+     180           0 :   } else if(!std::strcmp(getenvForceUnique(),"yes")) {
+     181           0 :     unique_serial=true;
+     182           0 :   } else if(!std::strcmp(getenvForceUnique(),"no")) {
+     183           0 :     unique_serial=false;
+     184             :   } else {
+     185           0 :     plumed_error()<<"PLUMED_FORCE_UNIQUE set to unknown value "<<getenvForceUnique();
+     186             :   }
+     187             : 
+     188       53319 :   if(unique_serial || !(int(gatindex.size())==natoms && shuffledAtoms==0)) {
+     189             :     std::vector<const std::vector<AtomNumber>*> vectors;
+     190       27014 :     vectors.reserve(actions.size());
+     191      117203 :     for(unsigned i=0; i<actions.size(); i++) {
+     192       90189 :       if(actions[i]->isActive()) {
+     193       66031 :         if(!actions[i]->getUnique().empty()) {
+     194             :           // unique are the local atoms
+     195       55184 :           vectors.push_back(&actions[i]->getUniqueLocal());
+     196             :         }
+     197             :       }
+     198             :     }
+     199       27014 :     if(!vectors.empty()) atomsNeeded=true;
+     200       27014 :     unique.clear();
+     201       27014 :     Tools::mergeSortedVectors(vectors,unique,getenvMergeVectorsPriorityQueue());
+     202             :   } else {
+     203      139498 :     for(unsigned i=0; i<actions.size(); i++) {
+     204      113193 :       if(actions[i]->isActive()) {
+     205       87983 :         if(!actions[i]->getUnique().empty()) {
+     206       78676 :           atomsNeeded=true;
+     207             :         }
+     208             :       }
+     209             :     }
+     210             : 
+     211             :   }
+     212             : 
+     213       53319 :   share(unique);
+     214             : }
+     215             : 
+     216         990 : void Atoms::shareAll() {
+     217         990 :   unique.clear();
+     218             :   // keep in unique only those atoms that are local
+     219         990 :   if(dd && shuffledAtoms>0) {
+     220       17616 :     for(int i=0; i<natoms; i++) if(g2l[i]>=0) unique.push_back(AtomNumber::index(i)); // already sorted
+     221             :   } else {
+     222         804 :     unique.resize(natoms);
+     223      831815 :     for(int i=0; i<natoms; i++) unique[i]=AtomNumber::index(i);
+     224             :   }
+     225         990 :   atomsNeeded=true;
+     226         990 :   share(unique);
+     227         990 : }
+     228             : 
+     229       54309 : void Atoms::share(const std::vector<AtomNumber>& unique) {
+     230       54309 :   plumed_assert( positionsHaveBeenSet==3 && massesHaveBeenSet );
+     231             : 
+     232       54309 :   virial.zero();
+     233       54309 :   if(zeroallforces || (int(gatindex.size())==natoms && !unique_serial)) {
+     234       27168 :     Tools::set_to_zero(forces);
+     235             :   } else {
+     236      403148 :     for(const auto & p : unique) forces[p.index()].zero();
+     237       28990 :     for(unsigned i=getNatoms(); i<positions.size(); i++) forces[i].zero(); // virtual atoms
+     238             :   }
+     239       54309 :   forceOnEnergy=0.0;
+     240       54309 :   mdatoms->getBox(box);
+     241             : 
+     242       54309 :   if(!atomsNeeded) return;
+     243       53067 :   atomsNeeded=false;
+     244             : 
+     245       53067 :   if(!(int(gatindex.size())==natoms && shuffledAtoms==0)) {
+     246        2212 :     uniq_index.resize(unique.size());
+     247       32705 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=g2l[unique[i].index()];
+     248        2212 :     mdatoms->getPositions(unique,uniq_index,positions);
+     249       50855 :   } else if(unique_serial) {
+     250       23746 :     uniq_index.resize(unique.size());
+     251      371042 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=unique[i].index();
+     252       23746 :     mdatoms->getPositions(unique,uniq_index,positions);
+     253             :   } else {
+     254             : // faster version, which retrieves all atoms
+     255       27109 :     mdatoms->getPositions(0,natoms,positions);
+     256             :   }
+     257             : 
+     258             : 
+     259             : // how many double per atom should be scattered:
+     260             :   int ndata=3;
+     261       53067 :   if(!massAndChargeOK) {
+     262             :     ndata=5;
+     263         876 :     masses.assign(masses.size(),std::numeric_limits<double>::quiet_NaN());
+     264         876 :     charges.assign(charges.size(),std::numeric_limits<double>::quiet_NaN());
+     265         876 :     mdatoms->getCharges(gatindex,charges);
+     266         876 :     mdatoms->getMasses(gatindex,masses);
+     267             :   }
+     268             : 
+     269       53067 :   if(dd && shuffledAtoms>0) {
+     270        2142 :     if(dd.async) {
+     271        9510 :       for(unsigned i=0; i<dd.mpi_request_positions.size(); i++) dd.mpi_request_positions[i].wait();
+     272        9510 :       for(unsigned i=0; i<dd.mpi_request_index.size(); i++)     dd.mpi_request_index[i].wait();
+     273             :     }
+     274        2142 :     int count=0;
+     275       29223 :     for(const auto & p : unique) {
+     276       27081 :       dd.indexToBeSent[count]=p.index();
+     277       27081 :       dd.positionsToBeSent[ndata*count+0]=positions[p.index()][0];
+     278       27081 :       dd.positionsToBeSent[ndata*count+1]=positions[p.index()][1];
+     279       27081 :       dd.positionsToBeSent[ndata*count+2]=positions[p.index()][2];
+     280       27081 :       if(!massAndChargeOK) {
+     281        2477 :         dd.positionsToBeSent[ndata*count+3]=masses[p.index()];
+     282        2477 :         dd.positionsToBeSent[ndata*count+4]=charges[p.index()];
+     283             :       }
+     284       27081 :       count++;
+     285             :     }
+     286        2142 :     if(dd.async) {
+     287        2122 :       asyncSent=true;
+     288        2122 :       dd.mpi_request_positions.resize(dd.Get_size());
+     289        2122 :       dd.mpi_request_index.resize(dd.Get_size());
+     290        9710 :       for(int i=0; i<dd.Get_size(); i++) {
+     291        7588 :         dd.mpi_request_index[i]=dd.Isend(&dd.indexToBeSent[0],count,i,666);
+     292        7588 :         dd.mpi_request_positions[i]=dd.Isend(&dd.positionsToBeSent[0],ndata*count,i,667);
+     293             :       }
+     294             :     } else {
+     295          20 :       const int n=(dd.Get_size());
+     296          20 :       std::vector<int> counts(n);
+     297          20 :       std::vector<int> displ(n);
+     298          20 :       std::vector<int> counts5(n);
+     299          20 :       std::vector<int> displ5(n);
+     300          20 :       dd.Allgather(count,counts);
+     301          20 :       displ[0]=0;
+     302          80 :       for(int i=1; i<n; ++i) displ[i]=displ[i-1]+counts[i-1];
+     303         100 :       for(int i=0; i<n; ++i) counts5[i]=counts[i]*ndata;
+     304         100 :       for(int i=0; i<n; ++i) displ5[i]=displ[i]*ndata;
+     305          20 :       dd.Allgatherv(&dd.indexToBeSent[0],count,&dd.indexToBeReceived[0],&counts[0],&displ[0]);
+     306          20 :       dd.Allgatherv(&dd.positionsToBeSent[0],ndata*count,&dd.positionsToBeReceived[0],&counts5[0],&displ5[0]);
+     307          20 :       int tot=displ[n-1]+counts[n-1];
+     308        1620 :       for(int i=0; i<tot; i++) {
+     309        1600 :         positions[dd.indexToBeReceived[i]][0]=dd.positionsToBeReceived[ndata*i+0];
+     310        1600 :         positions[dd.indexToBeReceived[i]][1]=dd.positionsToBeReceived[ndata*i+1];
+     311        1600 :         positions[dd.indexToBeReceived[i]][2]=dd.positionsToBeReceived[ndata*i+2];
+     312        1600 :         if(!massAndChargeOK) {
+     313         432 :           masses[dd.indexToBeReceived[i]]      =dd.positionsToBeReceived[ndata*i+3];
+     314         432 :           charges[dd.indexToBeReceived[i]]     =dd.positionsToBeReceived[ndata*i+4];
+     315             :         }
+     316             :       }
+     317             :     }
+     318             :   }
+     319             : }
+     320             : 
+     321       54309 : void Atoms::wait() {
+     322       54309 :   dataCanBeSet=false; // Everything should be set by this stage
+     323             : // How many double per atom should be scattered
+     324             :   std::size_t ndata=3;
+     325       54309 :   if(!massAndChargeOK)ndata=5;
+     326             : 
+     327       54309 :   if(dd) {
+     328       21601 :     dd.Bcast(box,0);
+     329             :   }
+     330       54309 :   pbc.setBox(box);
+     331             : 
+     332       54309 :   if(collectEnergy) energy=md_energy;
+     333             : 
+     334       54309 :   if(dd && shuffledAtoms>0) {
+     335             : // receive toBeReceived
+     336        2142 :     if(asyncSent) {
+     337             :       Communicator::Status status;
+     338             :       std::size_t count=0;
+     339        9710 :       for(int i=0; i<dd.Get_size(); i++) {
+     340        7588 :         dd.Recv(&dd.indexToBeReceived[count],dd.indexToBeReceived.size()-count,i,666,status);
+     341        7588 :         int c=status.Get_count<int>();
+     342        7588 :         dd.Recv(&dd.positionsToBeReceived[ndata*count],dd.positionsToBeReceived.size()-ndata*count,i,667);
+     343        7588 :         count+=c;
+     344             :       }
+     345       64820 :       for(int i=0; i<count; i++) {
+     346       62698 :         positions[dd.indexToBeReceived[i]][0]=dd.positionsToBeReceived[ndata*i+0];
+     347       62698 :         positions[dd.indexToBeReceived[i]][1]=dd.positionsToBeReceived[ndata*i+1];
+     348       62698 :         positions[dd.indexToBeReceived[i]][2]=dd.positionsToBeReceived[ndata*i+2];
+     349       62698 :         if(!massAndChargeOK) {
+     350        5946 :           masses[dd.indexToBeReceived[i]]      =dd.positionsToBeReceived[ndata*i+3];
+     351        5946 :           charges[dd.indexToBeReceived[i]]     =dd.positionsToBeReceived[ndata*i+4];
+     352             :         }
+     353             :       }
+     354        2122 :       asyncSent=false;
+     355             :     }
+     356        2142 :     if(collectEnergy) dd.Sum(energy);
+     357             :   }
+     358             : // I take note that masses and charges have been set once for all
+     359             : // at the beginning of the simulation.
+     360       54309 :   if(shareMassAndChargeOnlyAtFirstStep) massAndChargeOK=true;
+     361       54309 : }
+     362             : 
+     363       54185 : void Atoms::updateForces() {
+     364       54185 :   plumed_assert( forcesHaveBeenSet==3 );
+     365       54185 :   if(forceOnEnergy*forceOnEnergy>epsilon) {
+     366          50 :     double alpha=1.0-forceOnEnergy;
+     367          50 :     mdatoms->rescaleForces(gatindex,alpha);
+     368          50 :     mdatoms->updateForces(gatindex,forces);
+     369             :   } else {
+     370       54135 :     if(!unique_serial && int(gatindex.size())==natoms && shuffledAtoms==0) mdatoms->updateForces(gatindex,forces);
+     371       27027 :     else mdatoms->updateForces(unique,uniq_index,forces);
+     372             :   }
+     373       54185 :   if( !plumed.novirial && dd.Get_rank()==0 ) {
+     374       39613 :     plumed_assert( virialHasBeenSet );
+     375       39613 :     mdatoms->updateVirial(virial);
+     376             :   }
+     377       54185 : }
+     378             : 
+     379         986 : void Atoms::setNatoms(int n) {
+     380         986 :   natoms=n;
+     381         986 :   positions.resize(n);
+     382         986 :   forces.resize(n);
+     383         986 :   masses.resize(n);
+     384         986 :   charges.resize(n);
+     385         986 :   gatindex.resize(n);
+     386      839573 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=i;
+     387         986 : }
+     388             : 
+     389             : 
+     390       10255 : void Atoms::add(ActionAtomistic*a) {
+     391       10255 :   actions.push_back(a);
+     392       10255 : }
+     393             : 
+     394       10255 : void Atoms::remove(ActionAtomistic*a) {
+     395       10255 :   auto f=find(actions.begin(),actions.end(),a);
+     396       10255 :   plumed_massert(f!=actions.end(),"cannot remove an action registered to atoms");
+     397       10255 :   actions.erase(f);
+     398       10255 : }
+     399             : 
+     400             : 
+     401         339 : void Atoms::DomainDecomposition::enable(Communicator& c) {
+     402         339 :   on=true;
+     403         339 :   Set_comm(c.Get_comm());
+     404         339 :   async=Get_size()<10;
+     405         339 :   if(std::getenv("PLUMED_ASYNC_SHARE")) {
+     406           4 :     std::string s(std::getenv("PLUMED_ASYNC_SHARE"));
+     407           4 :     if(s=="yes") async=true;
+     408           4 :     else if(s=="no") async=false;
+     409           0 :     else plumed_merror("PLUMED_ASYNC_SHARE variable is set to " + s + "; should be yes or no");
+     410             :   }
+     411         339 : }
+     412             : 
+     413        1479 : void Atoms::setAtomsNlocal(int n) {
+     414        1479 :   gatindex.resize(n);
+     415        1479 :   g2l.resize(natoms,-1);
+     416        1479 :   if(dd) {
+     417             : // Since these vectors are sent with MPI by using e.g.
+     418             : // &dd.positionsToBeSent[0]
+     419             : // we make sure they are non-zero-sized so as to
+     420             : // avoid errors when doing boundary check
+     421        1447 :     if(n==0) n++;
+     422        1447 :     dd.positionsToBeSent.resize(n*5,0.0);
+     423        1447 :     dd.positionsToBeReceived.resize(natoms*5,0.0);
+     424        1447 :     dd.indexToBeSent.resize(n,0);
+     425        1447 :     dd.indexToBeReceived.resize(natoms,0);
+     426             :   }
+     427        1479 : }
+     428             : 
+     429         988 : void Atoms::setAtomsGatindex(const TypesafePtr & g,bool fortran) {
+     430         988 :   plumed_massert( g || gatindex.size()==0, "NULL gatindex pointer with non-zero local atoms");
+     431             :   auto gg=g.get<const int*>(gatindex.size());
+     432         988 :   ddStep=plumed.getStep();
+     433         988 :   if(fortran) {
+     434           0 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i]-1;
+     435             :   } else {
+     436       22140 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i];
+     437             :   }
+     438       57530 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     439         988 :   if( gatindex.size()==natoms ) {
+     440           9 :     shuffledAtoms=0;
+     441        1005 :     for(unsigned i=0; i<gatindex.size(); i++) {
+     442         996 :       if( gatindex[i]!=i ) { shuffledAtoms=1; break; }
+     443             :     }
+     444             :   } else {
+     445         979 :     shuffledAtoms=1;
+     446             :   }
+     447         988 :   if(dd) {
+     448         956 :     dd.Sum(shuffledAtoms);
+     449             :   }
+     450       22140 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     451             : 
+     452       10390 :   for(unsigned i=0; i<actions.size(); i++) {
+     453             :     // keep in unique only those atoms that are local
+     454        9402 :     actions[i]->updateUniqueLocal();
+     455             :   }
+     456             :   unique.clear();
+     457         988 : }
+     458             : 
+     459         491 : void Atoms::setAtomsContiguous(int start) {
+     460         491 :   ddStep=plumed.getStep();
+     461      185344 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=start+i;
+     462      197656 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     463      185344 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     464         491 :   if(gatindex.size()<natoms) shuffledAtoms=1;
+     465         739 :   for(unsigned i=0; i<actions.size(); i++) {
+     466             :     // keep in unique only those atoms that are local
+     467         248 :     actions[i]->updateUniqueLocal();
+     468             :   }
+     469             :   unique.clear();
+     470         491 : }
+     471             : 
+     472         877 : void Atoms::setRealPrecision(int p) {
+     473        1754 :   mdatoms=MDAtomsBase::create(p);
+     474         877 : }
+     475             : 
+     476        1873 : int Atoms::getRealPrecision()const {
+     477        1873 :   return mdatoms->getRealPrecision();
+     478             : }
+     479             : 
+     480       13198 : void Atoms::MD2double(const TypesafePtr & m,double&d)const {
+     481       13198 :   plumed_assert(mdatoms); mdatoms->MD2double(m,d);
+     482       13198 : }
+     483        2390 : void Atoms::double2MD(const double&d,const TypesafePtr & m)const {
+     484        2390 :   plumed_assert(mdatoms); mdatoms->double2MD(d,m);
+     485        2390 : }
+     486             : 
+     487        1027 : void Atoms::updateUnits() {
+     488        1027 :   mdatoms->setUnits(units,MDUnits);
+     489        1027 : }
+     490             : 
+     491         866 : void Atoms::setTimeStep(const TypesafePtr & p) {
+     492         866 :   MD2double(p,timestep);
+     493             : // The following is to avoid extra digits in case the MD code uses floats
+     494             : // e.g.: float f=0.002 when converted to double becomes 0.002000000094995
+     495             : // To avoid this, we keep only up to 6 significant digits after first one
+     496         866 :   if(getRealPrecision()<=4) {
+     497           0 :     double magnitude=std::pow(10,std::floor(std::log10(timestep)));
+     498           0 :     timestep=std::round(timestep/magnitude*1e6)/1e6*magnitude;
+     499             :   }
+     500         866 : }
+     501             : 
+     502     3210555 : double Atoms::getTimeStep()const {
+     503     3210555 :   return timestep/units.getTime()*MDUnits.getTime();
+     504             : }
+     505             : 
+     506          59 : void Atoms::setKbT(const TypesafePtr & p) {
+     507          59 :   MD2double(p,kbT);
+     508          59 : }
+     509             : 
+     510        1294 : double Atoms::getKbT()const {
+     511        1294 :   return kbT/units.getEnergy()*MDUnits.getEnergy();
+     512             : }
+     513             : 
+     514             : 
+     515         116 : void Atoms::createFullList(const TypesafePtr & n) {
+     516         116 :   if(!massAndChargeOK && shareMassAndChargeOnlyAtFirstStep) {
+     517           7 :     n.set(int(natoms));
+     518           7 :     fullList.resize(natoms);
+     519         803 :     for(unsigned i=0; i<natoms; i++) fullList[i]=i;
+     520             :   } else {
+     521             : // We update here the unique list defined at Atoms::unique.
+     522             : // This is not very clear, and probably should be coded differently.
+     523             : // Hopefully this fix the longstanding issue with NAMD.
+     524         109 :     unique.clear();
+     525             :     std::vector<const std::vector<AtomNumber>*> vectors;
+     526         892 :     for(unsigned i=0; i<actions.size(); i++) {
+     527         783 :       if(actions[i]->isActive()) {
+     528         625 :         if(!actions[i]->getUnique().empty()) {
+     529         546 :           atomsNeeded=true;
+     530             :           // unique are the local atoms
+     531         546 :           vectors.push_back(&actions[i]->getUnique());
+     532             :         }
+     533             :       }
+     534             :     }
+     535             :     unique.clear();
+     536         109 :     Tools::mergeSortedVectors(vectors,unique,getenvMergeVectorsPriorityQueue());
+     537         109 :     fullList.clear();
+     538         109 :     fullList.reserve(unique.size());
+     539        5012 :     for(const auto & p : unique) fullList.push_back(p.index());
+     540         109 :     n.set(int(fullList.size()));
+     541             :   }
+     542         116 : }
+     543             : 
+     544         116 : void Atoms::getFullList(const TypesafePtr & x) {
+     545             :   auto xx=x.template get<const int**>();
+     546         116 :   if(!fullList.empty()) *xx=&fullList[0];
+     547           6 :   else *xx=NULL;
+     548         116 : }
+     549             : 
+     550         116 : void Atoms::clearFullList() {
+     551         116 :   fullList.resize(0);
+     552         116 : }
+     553             : 
+     554        1007 : void Atoms::init() {
+     555             : // Default: set domain decomposition to NO-decomposition, waiting for
+     556             : // further instruction
+     557        1007 :   if(dd) {
+     558         339 :     setAtomsNlocal(natoms);
+     559         339 :     setAtomsContiguous(0);
+     560             :   }
+     561        1007 : }
+     562             : 
+     563         339 : void Atoms::setDomainDecomposition(Communicator& comm) {
+     564         339 :   dd.enable(comm);
+     565         339 : }
+     566             : 
+     567       14356 : void Atoms::resizeVectors(unsigned n) {
+     568       14356 :   positions.resize(n);
+     569       14356 :   forces.resize(n);
+     570       14356 :   masses.resize(n);
+     571       14356 :   charges.resize(n);
+     572       14356 : }
+     573             : 
+     574        7178 : AtomNumber Atoms::addVirtualAtom(ActionWithVirtualAtom*a) {
+     575        7178 :   unsigned n=positions.size();
+     576        7178 :   resizeVectors(n+1);
+     577        7178 :   virtualAtomsActions.push_back(a);
+     578        7178 :   return AtomNumber::index(n);
+     579             : }
+     580             : 
+     581        7178 : void Atoms::removeVirtualAtom(ActionWithVirtualAtom*a) {
+     582        7178 :   unsigned n=positions.size();
+     583        7178 :   plumed_massert(a==virtualAtomsActions[virtualAtomsActions.size()-1],"virtual atoms should be destroyed in reverse creation order");
+     584        7178 :   resizeVectors(n-1);
+     585             :   virtualAtomsActions.pop_back();
+     586        7178 : }
+     587             : 
+     588         132 : void Atoms::insertGroup(const std::string&name,const std::vector<AtomNumber>&a) {
+     589           0 :   plumed_massert(groups.count(name)==0,"group named "+name+" already exists");
+     590         132 :   groups[name]=a;
+     591         132 : }
+     592             : 
+     593         132 : void Atoms::removeGroup(const std::string&name) {
+     594           0 :   plumed_massert(groups.count(name)==1,"cannot remove group named "+name);
+     595             :   groups.erase(name);
+     596         132 : }
+     597             : 
+     598         114 : void Atoms::writeBinary(std::ostream&o)const {
+     599         114 :   o.write(reinterpret_cast<const char*>(&positions[0][0]),natoms*3*sizeof(double));
+     600         114 :   o.write(reinterpret_cast<const char*>(&box(0,0)),9*sizeof(double));
+     601         114 :   o.write(reinterpret_cast<const char*>(&energy),sizeof(double));
+     602         114 : }
+     603             : 
+     604         114 : void Atoms::readBinary(std::istream&i) {
+     605         114 :   i.read(reinterpret_cast<char*>(&positions[0][0]),natoms*3*sizeof(double));
+     606         114 :   i.read(reinterpret_cast<char*>(&box(0,0)),9*sizeof(double));
+     607         114 :   i.read(reinterpret_cast<char*>(&energy),sizeof(double));
+     608         114 :   pbc.setBox(box);
+     609         114 : }
+     610             : 
+     611         596 : double Atoms::getKBoltzmann()const {
+     612         596 :   if(naturalUnits || MDnaturalUnits) return 1.0;
+     613         590 :   else return kBoltzmann/units.getEnergy();
+     614             : }
+     615             : 
+     616           0 : double Atoms::getMDKBoltzmann()const {
+     617           0 :   if(naturalUnits || MDnaturalUnits) return 1.0;
+     618           0 :   else return kBoltzmann/MDUnits.getEnergy();
+     619             : }
+     620             : 
+     621           0 : void Atoms::getLocalMasses(std::vector<double>& localMasses) {
+     622           0 :   localMasses.resize(gatindex.size());
+     623           0 :   for(unsigned i=0; i<gatindex.size(); i++) localMasses[i] = masses[gatindex[i]];
+     624           0 : }
+     625             : 
+     626         450 : void Atoms::getLocalPositions(std::vector<Vector>& localPositions) {
+     627         450 :   localPositions.resize(gatindex.size());
+     628         450 :   mdatoms->getLocalPositions(localPositions);
+     629         450 : }
+     630             : 
+     631         450 : void Atoms::getLocalForces(std::vector<Vector>& localForces) {
+     632         450 :   localForces.resize(gatindex.size());
+     633       16650 :   for(unsigned i=0; i<gatindex.size(); i++) localForces[i] = forces[gatindex[i]];
+     634         450 : }
+     635             : 
+     636           0 : void Atoms::getLocalMDForces(std::vector<Vector>& localForces) {
+     637           0 :   localForces.resize(gatindex.size());
+     638           0 :   for(unsigned i=0; i<gatindex.size(); i++) {
+     639           0 :     localForces[i] = mdatoms->getMDforces(i);
+     640             :   }
+     641           0 : }
+     642             : 
+     643          30 : void Atoms::setExtraCV(const std::string &name,const TypesafePtr & p) {
+     644          30 :   mdatoms->setExtraCV(name,p);
+     645          30 : }
+     646             : 
+     647          30 : void Atoms::setExtraCVForce(const std::string &name,const TypesafePtr & p) {
+     648          30 :   mdatoms->setExtraCVForce(name,p);
+     649          30 : }
+     650             : 
+     651          72 : double Atoms::getExtraCV(const std::string &name) {
+     652          72 :   return mdatoms->getExtraCV(name);
+     653             : }
+     654             : 
+     655          48 : void Atoms::updateExtraCVForce(const std::string &name,double f) {
+     656          48 :   mdatoms->updateExtraCVForce(name,f);
+     657          48 : }
+     658             : 
+     659          72 : void Atoms::setExtraCVNeeded(const std::string &name,bool needed) {
+     660          72 :   mdatoms->setExtraCVNeeded(name,needed);
+     661          72 : }
+     662             : 
+     663          10 : bool Atoms::isExtraCVNeeded(const std::string &name) const {
+     664          10 :   return mdatoms->isExtraCVNeeded(name);
+     665             : }
+     666             : 
+     667      256144 : void Atoms::resetExtraCVNeeded() {
+     668      256144 :   mdatoms->resetExtraCVNeeded();
+     669      256144 : }
+     670             : 
+     671             : 
+     672             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + 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..ae90307e17 --- /dev/null +++ b/coverage/core/Atoms.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Atoms9getEnergyEv3989
_ZN4PLMD5Atoms19DomainDecompositionC2Ev805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Atoms.h.func.html b/coverage/core/Atoms.h.func.html new file mode 100644 index 0000000000..22bb206f08 --- /dev/null +++ b/coverage/core/Atoms.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Atoms19DomainDecompositionC2Ev805268
_ZNK4PLMD5Atoms9getEnergyEv3989
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Atoms.h.gcov.html b/coverage/core/Atoms.h.gcov.html new file mode 100644 index 0000000000..16c92f9e04 --- /dev/null +++ b/coverage/core/Atoms.h.gcov.html @@ -0,0 +1,379 @@ + + + + + + + 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-05-27 13:05: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 <map>
+      34             : #include <string>
+      35             : #include <memory>
+      36             : 
+      37             : namespace PLMD {
+      38             : 
+      39             : class MDAtomsBase;
+      40             : class PlumedMain;
+      41             : class ActionAtomistic;
+      42             : class ActionWithVirtualAtom;
+      43             : class Pbc;
+      44             : 
+      45             : /// Class containing atom related quantities from the MD code.
+      46             : /// IT IS STILL UNDOCUMENTED. IT PROBABLY NEEDS A STRONG CLEANUP
+      47             : class Atoms
+      48             : {
+      49             :   friend class ActionAtomistic;
+      50             :   friend class ActionWithVirtualAtom;
+      51             :   int natoms;
+      52             :   bool unique_serial=false; // use unique in serial mode
+      53             :   std::vector<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      186072 :     operator bool() const {return on;}
+     134      805268 :     DomainDecomposition():
+     135      805268 :       on(false), async(false)
+     136      805268 :     {}
+     137             :     void enable(Communicator& c);
+     138             :   };
+     139             : 
+     140             :   DomainDecomposition dd;
+     141             :   long long int ddStep;  //last step in which dd happened
+     142             : 
+     143             :   void share(const std::vector<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 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         810 :   void setMDLengthUnits(double d) {MDUnits.setLength(d);}
+     215           6 :   void setMDTimeUnits(double d) {MDUnits.setTime(d);}
+     216         810 :   void setMDChargeUnits(double d) {MDUnits.setCharge(d);}
+     217         810 :   void setMDMassUnits(double d) {MDUnits.setMass(d);}
+     218             :   const Units& getMDUnits() {return MDUnits;}
+     219          20 :   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          20 :   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             :   void setExtraCVNeeded(const std::string &name,bool needed=true);
+     242             :   bool isExtraCVNeeded(const std::string &name) const;
+     243             :   void resetExtraCVNeeded();
+     244             : };
+     245             : 
+     246             : inline
+     247             : int Atoms::getNatoms()const {
+     248      800903 :   return natoms;
+     249             : }
+     250             : 
+     251             : inline
+     252             : int Atoms::getNVirtualAtoms()const {
+     253          10 :   return virtualAtomsActions.size();
+     254             : }
+     255             : 
+     256             : inline
+     257             : const long long int& Atoms::getDdStep()const {
+     258             :   return ddStep;
+     259             : }
+     260             : 
+     261             : inline
+     262             : const std::vector<int>& Atoms::getGatindex()const {
+     263           9 :   return gatindex;
+     264             : }
+     265             : 
+     266             : inline
+     267             : const Pbc& Atoms::getPbc()const {
+     268         900 :   return pbc;
+     269             : }
+     270             : 
+     271             : inline
+     272             : bool Atoms::isVirtualAtom(AtomNumber i)const {
+     273     1384097 :   return i.index()>=(unsigned) getNatoms();
+     274             : }
+     275             : 
+     276             : inline
+     277             : ActionWithVirtualAtom* Atoms::getVirtualAtomsAction(AtomNumber i)const {
+     278        7234 :   return virtualAtomsActions[i.index()-getNatoms()];
+     279             : }
+     280             : 
+     281             : inline
+     282             : bool Atoms::usingNaturalUnits() const {
+     283        2464 :   return naturalUnits || MDnaturalUnits;
+     284             : }
+     285             : 
+     286             : inline
+     287             : bool Atoms::chargesWereSet() const {
+     288      176490 :   return chargesHaveBeenSet;
+     289             : }
+     290             : 
+     291             : inline
+     292             : bool Atoms::boxWasSet() const {
+     293             :   return boxHasBeenSet;
+     294             : }
+     295             : 
+     296             : inline
+     297             : const Tensor& Atoms::getVirial()const {
+     298         450 :   return virial;
+     299             : }
+     300             : 
+     301             : 
+     302             : }
+     303             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.func-sort-c.html b/coverage/core/CLTool.cpp.func-sort-c.html new file mode 100644 index 0000000000..881598fca4 --- /dev/null +++ b/coverage/core/CLTool.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2972
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3024
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3024
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3088
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3088
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3088
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb20945
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE58352
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.func.html b/coverage/core/CLTool.cpp.func.html new file mode 100644 index 0000000000..37538e856a --- /dev/null +++ b/coverage/core/CLTool.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3088
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3088
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE58352
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2972
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3024
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb20945
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3024
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.gcov.html b/coverage/core/CLTool.cpp.gcov.html new file mode 100644 index 0000000000..4531c5dc6b --- /dev/null +++ b/coverage/core/CLTool.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-05-27 13:05: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        3088 : CLToolOptions::CLToolOptions(const std::string &name):
+      29        3088 :   line(1,name),
+      30        3088 :   keys(emptyKeys)
+      31             : {
+      32        3088 : }
+      33             : 
+      34        3088 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
+      35        3088 :   line(co.line),
+      36        3088 :   keys(k)
+      37             : {
+      38        3088 : }
+      39             : 
+      40       58352 : void CLTool::registerKeywords( Keywords& keys ) {
+      41      116704 :   keys.addFlag("--help/-h",false,"print this help");
+      42       58352 : }
+      43             : 
+      44        3088 : CLTool::CLTool(const CLToolOptions& co ):
+      45        3088 :   name(co.line[0]),
+      46        3088 :   keywords(co.keys),
+      47        3088 :   inputdata(unset)
+      48             : {
+      49        3088 : }
+      50             : 
+      51       20945 : void CLTool::parseFlag( const std::string&key, bool&t ) {
+      52       20945 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+      53       41890 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
+      54           0 :   plumed_assert(inputData.count(key)>0);
+      55       41890 :   if( inputData[key]=="true") t=true;
+      56       37446 :   else if( inputData[key]=="false") t=false;
+      57           0 :   else plumed_error();
+      58       20945 : }
+      59             : 
+      60        3024 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
+      61        3024 :   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        3024 :   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        2972 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
+      71        2972 :   plumed_assert(inputdata==commandline);
+      72        2972 :   std::string prefix(""), a(""), thiskey;
+      73             : 
+      74             :   // Set all flags to default false
+      75       56704 :   for(unsigned k=0; k<keywords.size(); ++k) {
+      76       53732 :     thiskey=keywords.get(k);
+      77      131760 :     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       12309 :   for(int i=1; i<argc; i++) {
+      83       18674 :     a=prefix+argv[i];
+      84        9337 :     if(a.length()==0) continue;
+      85       18674 :     if(a=="-h" || a=="--help") {
+      86             :       printhelp=true;
+      87             :     } else {
+      88             :       bool found=false;
+      89      304598 :       for(unsigned k=0; k<keywords.size(); ++k) {
+      90      295261 :         thiskey=keywords.get(k);
+      91      590522 :         if( keywords.style(thiskey,"flag") ) {
+      92       60380 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
+      93             :         } else {
+      94      234881 :           if( a==thiskey ) {
+      95        3299 :             prefix=thiskey+"="; found=true;
+      96        6598 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
+      97      463164 :           } else if(Tools::startWith(a,thiskey+"=")) {
+      98        3818 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
+      99             :             if(inputData.count(thiskey)==0) {
+     100        1040 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
+     101             :             } else {
+     102        3298 :               inputData[thiskey]=a;
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107        9337 :       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        9337 :     if(printhelp) break;
+     116             :   }
+     117             : 
+     118        2972 :   if(!printhelp) setRemainingToDefault(out);
+     119             : 
+     120        2972 :   if(printhelp) {
+     121             :     std::fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
+     122           0 :     keywords.print( out );
+     123             :   }
+     124             : 
+     125        2972 :   return !printhelp;
+     126             : }
+     127             : 
+     128        3024 : void CLTool::setRemainingToDefault(FILE* out) {
+     129             :   std::string def, thiskey;
+     130       57764 :   for(unsigned k=0; k<keywords.size(); ++k) {
+     131       54740 :     thiskey=keywords.get(k);
+     132      109480 :     if( keywords.style(thiskey,"compulsory") ) {
+     133             :       if( inputData.count(thiskey)==0 ) {
+     134        1644 :         if( keywords.getDefaultValue(thiskey,def) ) {
+     135        1644 :           plumed_assert( def.length()>0 );
+     136        3288 :           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        3024 : }
+     145             : 
+     146          52 : bool CLTool::readInputFile( int argc, char**argv, FILE* in, FILE*out ) {
+     147          52 :   plumed_assert(inputdata==ifile);
+     148             : 
+     149             :   // Check if use is just asking for help
+     150             :   std::string a;
+     151          95 :   for(int i=1; i<argc; i++) {
+     152          43 :     a=argv[i];
+     153          43 :     if(a.length()==0) continue;
+     154          86 :     if(a=="-h" || a=="--help") {
+     155             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     156             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     157           0 :       keywords.print( out );
+     158             :       return false;
+     159             :     }
+     160             :   }
+     161             : 
+     162             :   FILE* mystdin=in;
+     163             : // call fclose when fp_deleter goes out of scope
+     164          43 :   auto deleter=[](FILE* f) { std::fclose(f); };
+     165             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(nullptr,deleter);
+     166             : 
+     167          52 :   if(argc==2) {
+     168          43 :     mystdin=std::fopen(argv[1],"r");
+     169          43 :     if(!mystdin) {
+     170           0 :       std::fprintf(stderr,"ERROR: cannot open file %s\n\n",argv[1]);
+     171             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     172             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     173           0 :       keywords.print( out );
+     174             :       return false;
+     175             :     }
+     176             :     fp_deleter.reset(mystdin);
+     177             :   }
+     178             : 
+     179          52 :   plumed_assert(mystdin);
+     180             : 
+     181             :   char buffer[256]; std::string line; line.resize(256);
+     182         864 :   while(fgets(buffer,256,mystdin)) {
+     183             :     line=buffer;
+     184       24516 :     for(unsigned i=0; i<line.length(); ++i) if(line[i]=='#' || line[i]=='\n') line.erase(i);
+     185         812 :     Tools::stripLeadingAndTrailingBlanks( line );
+     186         812 :     if(line.length()==0) continue;
+     187         775 :     std::sscanf(line.c_str(),"%255s",buffer);
+     188         775 :     std::string keyword=buffer; bool found=false;
+     189       16236 :     for(unsigned i=0; i<keywords.size(); ++i) {
+     190       15461 :       std::string thiskey=keywords.get(i);
+     191       15461 :       if(thiskey==keyword) {
+     192             :         found=true;
+     193         775 :         std::size_t keypos=line.find_first_of(keyword)+keyword.length();
+     194        1550 :         inputData.insert(std::pair<std::string,std::string>(thiskey,line.substr(keypos)));
+     195         775 :         Tools::stripLeadingAndTrailingBlanks( inputData[thiskey] );
+     196             :       }
+     197             :     }
+     198         775 :     if(!found) {
+     199           0 :       std::fprintf(stderr,"ERROR in input for command line tool %s : unknown keyword %s found in input file\n\n",name.c_str(),keyword.c_str());
+     200             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     201             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     202           0 :       keywords.print( out );
+     203             :       return false;
+     204             :     }
+     205             :   }
+     206             : 
+     207          52 :   setRemainingToDefault(out);
+     208             :   return true;
+     209             : }
+     210             : 
+     211           0 : [[noreturn]] void CLTool::error( const std::string& msg ) {
+     212           0 :   std::fprintf(stderr,"ERROR : in input for command line tool %s : %s\n",name.c_str(),msg.c_str());
+     213           0 :   plumed_error();
+     214             : }
+     215             : 
+     216             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func-sort-c.html b/coverage/core/CLTool.h.func-sort-c.html new file mode 100644 index 0000000000..81bd6a8d8d --- /dev/null +++ b/coverage/core/CLTool.h.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLToolD0Ev0
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev0
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE158
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_804
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_852
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1590
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1698
_ZN4PLMD6CLToolD2Ev3088
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_22488
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func.html b/coverage/core/CLTool.h.func.html new file mode 100644 index 0000000000..e9ac07dbdf --- /dev/null +++ b/coverage/core/CLTool.h.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE158
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_22488
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1698
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1590
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_852
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_804
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLToolD2Ev3088
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.gcov.html b/coverage/core/CLTool.h.gcov.html new file mode 100644 index 0000000000..8bdc211e09 --- /dev/null +++ b/coverage/core/CLTool.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + 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-05-27 13:05:14Functions:121580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_CLTool_h
+      23             : #define __PLUMED_core_CLTool_h
+      24             : #include <cstdio>
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <cstdio>
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/Keywords.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class Communicator;
+      34             : 
+      35        6176 : 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        3088 :   virtual ~CLTool() {}
+     100             : };
+     101             : 
+     102             : template<class T>
+     103       27552 : bool CLTool::parse(const std::string&key,T&t) {
+     104       27552 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     105       55104 :   if(keywords.style(key,"compulsory") ) {
+     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
+     107        4092 :     bool check=Tools::convertNoexcept(inputData[key],t);
+     108        4092 :     if(!check) error("data input for keyword " + key + " has wrong type");
+     109             :     return true;
+     110             :   }
+     111       21619 :   if( inputData.count(key)==0 ) return false;
+     112        1841 :   Tools::convert(inputData[key],t);
+     113        1841 :   return true;
+     114             : }
+     115             : // very limited support and check: take more from core/Action.h parseVector
+     116             : template<class T>
+     117         366 : bool CLTool::parseVector(const std::string&key,std::vector<T>&t) {
+     118             : 
+     119             :   // Check keyword has been registered
+     120         366 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     121             :   // initial size
+     122         366 :   unsigned size=t.size();
+     123             :   bool skipcheck=false;
+     124         366 :   if(size==0) skipcheck=true; // if the vector in input has size zero, skip the check if size of input vector is the same of argument read
+     125             : 
+     126             :   // check if there is some value
+     127             : 
+     128         732 :   plumed_massert(inputData[key]!="false","compulsory keyword "+std::string(key)+"has no data");
+     129         366 :   std::vector<std::string> words=Tools::getWords(inputData[key],"\t\n ,");
+     130         366 :   t.resize(0);
+     131         366 :   if(words.size()==0)return false;
+     132             : 
+     133         773 :   for(unsigned i=0; i<words.size(); ++i) {
+     134             :     T v;
+     135         487 :     Tools::convert(words[i],v);
+     136         487 :     t.push_back(v);
+     137             :   }
+     138             :   // check the size
+     139         286 :   if( !skipcheck && t.size()!=size ) {
+     140           0 :     plumed_merror("vector read in for keyword  "+key+" has wrong size" );
+     141             :   }
+     142             :   std::string def;
+     143             :   T val;
+     144         572 :   if ( keywords.style(key,"compulsory") && t.size()==0 ) {
+     145           0 :     if( keywords.getDefaultValue(key,def) ) {
+     146           0 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     147           0 :         plumed_merror("ERROR in keyword "+key+ " has weird default value" );
+     148             :       } else {
+     149             :         // GB: before it was like this, but clearly if t.size()==0 this was not doing anything
+     150             :         // for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     151           0 :         t.resize(1);
+     152           0 :         t[0]=val;
+     153             :       }
+     154             :     } else {
+     155           0 :       plumed_merror("keyword " + key + " is compulsory for this action");
+     156             :     }
+     157             :   }
+     158             :   return true;
+     159         366 : }
+     160             : 
+     161             : 
+     162             : 
+     163             : }
+     164             : 
+     165             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func-sort-c.html b/coverage/core/CLToolMain.cpp.func-sort-c.html new file mode 100644 index 0000000000..315c206504 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE4217
_ZN4PLMD10CLToolMainC2Ev4217
_ZN4PLMD10CLToolMainD0Ev4217
_ZN4PLMD10CLToolMainD2Ev4217
_ZN4PLMD10CLToolMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE12906
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func.html b/coverage/core/CLToolMain.cpp.func.html new file mode 100644 index 0000000000..13b2e8c0c9 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE12906
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE4217
_ZN4PLMD10CLToolMainC2Ev4217
_ZN4PLMD10CLToolMainD0Ev4217
_ZN4PLMD10CLToolMainD2Ev4217
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.gcov.html b/coverage/core/CLToolMain.cpp.gcov.html new file mode 100644 index 0000000000..bd7102503e --- /dev/null +++ b/coverage/core/CLToolMain.cpp.gcov.html @@ -0,0 +1,367 @@ + + + + + + + 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-05-27 13:05: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        4217 : CLToolMain::CLToolMain():
+      41        4217 :   argc(0),
+      42        4217 :   in(stdin),
+      43        4217 :   out(stdout)
+      44             : {
+      45        4217 : }
+      46             : 
+      47        8434 : CLToolMain::~CLToolMain() {
+      48             : // empty destructor to delete unique_ptr
+      49        8434 : }
+      50             : 
+      51             : #define CHECK_NULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"CLTool " + word + "\")");
+      52             : 
+      53       12906 : 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       50130 :   };
+      64             : 
+      65       12906 :   std::vector<std::string> words=Tools::getWords(word);
+      66       12906 :   unsigned nw=words.size();
+      67       12906 :   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       12906 :     if(it!=word_map.end()) iword=it->second;
+      75       12906 :     switch(iword) {
+      76             :     case cmd_setArgc:
+      77        4133 :       CHECK_NULL(val,word);
+      78        4133 :       argc=val.get<int>();
+      79        4133 :       break;
+      80             :     case cmd_setArgv:
+      81        4133 :       CHECK_NULL(val,word);
+      82        4133 :       v=val.get<const char*const*>(argc);
+      83       26792 :       for(int i=0; i<argc; ++i) argv.push_back(std::string(v[i]));
+      84             :       break;
+      85             :     case cmd_setArgvLine:
+      86          84 :       CHECK_NULL(val,word);
+      87             :       vv=val.get<const char*>();
+      88          84 :       argv=Tools::getWords(vv);
+      89          84 :       break;
+      90             :     case cmd_setIn:
+      91           0 :       CHECK_NULL(val,word);
+      92           0 :       in=val.get<FILE*>();
+      93           0 :       break;
+      94             :     case cmd_setOut:
+      95           1 :       CHECK_NULL(val,word);
+      96           1 :       out=val.get<FILE*>();
+      97           1 :       break;
+      98         338 :     case cmd_setMPIComm:
+      99         338 :       comm.Set_comm(val);
+     100             :       break;
+     101           0 :     case cmd_setMPIFComm:
+     102           0 :       comm.Set_fcomm(val);
+     103             :       break;
+     104             :     case cmd_run:
+     105        4217 :       CHECK_NULL(val,word);
+     106        4217 :       argc=argv.size();
+     107             :       {
+     108       27364 :         int n=0; for(int i=0; i<argc; ++i) n+=argv[i].length()+1;
+     109        4217 :         std::vector<char> args(n);
+     110        4217 :         std::vector<char*> vvv(argc);
+     111             :         char* ptr=&args[0];
+     112       27364 :         for(int i=0; i<argc; ++i) {
+     113       23147 :           vvv[i]=ptr;
+     114      199570 :           for(unsigned c=0; c<argv[i].length(); ++c) {
+     115      176423 :             *ptr=argv[i][c]; ptr++;
+     116             :           }
+     117       23147 :           *ptr=0; ptr++;
+     118             :         }
+     119        4217 :         val.set(int(run(argc,&vvv[0],in,out,comm)));
+     120             :       }
+     121        4217 :       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       12906 : }
+     128             : 
+     129             : /**
+     130             : This is the entry point to the command line tools
+     131             : included in the plumed library.
+     132             : */
+     133             : 
+     134        4217 : int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) {
+     135             :   int i;
+     136             :   bool printhelp=false;
+     137             : 
+     138        4217 :   DLLoader dlloader;
+     139             : 
+     140        4217 :   std::string root=config::getPlumedRoot();
+     141             : 
+     142             :   bool standalone_executable=false;
+     143             : 
+     144             : // Start parsing options
+     145        4217 :   std::string prefix("");
+     146        4217 :   std::string a("");
+     147        8012 :   for(i=1; i<argc; i++) {
+     148       16024 :     a=prefix+argv[i];
+     149        8012 :     if(a.length()==0) continue;
+     150       24036 :     if(a=="help" || a=="-h" || a=="--help") {
+     151             :       printhelp=true;
+     152             :       break;
+     153        8008 :     } else if(a=="--has-mpi") {
+     154           0 :       if(Communicator::initialized()) return 0;
+     155           0 :       else return 1;
+     156        8008 :     } else if(a=="--has-cregex") {
+     157           0 :       return (config::hasCregex()?0:1);
+     158        8008 :     } else if(a=="--has-dlopen") {
+     159           0 :       return (config::hasDlopen()?0:1);
+     160        8008 :     } else if(a=="--has-molfile") {
+     161           0 :       return (config::hasMolfile()?0:1);
+     162        8008 :     } else if(a=="--has-external-molfile") {
+     163           0 :       return (config::hasExternalMolfile()?0:1);
+     164        8008 :     } else if(a=="--has-zlib") {
+     165           0 :       return (config::hasZlib()?0:1);
+     166        8008 :     } else if(a=="--has-xdrfile") {
+     167             :       return 0; // always ok
+     168        8008 :     } else if(a=="--is-installed") {
+     169         638 :       return (config::isInstalled()?0:1);
+     170        7370 :     } else if(a=="--no-mpi") {
+     171             : // this is ignored, as it is parsed in main
+     172        3795 :       continue;
+     173        3575 :     } else if(a=="--mpi") {
+     174             : // this is ignored, as it is parsed in main
+     175           0 :       continue;
+     176        3575 :     } else if(a=="--standalone-executable") {
+     177             :       standalone_executable=true;
+     178        7150 :     } 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        3575 :     } else if(a=="--load") {
+     188             :       prefix="--load=";
+     189        3575 :     } 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        3579 :   if(!standalone_executable) {
+     198        3579 :     std::vector<std::string> files=Tools::ls(root);
+     199        3579 :     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        3579 :   }
+     205             : 
+     206             : // Build list of available C++ tools:
+     207        3579 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+     208             : // Build list of available shell tools:
+     209             :   std::vector<std::string> availableShell;
+     210        3579 :   if(!standalone_executable) {
+     211             :     std::vector<std::string> tmp;
+     212        7158 :     tmp=Tools::ls(std::string(root+"/scripts"));
+     213       28632 :     for(unsigned j=0; j<tmp.size(); ++j) {
+     214       25053 :       size_t ff=tmp[j].find(".sh");
+     215       25053 :       if(ff==std::string::npos) tmp[j].erase();
+     216       25053 :       else                 tmp[j].erase(ff);
+     217             :     }
+     218       28632 :     for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) availableShell.push_back(tmp[j]);
+     219        3579 :   }
+     220             : 
+     221        3579 :   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          68 :     for(unsigned j=0; j<availableCxx.size(); ++j) {
+     235         128 :       auto cl=cltoolRegister().create(CLToolOptions(availableCxx[j]));
+     236          64 :       plumed_assert(cl);
+     237         128 :       std::string manual=availableCxx[j]+" : "+cl->description();
+     238             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     239          64 :     }
+     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        3575 :   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        3575 :   std::string command(argv[i]);
+     263             : 
+     264        3575 :   if(find(availableCxx.begin(),availableCxx.end(),command)!=availableCxx.end()) {
+     265        6048 :     auto cl=cltoolRegister().create(CLToolOptions(command));
+     266        3024 :     plumed_assert(cl);
+     267             :     // Read the command line options (returns false if we are just printing help)
+     268        3024 :     if( !cl->readInput( argc-i,&argv[i],in,out ) ) { return 0; }
+     269        3024 :     int ret=cl->main(in,out,pc);
+     270             :     return ret;
+     271        3024 :   }
+     272             : 
+     273         551 :   if(find(availableShell.begin(),availableShell.end(),command)!=availableShell.end()) {
+     274         551 :     plumed_massert(in==stdin,"shell tools can only work on stdin");
+     275         551 :     plumed_massert(out==stdout,"shell tools can only work on stdin");
+     276        1102 :     std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+command+".sh\"";
+     277        2089 :     for(int j=i+1; j<argc; j++) cmd+=std::string(" ")+argv[j];
+     278         551 :     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         551 :     if(r!=0) return 1;
+     283         439 :     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        7796 : }
+     291             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func-sort-c.html b/coverage/core/CLToolRegister.cpp.func-sort-c.html new file mode 100644 index 0000000000..7404c251d4 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE293
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE3088
_ZNK4PLMD14CLToolRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3089
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3872
_ZN4PLMD14CLToolRegisterD2Ev4168
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE66688
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE66688
_ZN4PLMD14cltoolRegisterEv140337
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func.html b/coverage/core/CLToolRegister.cpp.func.html new file mode 100644 index 0000000000..b00ad35d3b --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsEE66688
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE3088
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE66688
_ZN4PLMD14CLToolRegisterD2Ev4168
_ZN4PLMD14cltoolRegisterEv140337
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE293
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3872
_ZNK4PLMD14CLToolRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3089
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.gcov.html b/coverage/core/CLToolRegister.cpp.gcov.html new file mode 100644 index 0000000000..05a8a06c4c --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05: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        4168 : CLToolRegister::~CLToolRegister() {
+      32        4168 :   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        4168 : }
+      38             : 
+      39      140337 : CLToolRegister& cltoolRegister() {
+      40      140337 :   static CLToolRegister ans;
+      41      140337 :   return ans;
+      42             : }
+      43             : 
+      44       66688 : void CLToolRegister::remove(creator_pointer f) {
+      45      483488 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      46      483488 :     if((*p).second==f) {
+      47       66688 :       m.erase(p); break;
+      48             :     }
+      49             :   }
+      50       66688 : }
+      51             : 
+      52       66688 : 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       66688 :     m.insert(std::pair<std::string,creator_pointer>(key,f));
+      58       66688 :     Keywords keys; kf(keys);
+      59       66688 :     mk.insert(std::pair<std::string,Keywords>(key,keys));
+      60       66688 :   };
+      61       66688 : }
+      62             : 
+      63        3089 : bool CLToolRegister::check(const std::string & key)const {
+      64        3088 :   if(m.count(key)>0) return true;
+      65             :   return false;
+      66             : }
+      67             : 
+      68        3088 : std::unique_ptr<CLTool> CLToolRegister::create(const CLToolOptions&ao) {
+      69        3088 :   if(ao.line.size()<1)return NULL;
+      70        3088 :   std::unique_ptr<CLTool> cltool;
+      71        3088 :   if(check(ao.line[0])) {
+      72        3088 :     CLToolOptions nao( ao,mk[ao.line[0]] );
+      73        6176 :     cltool=m[ao.line[0]](nao);
+      74             :   }
+      75             :   return cltool;
+      76        3088 : }
+      77             : 
+      78             : 
+      79         293 : std::ostream & operator<<(std::ostream &log,const CLToolRegister&ar) {
+      80         293 :   std::vector<std::string> s(ar.list());
+      81        4981 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+      82         293 :   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         293 :   return log;
+      92         293 : }
+      93             : 
+      94           1 : bool CLToolRegister::printManual( const std::string& cltool, const bool& spelling ) {
+      95           1 :   if( spelling && check(cltool) ) {
+      96           0 :     mk[cltool].print_spelling();
+      97           0 :     return true;
+      98           1 :   } else if ( check(cltool) ) {
+      99           0 :     mk[cltool].print_html();
+     100           0 :     return true;
+     101             :   } else {
+     102             :     return false;
+     103             :   }
+     104             : }
+     105             : 
+     106           0 : std::vector<std::string> CLToolRegister::getKeys(const std::string& cltool)const {
+     107           0 :   if ( check(cltool) ) {
+     108             :     return mk.find(cltool)->second.getKeys();
+     109             :   } else {
+     110             :     std::vector<std::string> empty;
+     111             :     return empty;
+     112           0 :   }
+     113             : }
+     114             : 
+     115             : 
+     116        3872 : std::vector<std::string> CLToolRegister::list()const {
+     117             :   std::vector<std::string> s;
+     118       65824 :   for(const auto & it : m) s.push_back(it.first);
+     119        3872 :   std::sort(s.begin(),s.end());
+     120        3872 :   return s;
+     121           0 : }
+     122             : 
+     123             : 
+     124             : 
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func-sort-c.html b/coverage/core/Colvar.cpp.func-sort-c.html new file mode 100644 index 0000000000..fbf73e5ba1 --- /dev/null +++ b/coverage/core/Colvar.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1898
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1915
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2286
_ZN4PLMD6Colvar5applyEv115636
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE190405
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func.html b/coverage/core/Colvar.cpp.func.html new file mode 100644 index 0000000000..bb23cbf833 --- /dev/null +++ b/coverage/core/Colvar.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2286
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1915
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE190405
_ZN4PLMD6Colvar5applyEv115636
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1898
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.gcov.html b/coverage/core/Colvar.cpp.gcov.html new file mode 100644 index 0000000000..66155efbe0 --- /dev/null +++ b/coverage/core/Colvar.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05: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        1898 : Colvar::Colvar(const ActionOptions&ao):
+      30             :   Action(ao),
+      31             :   ActionAtomistic(ao),
+      32             :   ActionWithValue(ao),
+      33        1898 :   isEnergy(false),
+      34        1898 :   isExtraCV(false)
+      35             : {
+      36        1898 : }
+      37             : 
+      38        1915 : void Colvar::registerKeywords( Keywords& keys ) {
+      39        1915 :   Action::registerKeywords( keys );
+      40        1915 :   ActionWithValue::registerKeywords( keys );
+      41        1915 :   ActionAtomistic::registerKeywords( keys );
+      42        3830 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      43        1915 : }
+      44             : 
+      45        2286 : void Colvar::requestAtoms(const std::vector<AtomNumber> & a) {
+      46        2286 :   plumed_massert(!isEnergy,"request atoms should not be called if this is energy");
+      47             : // Tell actionAtomistic what atoms we are getting
+      48        2286 :   ActionAtomistic::requestAtoms(a);
+      49             : // Resize the derivatives of all atoms
+      50        6013 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      51        2285 : }
+      52             : 
+      53      115636 : void Colvar::apply() {
+      54             :   std::vector<Vector>&   f(modifyForces());
+      55             :   Tensor&           v(modifyVirial());
+      56             :   const unsigned    nat=getNumberOfAtoms();
+      57      115636 :   const unsigned    ncp=getNumberOfComponents();
+      58      115636 :   const unsigned    fsz=f.size();
+      59             : 
+      60             :   unsigned stride=1;
+      61             :   unsigned rank=0;
+      62      115636 :   if(ncp>4*comm.Get_size()) {
+      63        1560 :     stride=comm.Get_size();
+      64        1560 :     rank=comm.Get_rank();
+      65             :   }
+      66             : 
+      67      115636 :   unsigned nt=OpenMP::getNumThreads();
+      68      115636 :   if(nt>ncp/(4*stride)) nt=1;
+      69             : 
+      70      115636 :   if(!isEnergy && !isExtraCV) {
+      71      111599 :     #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      111599 :     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        4037 :   } else if( isEnergy ) {
+     108        3989 :     std::vector<double> forces(1);
+     109        3989 :     if(getPntrToComponent(0)->applyForce(forces)) modifyForceOnEnergy()+=forces[0];
+     110          48 :   } else if( isExtraCV ) {
+     111          48 :     std::vector<double> forces(1);
+     112          48 :     if(getPntrToComponent(0)->applyForce(forces)) modifyForceOnExtraCV()+=forces[0];
+     113             :   }
+     114      115636 : }
+     115             : 
+     116      190405 : void Colvar::setBoxDerivativesNoPbc(Value* v) {
+     117      190405 :   Tensor virial;
+     118             :   unsigned nat=getNumberOfAtoms();
+     119    33615697 :   for(unsigned i=0; i<nat; i++) virial-=Tensor(getPosition(i),
+     120    16712646 :                                           Vector(v->getDerivative(3*i+0),
+     121             :                                               v->getDerivative(3*i+1),
+     122    33425292 :                                               v->getDerivative(3*i+2)));
+     123      190405 :   setBoxDerivatives(v,virial);
+     124      190405 : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func-sort-c.html b/coverage/core/Colvar.h.func-sort-c.html new file mode 100644 index 0000000000..117d22cddb --- /dev/null +++ b/coverage/core/Colvar.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarD2Ev1897
_ZN4PLMD6Colvar22getNumberOfDerivativesEv4913
_ZN4PLMD6Colvar17setBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE13257
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEv119018
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE229075
_ZN4PLMD6Colvar19setAtomsDerivativesEiRKNS_13VectorGenericILj3EEE16401018
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18212413
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func.html b/coverage/core/Colvar.h.func.html new file mode 100644 index 0000000000..fe39af8e8d --- /dev/null +++ b/coverage/core/Colvar.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE229075
_ZN4PLMD6Colvar17setBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE13257
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18212413
_ZN4PLMD6Colvar19setAtomsDerivativesEiRKNS_13VectorGenericILj3EEE16401018
_ZN4PLMD6Colvar22getNumberOfDerivativesEv4913
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEv119018
_ZN4PLMD6ColvarD2Ev1897
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.gcov.html b/coverage/core/Colvar.h.gcov.html new file mode 100644 index 0000000000..90716a71b4 --- /dev/null +++ b/coverage/core/Colvar.h.gcov.html @@ -0,0 +1,195 @@ + + + + + + + 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-05-27 13:05: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      116006 :   bool checkIsEnergy() {return isEnergy;}
+      68             :   explicit Colvar(const ActionOptions&);
+      69        1897 :   ~Colvar() {}
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   unsigned getNumberOfDerivatives() override;
+      72             : };
+      73             : 
+      74             : inline
+      75    18212413 : void Colvar::setAtomsDerivatives(Value*v,int i,const Vector&d) {
+      76    18212413 :   v->addDerivative(3*i+0,d[0]);
+      77    18212413 :   v->addDerivative(3*i+1,d[1]);
+      78    18212413 :   v->addDerivative(3*i+2,d[2]);
+      79    18212413 : }
+      80             : 
+      81             : 
+      82             : inline
+      83      229075 : void Colvar::setBoxDerivatives(Value* v,const Tensor&d) {
+      84             :   unsigned nat=getNumberOfAtoms();
+      85      229075 :   v->addDerivative(3*nat+0,d(0,0));
+      86      229075 :   v->addDerivative(3*nat+1,d(0,1));
+      87      229075 :   v->addDerivative(3*nat+2,d(0,2));
+      88      229075 :   v->addDerivative(3*nat+3,d(1,0));
+      89      229075 :   v->addDerivative(3*nat+4,d(1,1));
+      90      229075 :   v->addDerivative(3*nat+5,d(1,2));
+      91      229075 :   v->addDerivative(3*nat+6,d(2,0));
+      92      229075 :   v->addDerivative(3*nat+7,d(2,1));
+      93      229075 :   v->addDerivative(3*nat+8,d(2,2));
+      94      229075 : }
+      95             : 
+      96             : inline
+      97    16401018 : void Colvar::setAtomsDerivatives(int i,const Vector&d) {
+      98    16401018 :   setAtomsDerivatives(getPntrToValue(),i,d);
+      99    16401018 : }
+     100             : 
+     101             : inline
+     102       13257 : void Colvar::setBoxDerivatives(const Tensor&d) {
+     103       13257 :   setBoxDerivatives(getPntrToValue(),d);
+     104       13257 : }
+     105             : 
+     106             : inline
+     107      119018 : void Colvar::setBoxDerivativesNoPbc() {
+     108      119018 :   setBoxDerivativesNoPbc(getPntrToValue());
+     109      119018 : }
+     110             : 
+     111             : inline
+     112        4913 : unsigned Colvar::getNumberOfDerivatives() {
+     113        4913 :   return 3*getNumberOfAtoms() + 9;
+     114             : }
+     115             : 
+     116             : 
+     117             : }
+     118             : 
+     119             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + 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..643cd5aaa8 --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD23DataFetchingObjectTypedIdE14finishDataGrabEv254039
_ZNK4PLMD18DataFetchingObject8activateEv256426
_ZN4PLMD23DataFetchingObjectTypedIdEC2ERNS_10PlumedMainE806144
_ZN4PLMD23DataFetchingObjectTypedIdED0Ev806144
_ZN4PLMD23DataFetchingObjectTypedIdED2Ev806144
_ZN4PLMD18DataFetchingObject6createEjRNS_10PlumedMainE806145
_ZN4PLMD18DataFetchingObjectC2ERNS_10PlumedMainE806145
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataFetchingObject.cpp.func.html b/coverage/core/DataFetchingObject.cpp.func.html new file mode 100644 index 0000000000..4689e3faa9 --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObject10findActionERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE128
_ZN4PLMD18DataFetchingObject6createEjRNS_10PlumedMainE806145
_ZN4PLMD18DataFetchingObject8get_rankERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE64
_ZN4PLMD18DataFetchingObject9get_shapeERKNS_9ActionSetERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_RKNS_11TypesafePtrE0
_ZN4PLMD18DataFetchingObjectC2ERNS_10PlumedMainE806145
_ZN4PLMD23DataFetchingObjectTypedIdE14finishDataGrabEv254039
_ZN4PLMD23DataFetchingObjectTypedIdE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE64
_ZN4PLMD23DataFetchingObjectTypedIdEC2ERNS_10PlumedMainE806144
_ZN4PLMD23DataFetchingObjectTypedIdED0Ev806144
_ZN4PLMD23DataFetchingObjectTypedIdED2Ev806144
_ZN4PLMD23DataFetchingObjectTypedIfE14finishDataGrabEv0
_ZN4PLMD23DataFetchingObjectTypedIfE7setDataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_11TypesafePtrE0
_ZN4PLMD23DataFetchingObjectTypedIfEC2ERNS_10PlumedMainE1
_ZN4PLMD23DataFetchingObjectTypedIfED0Ev1
_ZN4PLMD23DataFetchingObjectTypedIfED2Ev1
_ZNK4PLMD18DataFetchingObject8activateEv256426
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataFetchingObject.cpp.gcov.html b/coverage/core/DataFetchingObject.cpp.gcov.html new file mode 100644 index 0000000000..e939f434eb --- /dev/null +++ b/coverage/core/DataFetchingObject.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + 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-05-27 13:05: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     1612290 :   ~DataFetchingObjectTyped() {}
+      41             :   void setData( const std::string& key, const std::string& type, const TypesafePtr & outval ) override;
+      42             :   void finishDataGrab() override;
+      43             : };
+      44             : 
+      45      806145 : std::unique_ptr<DataFetchingObject> DataFetchingObject::create(unsigned n, PlumedMain& p) {
+      46      806145 :   if(n==sizeof(double)) {
+      47      806144 :     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      806145 : DataFetchingObject::DataFetchingObject(PlumedMain&p):
+      56      806145 :   plumed(p)
+      57             : {
+      58      806145 : }
+      59             : 
+      60      256426 : bool DataFetchingObject::activate() const {
+      61      257066 :   for(unsigned j=0; j<myactions.size(); ++j) myactions[j]->activate();
+      62      256426 :   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      806145 : DataFetchingObjectTyped<T>::DataFetchingObjectTyped(PlumedMain&p):
+     116      806145 :   DataFetchingObject(p)
+     117             : {
+     118      806145 : }
+     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      254039 : void DataFetchingObjectTyped<T>::finishDataGrab() {
+     143             :   // Run over all values and collect data
+     144      254679 :   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      254039 : }
+     157             : 
+     158             : }
+     159             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + 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..4d2f944a93 --- /dev/null +++ b/coverage/core/DataFetchingObject.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObjectD0Ev0
_ZN4PLMD18DataFetchingObjectD2Ev806145
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataFetchingObject.h.func.html b/coverage/core/DataFetchingObject.h.func.html new file mode 100644 index 0000000000..01b20b5cb1 --- /dev/null +++ b/coverage/core/DataFetchingObject.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18DataFetchingObjectD0Ev0
_ZN4PLMD18DataFetchingObjectD2Ev806145
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataFetchingObject.h.gcov.html b/coverage/core/DataFetchingObject.h.gcov.html new file mode 100644 index 0000000000..e8a927b1bf --- /dev/null +++ b/coverage/core/DataFetchingObject.h.gcov.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05: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      806145 :   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.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func-sort-c.html b/coverage/core/ExchangePatterns.cpp.func-sort-c.html new file mode 100644 index 0000000000..c32c34c673 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev805268
_ZN4PLMD16ExchangePatternsD2Ev805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func.html b/coverage/core/ExchangePatterns.cpp.func.html new file mode 100644 index 0000000000..8f1b2ef2ff --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev805268
_ZN4PLMD16ExchangePatternsD2Ev805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.gcov.html b/coverage/core/ExchangePatterns.cpp.gcov.html new file mode 100644 index 0000000000..c66c7c00b2 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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      805268 : ExchangePatterns::ExchangePatterns():
+      28      805268 :   PatternFlag(NONE),
+      29      805268 :   NumberOfReplicas(1)
+      30      805268 : {}
+      31             : 
+      32      805268 : ExchangePatterns::~ExchangePatterns() {}
+      33             : 
+      34           0 : void ExchangePatterns::setNofR(const int nrepl) {
+      35           0 :   NumberOfReplicas=nrepl;
+      36           0 : }
+      37             : 
+      38           0 : void ExchangePatterns::setFlag(const int flag) {
+      39           0 :   PatternFlag=flag;
+      40           0 : }
+      41             : 
+      42           0 : void ExchangePatterns::getFlag(int &flag) {
+      43           0 :   flag=PatternFlag;
+      44           0 : }
+      45             : 
+      46           0 : void ExchangePatterns::setSeed(const int seed)
+      47             : {
+      48           0 :   random.setSeed(seed);
+      49           0 : }
+      50             : 
+      51           0 : void ExchangePatterns::getList(const TypesafePtr & ind)
+      52             : {
+      53           0 :   auto iind=ind.get<int*>(NumberOfReplicas);
+      54           0 :   switch(PatternFlag)
+      55             :   {
+      56             :   case RANDOM:
+      57           0 :     for(int i=0; i<NumberOfReplicas; i++) {
+      58             :       int stat=1;
+      59           0 :       while(stat) {
+      60             :         stat=0;
+      61           0 :         iind[i] = (int) (random.U01()*NumberOfReplicas);
+      62           0 :         for(int j=0; j<i; j++) if(iind[i]==iind[j]) stat=1;
+      63             :       }
+      64             :     }
+      65             :     break;
+      66             :   case NEIGHBOR:
+      67           0 :     for(int i=0; i<NumberOfReplicas; i++) iind[i]=i;
+      68             :     break;
+      69             :   }
+      70           0 : }
+      71             : 
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func-sort-c.html b/coverage/core/FlexibleBin.cpp.func-sort-c.html new file mode 100644 index 0000000000..ea5f2c0c91 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func.html b/coverage/core/FlexibleBin.cpp.func.html new file mode 100644 index 0000000000..36d42d7659 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.gcov.html b/coverage/core/FlexibleBin.cpp.gcov.html new file mode 100644 index 0000000000..dc3b856c77 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.gcov.html @@ -0,0 +1,412 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/GREX.cpp.func-sort-c.html b/coverage/core/GREX.cpp.func-sort-c.html new file mode 100644 index 0000000000..b1e261f0d7 --- /dev/null +++ b/coverage/core/GREX.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/GREX.cpp.func.html b/coverage/core/GREX.cpp.func.html new file mode 100644 index 0000000000..b25676bb9d --- /dev/null +++ b/coverage/core/GREX.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/GREX.cpp.gcov.html b/coverage/core/GREX.cpp.gcov.html new file mode 100644 index 0000000000..01529aeeff --- /dev/null +++ b/coverage/core/GREX.cpp.gcov.html @@ -0,0 +1,298 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.func-sort-c.html b/coverage/core/GenericMolInfo.cpp.func-sort-c.html new file mode 100644 index 0000000000..733dff15a7 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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:19022285.6 %
Date:2024-05-27 13:05:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZNK4PLMD14GenericMolInfo7isWholeEv2
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE25
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE87
_ZN4PLMD14GenericMolInfoD0Ev87
_ZN4PLMD14GenericMolInfoD1Ev87
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE89
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE249
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE617
_ZN4PLMD14GenericMolInfo7prepareEv5127
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE15015
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv17337
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE37702
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE47043
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE61067
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.func.html b/coverage/core/GenericMolInfo.cpp.func.html new file mode 100644 index 0000000000..a0a72e1444 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func.html @@ -0,0 +1,144 @@ + + + + + + + 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:19022285.6 %
Date:2024-05-27 13:05:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE25
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE617
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZN4PLMD14GenericMolInfo7prepareEv5127
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE87
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD0Ev87
_ZN4PLMD14GenericMolInfoD1Ev87
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv17337
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE47043
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE37702
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE15015
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE61067
_ZNK4PLMD14GenericMolInfo7isWholeEv2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.gcov.html b/coverage/core/GenericMolInfo.cpp.gcov.html new file mode 100644 index 0000000000..7768b61bbf --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.gcov.html @@ -0,0 +1,448 @@ + + + + + + + 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:19022285.6 %
Date:2024-05-27 13:05:14Functions:151883.3 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5127
_ZN4PLMD14GenericMolInfo9calculateEv5127
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func.html b/coverage/core/GenericMolInfo.h.func.html new file mode 100644 index 0000000000..270ece95a8 --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MDAtomsTypedIfE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12MDAtomsTypedIfE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERKS2_INS_13VectorGenericILj3EEESaISD_EE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZN4PLMD12MDAtomsTypedIfE13rescaleForcesERKSt6vectorIiSaIiEEd0
_ZN4PLMD12MDAtomsTypedIfE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD12MDAtomsTypedIfE18resetExtraCVNeededEv0
_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
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERS2_INS_13VectorGenericILj3EEESaISD_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE12updateVirialERKNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD12MDAtomsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD12MDAtomsTypedIfE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE6getBoxERNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE9MD2doubleERKNS_11TypesafePtrERd0
_ZNK4PLMD12MDAtomsTypedIfE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
_ZNK4PLMD12MDAtomsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrEi3
_ZNK4PLMD12MDAtomsTypedIdE15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10
_ZN4PLMD12MDAtomsTypedIdE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD12MDAtomsTypedIdE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD12MDAtomsTypedIdE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd48
_ZN4PLMD12MDAtomsTypedIdE13rescaleForcesERKSt6vectorIiSaIiEEd50
_ZN4PLMD12MDAtomsTypedIdE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE72
_ZN4PLMD12MDAtomsTypedIdE16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb72
_ZNK4PLMD12MDAtomsTypedIdE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE450
_ZNK4PLMD12MDAtomsTypedIdE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE876
_ZNK4PLMD12MDAtomsTypedIdE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE876
_ZN4PLMD12MDAtomsTypedIdE8setUnitsERKNS_5UnitsES4_1027
_ZNK4PLMD12MDAtomsTypedIdE16getRealPrecisionEv1873
_ZNK4PLMD12MDAtomsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2389
_ZNK4PLMD12MDAtomsTypedIdE9MD2doubleERKNS_11TypesafePtrERd13198
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERS2_INS_13VectorGenericILj3EEESaISD_EE25958
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERKS2_INS_13VectorGenericILj3EEESaISD_EE27027
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE27109
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE27158
_ZNK4PLMD12MDAtomsTypedIdE12updateVirialERKNS_13TensorGenericILj3ELj3EEE39613
_ZN4PLMD12MDAtomsTypedIdE4setcERKNS_11TypesafePtrE45883
_ZN4PLMD12MDAtomsTypedIdE9setVirialERKNS_11TypesafePtrE45989
_ZN4PLMD12MDAtomsTypedIdE6setBoxERKNS_11TypesafePtrE51647
_ZN4PLMDL11getPointersIKdEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj53517
_ZN4PLMDL11getPointersIdEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj54235
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrE55788
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrE55788
_ZN4PLMD12MDAtomsTypedIdE4setmERKNS_11TypesafePtrE55789
_ZNK4PLMD12MDAtomsTypedIdE6getBoxERNS_13TensorGenericILj3ELj3EEE105956
_ZN4PLMD12MDAtomsTypedIdE18resetExtraCVNeededEv256144
_ZN4PLMD11MDAtomsBase6createEj806145
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/MDAtoms.cpp.func.html b/coverage/core/MDAtoms.cpp.func.html new file mode 100644 index 0000000000..5666ca03cf --- /dev/null +++ b/coverage/core/MDAtoms.cpp.func.html @@ -0,0 +1,340 @@ + + + + + + + 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:16618191.7 %
Date:2024-05-27 13:05:14Functions:336749.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11MDAtomsBase6createEj806145
_ZN4PLMD12MDAtomsTypedIdE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE72
_ZN4PLMD12MDAtomsTypedIdE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERKS2_INS_13VectorGenericILj3EEESaISD_EE27027
_ZN4PLMD12MDAtomsTypedIdE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE27158
_ZN4PLMD12MDAtomsTypedIdE13rescaleForcesERKSt6vectorIiSaIiEEd50
_ZN4PLMD12MDAtomsTypedIdE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE30
_ZN4PLMD12MDAtomsTypedIdE16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb72
_ZN4PLMD12MDAtomsTypedIdE18resetExtraCVNeededEv256144
_ZN4PLMD12MDAtomsTypedIdE18updateExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd48
_ZN4PLMD12MDAtomsTypedIdE4setcERKNS_11TypesafePtrE45883
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrE55788
_ZN4PLMD12MDAtomsTypedIdE4setfERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE4setmERKNS_11TypesafePtrE55789
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrE55788
_ZN4PLMD12MDAtomsTypedIdE4setpERKNS_11TypesafePtrEi3
_ZN4PLMD12MDAtomsTypedIdE6setBoxERKNS_11TypesafePtrE51647
_ZN4PLMD12MDAtomsTypedIdE8setUnitsERKNS_5UnitsES4_1027
_ZN4PLMD12MDAtomsTypedIdE9setVirialERKNS_11TypesafePtrE45989
_ZN4PLMD12MDAtomsTypedIfE10getExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12MDAtomsTypedIfE10setExtraCVERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERKS2_INS_13VectorGenericILj3EEESaISD_EE0
_ZN4PLMD12MDAtomsTypedIfE12updateForcesERKSt6vectorIiSaIiEERKS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZN4PLMD12MDAtomsTypedIfE13rescaleForcesERKSt6vectorIiSaIiEEd0
_ZN4PLMD12MDAtomsTypedIfE15setExtraCVForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD12MDAtomsTypedIfE16setExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD12MDAtomsTypedIfE18resetExtraCVNeededEv0
_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_Rj53517
_ZN4PLMDL11getPointersIKfEEvRKNS_11TypesafePtrES4_S4_S4_jRPT_S7_S7_Rj0
_ZN4PLMDL11getPointersIdEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj54235
_ZN4PLMDL11getPointersIfEEvRKNS_11TypesafePtrES3_S3_S3_jRPT_S6_S6_Rj0
_ZNK4PLMD12MDAtomsTypedIdE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE876
_ZNK4PLMD12MDAtomsTypedIdE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERS2_INS_13VectorGenericILj3EEESaISD_EE25958
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIdE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE27109
_ZNK4PLMD12MDAtomsTypedIdE12updateVirialERKNS_13TensorGenericILj3ELj3EEE39613
_ZNK4PLMD12MDAtomsTypedIdE15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10
_ZNK4PLMD12MDAtomsTypedIdE16getRealPrecisionEv1873
_ZNK4PLMD12MDAtomsTypedIdE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE450
_ZNK4PLMD12MDAtomsTypedIdE6getBoxERNS_13TensorGenericILj3ELj3EEE105956
_ZNK4PLMD12MDAtomsTypedIdE9MD2doubleERKNS_11TypesafePtrERd13198
_ZNK4PLMD12MDAtomsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2389
_ZNK4PLMD12MDAtomsTypedIdE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE876
_ZNK4PLMD12MDAtomsTypedIfE10getChargesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
_ZNK4PLMD12MDAtomsTypedIfE11getMDforcesEj0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEERS2_INS_13VectorGenericILj3EEESaISD_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsERKSt6vectorIiSaIiEERS2_INS_13VectorGenericILj3EEESaIS8_EE0
_ZNK4PLMD12MDAtomsTypedIfE12getPositionsEjjRSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE12updateVirialERKNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE15isExtraCVNeededERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD12MDAtomsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD12MDAtomsTypedIfE17getLocalPositionsERSt6vectorINS_13VectorGenericILj3EEESaIS4_EE0
_ZNK4PLMD12MDAtomsTypedIfE6getBoxERNS_13TensorGenericILj3ELj3EEE0
_ZNK4PLMD12MDAtomsTypedIfE9MD2doubleERKNS_11TypesafePtrERd0
_ZNK4PLMD12MDAtomsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZNK4PLMD12MDAtomsTypedIfE9getMassesERKSt6vectorIiSaIiEERS2_IdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/MDAtoms.cpp.gcov.html b/coverage/core/MDAtoms.cpp.gcov.html new file mode 100644 index 0000000000..046e2700a4 --- /dev/null +++ b/coverage/core/MDAtoms.cpp.gcov.html @@ -0,0 +1,480 @@ + + + + + + + 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:16618191.7 %
Date:2024-05-27 13:05:14Functions:336749.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 "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      107752 : 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      107752 :   if(p) {
+      36      107714 :     auto p_=p.get<T*>({maxel,3});
+      37      107714 :     ppx=p_;
+      38      107714 :     ppy=p_+1;
+      39      107714 :     ppz=p_+2;
+      40      107714 :     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      107752 : }
+      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             :   std::map<std::string,bool> extraCVNeeded;
+      78             : public:
+      79             :   void setm(const TypesafePtr & m) override;
+      80             :   void setc(const TypesafePtr & m) override;
+      81             :   void setBox(const TypesafePtr & ) override;
+      82             :   void setp(const TypesafePtr & p) override;
+      83             :   void setVirial(const TypesafePtr & ) override;
+      84             :   void setf(const TypesafePtr & f) override;
+      85             :   void setp(const TypesafePtr & p,int i) override;
+      86             :   void setf(const TypesafePtr & f,int i) override;
+      87             :   void setUnits(const Units&,const Units&) override;
+      88          30 :   void setExtraCV(const std::string &name,const TypesafePtr & p) override {
+      89          30 :     p.get<T>(); // just check type and discard pointer
+      90          30 :     extraCV[name]=p.copy();
+      91          30 :   }
+      92          30 :   void setExtraCVForce(const std::string &name,const TypesafePtr & p) override {
+      93          30 :     p.get<T*>(); // just check type and discard pointer
+      94          30 :     extraCVForce[name]=p.copy();
+      95          30 :   }
+      96          72 :   double getExtraCV(const std::string &name) override {
+      97             :     auto search=extraCV.find(name);
+      98          72 :     if(search != extraCV.end()) {
+      99          72 :       return static_cast<double>(search->second.template get<T>());
+     100             :     } else {
+     101           0 :       plumed_error() << "Unable to access extra cv named '" << name << "'.\nNotice that extra cvs need to be calculated in the MD code.";
+     102             :     }
+     103             :   }
+     104             : 
+     105          48 :   void updateExtraCVForce(const std::string &name,double f) override {
+     106          48 :     *extraCVForce[name].template get<T*>()+=static_cast<T>(f);
+     107          48 :   }
+     108             : 
+     109          72 :   void setExtraCVNeeded(const std::string &name,bool needed=true) override {
+     110          72 :     extraCVNeeded[name]=needed;
+     111          72 :   }
+     112             : 
+     113          10 :   bool isExtraCVNeeded(const std::string &name) const override {
+     114             :     auto search=extraCVNeeded.find(name);
+     115          10 :     if(search != extraCVNeeded.end()) return search->second;
+     116             :     return false;
+     117             :   }
+     118             : 
+     119      256144 :   void resetExtraCVNeeded() override {
+     120      256171 :     for(auto & i : extraCVNeeded) i.second=false;
+     121      256144 :   }
+     122             : 
+     123       13198 :   void MD2double(const TypesafePtr & m,double&d)const override {
+     124       13198 :     d=double(m.template get<T>());
+     125       13198 :   }
+     126        2390 :   void double2MD(const double&d,const TypesafePtr & m)const override {
+     127        2390 :     m.set(T(d));
+     128        2390 :   }
+     129           0 :   Vector getMDforces(const unsigned index)const override {
+     130             :     unsigned stride;
+     131             :     const T* ffx;
+     132             :     const T* ffy;
+     133             :     const T* ffz;
+     134             :     // 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
+     135           0 :     getPointers(f,fx,fy,fz,index+1,ffx,ffy,ffz,stride);
+     136           0 :     Vector force(ffx[stride*index],ffy[stride*index],ffz[stride*index]);
+     137           0 :     return force/scalef;
+     138             :   }
+     139             :   void getBox(Tensor &) const override;
+     140             :   void getPositions(const std::vector<int>&index,std::vector<Vector>&positions) const override;
+     141             :   void getPositions(const std::vector<AtomNumber>&index,const std::vector<unsigned>&i,std::vector<Vector>&positions) const override;
+     142             :   void getPositions(unsigned j,unsigned k,std::vector<Vector>&positions) const override;
+     143             :   void getLocalPositions(std::vector<Vector>&p) const override;
+     144             :   void getMasses(const std::vector<int>&index,std::vector<double>&) const override;
+     145             :   void getCharges(const std::vector<int>&index,std::vector<double>&) const override;
+     146             :   void updateVirial(const Tensor&) const override;
+     147             :   void updateForces(const std::vector<int>&index,const std::vector<Vector>&) override;
+     148             :   void updateForces(const std::vector<AtomNumber>&index,const std::vector<unsigned>&i,const std::vector<Vector>&forces) override;
+     149             :   void rescaleForces(const std::vector<int>&index,double factor) override;
+     150             :   unsigned  getRealPrecision()const override;
+     151             : };
+     152             : 
+     153             : template <class T>
+     154        1027 : void MDAtomsTyped<T>::setUnits(const Units& units,const Units& MDUnits) {
+     155        1027 :   double lscale=units.getLength()/MDUnits.getLength();
+     156        1027 :   double escale=units.getEnergy()/MDUnits.getEnergy();
+     157        1027 :   double cscale=units.getCharge()/MDUnits.getCharge();
+     158        1027 :   double mscale=units.getMass()/MDUnits.getMass();
+     159             : // scalep and scaleb are used to convert MD to plumed
+     160        1027 :   scalep=1.0/lscale;
+     161        1027 :   scaleb=1.0/lscale;
+     162             : // scalef and scalev are used to convert plumed to MD
+     163        1027 :   scalef=escale/lscale;
+     164        1027 :   scalev=escale;
+     165        1027 :   scalec=1.0/cscale;
+     166        1027 :   scalem=1.0/mscale;
+     167        1027 : }
+     168             : 
+     169             : template <class T>
+     170      105956 : void MDAtomsTyped<T>::getBox(Tensor&box)const {
+     171      105956 :   auto b=this->box.template get<const T*>({3,3});
+     172     1328924 :   if(b) for(int i=0; i<3; i++)for(int j=0; j<3; j++) box(i,j)=b[3*i+j]*scaleb;
+     173        4042 :   else box.zero();
+     174      105956 : }
+     175             : 
+     176             : template <class T>
+     177           0 : void MDAtomsTyped<T>::getPositions(const std::vector<int>&index,std::vector<Vector>&positions)const {
+     178             :   unsigned stride;
+     179             :   const T* ppx;
+     180             :   const T* ppy;
+     181             :   const T* ppz;
+     182           0 :   getPointers(p,px,py,pz,index.size(),ppx,ppy,ppz,stride);
+     183           0 :   plumed_assert(index.size()==0 || (ppx && ppy && ppz));
+     184             : // cannot be parallelized with omp because access to positions is not ordered
+     185           0 :   for(unsigned i=0; i<index.size(); ++i) {
+     186           0 :     positions[index[i]][0]=ppx[stride*i]*scalep;
+     187           0 :     positions[index[i]][1]=ppy[stride*i]*scalep;
+     188           0 :     positions[index[i]][2]=ppz[stride*i]*scalep;
+     189             :   }
+     190           0 : }
+     191             : 
+     192             : template <class T>
+     193       25958 : void MDAtomsTyped<T>::getPositions(const std::vector<AtomNumber>&index,const std::vector<unsigned>&i, std::vector<Vector>&positions)const {
+     194             :   unsigned stride;
+     195             :   const T* ppx;
+     196             :   const T* ppy;
+     197             :   const T* ppz;
+     198             : #ifndef NDEBUG
+     199             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     200             :   const unsigned maxel=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     201             : #else
+     202             :   const unsigned maxel=0;
+     203             : #endif
+     204       25958 :   getPointers(p,px,py,pz,maxel,ppx,ppy,ppz,stride);
+     205       25958 :   plumed_assert(index.size()==0 || (ppx && ppy && ppz));
+     206             : // cannot be parallelized with omp because access to positions is not ordered
+     207             :   unsigned k=0;
+     208      403747 :   for(const auto & p : index) {
+     209      377789 :     positions[p.index()][0]=ppx[stride*i[k]]*scalep;
+     210      377789 :     positions[p.index()][1]=ppy[stride*i[k]]*scalep;
+     211      377789 :     positions[p.index()][2]=ppz[stride*i[k]]*scalep;
+     212      377789 :     k++;
+     213             :   }
+     214       25958 : }
+     215             : 
+     216             : template <class T>
+     217       27109 : void MDAtomsTyped<T>::getPositions(unsigned j,unsigned k,std::vector<Vector>&positions)const {
+     218             :   unsigned stride;
+     219             :   const T* ppx;
+     220             :   const T* ppy;
+     221             :   const T* ppz;
+     222       27109 :   getPointers(p,px,py,pz,k,ppx,ppy,ppz,stride);
+     223       27109 :   plumed_assert(k==j || (ppx && ppy && ppz));
+     224       27109 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(&positions[j],(k-j)))
+     225             :   for(unsigned i=j; i<k; ++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       27109 : }
+     231             : 
+     232             : 
+     233             : template <class T>
+     234         450 : void MDAtomsTyped<T>::getLocalPositions(std::vector<Vector>&positions)const {
+     235             :   unsigned stride;
+     236             :   const T* ppx;
+     237             :   const T* ppy;
+     238             :   const T* ppz;
+     239         450 :   getPointers(p,px,py,pz,positions.size(),ppx,ppy,ppz,stride);
+     240         450 :   plumed_assert(positions.size()==0 || (ppx && ppy && ppz));
+     241         450 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(positions))
+     242             :   for(unsigned i=0; i<positions.size(); ++i) {
+     243             :     positions[i][0]=ppx[stride*i]*scalep;
+     244             :     positions[i][1]=ppy[stride*i]*scalep;
+     245             :     positions[i][2]=ppz[stride*i]*scalep;
+     246             :   }
+     247         450 : }
+     248             : 
+     249             : 
+     250             : template <class T>
+     251         876 : void MDAtomsTyped<T>::getMasses(const std::vector<int>&index,std::vector<double>&masses)const {
+     252         876 :   auto mm=m.get<const T*>(index.size());
+     253      835240 :   if(mm) for(unsigned i=0; i<index.size(); ++i) masses[index[i]]=scalem*mm[i];
+     254           0 :   else  for(unsigned i=0; i<index.size(); ++i) masses[index[i]]=0.0;
+     255         876 : }
+     256             : 
+     257             : template <class T>
+     258         876 : void MDAtomsTyped<T>::getCharges(const std::vector<int>&index,std::vector<double>&charges)const {
+     259         876 :   auto cc=c.get<const T*>(index.size());
+     260      833653 :   if(cc) for(unsigned i=0; i<index.size(); ++i) charges[index[i]]=scalec*cc[i];
+     261        1587 :   else  for(unsigned i=0; i<index.size(); ++i) charges[index[i]]=0.0;
+     262         876 : }
+     263             : 
+     264             : template <class T>
+     265       39613 : void MDAtomsTyped<T>::updateVirial(const Tensor&virial)const {
+     266       39613 :   auto v=this->virial.template get<T*>({3,3});
+     267      514969 :   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);
+     268       39613 : }
+     269             : 
+     270             : template <class T>
+     271       27027 : void MDAtomsTyped<T>::updateForces(const std::vector<AtomNumber>&index,const std::vector<unsigned>&i,const std::vector<Vector>&forces) {
+     272             :   unsigned stride;
+     273             :   T* ffx;
+     274             :   T* ffy;
+     275             :   T* ffz;
+     276             : #ifndef NDEBUG
+     277             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     278             :   const unsigned maxel=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     279             : #else
+     280             :   const unsigned maxel=0;
+     281             : #endif
+     282       27027 :   getPointers(f,fx,fy,fz,maxel,ffx,ffy,ffz,stride);
+     283       27027 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     284             :   unsigned k=0;
+     285      399162 :   for(const auto & p : index) {
+     286      372135 :     ffx[stride*i[k]]+=scalef*T(forces[p.index()][0]);
+     287      372135 :     ffy[stride*i[k]]+=scalef*T(forces[p.index()][1]);
+     288      372135 :     ffz[stride*i[k]]+=scalef*T(forces[p.index()][2]);
+     289      372135 :     k++;
+     290             :   }
+     291       27027 : }
+     292             : 
+     293             : template <class T>
+     294       27158 : void MDAtomsTyped<T>::updateForces(const std::vector<int>&index,const std::vector<Vector>&forces) {
+     295             :   unsigned stride;
+     296             :   T* ffx;
+     297             :   T* ffy;
+     298             :   T* ffz;
+     299       27158 :   getPointers(f,fx,fy,fz,index.size(),ffx,ffy,ffz,stride);
+     300       27158 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     301       27158 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(ffx,stride*index.size()))
+     302             :   for(unsigned i=0; i<index.size(); ++i) {
+     303             :     ffx[stride*i]+=scalef*T(forces[index[i]][0]);
+     304             :     ffy[stride*i]+=scalef*T(forces[index[i]][1]);
+     305             :     ffz[stride*i]+=scalef*T(forces[index[i]][2]);
+     306             :   }
+     307       27158 : }
+     308             : 
+     309             : template <class T>
+     310          50 : void MDAtomsTyped<T>::rescaleForces(const std::vector<int>&index,double factor) {
+     311             :   unsigned stride;
+     312             :   T* ffx;
+     313             :   T* ffy;
+     314             :   T* ffz;
+     315          50 :   getPointers(f,fx,fy,fz,index.size(),ffx,ffy,ffz,stride);
+     316          50 :   plumed_assert(index.size()==0 || (ffx && ffy && ffz));
+     317          50 :   auto v=virial.get<T*>({3,3});
+     318          50 :   if(v) for(unsigned i=0; i<3; i++)for(unsigned j=0; j<3; j++) v[3*i+j]*=T(factor);
+     319          50 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(ffx,stride*index.size()))
+     320             :   for(unsigned i=0; i<index.size(); ++i) {
+     321             :     ffx[stride*i]*=T(factor);
+     322             :     ffy[stride*i]*=T(factor);
+     323             :     ffz[stride*i]*=T(factor);
+     324             :   }
+     325          50 : }
+     326             : 
+     327             : template <class T>
+     328        1873 : unsigned MDAtomsTyped<T>::getRealPrecision()const {
+     329        1873 :   return sizeof(T);
+     330             : }
+     331             : 
+     332             : template <class T>
+     333       55788 : void MDAtomsTyped<T>::setp(const TypesafePtr & pp) {
+     334       55788 :   pp.get<const T*>(); // just check type and discard pointer
+     335       55788 :   p=pp.copy();
+     336       55788 :   px=TypesafePtr();
+     337       55788 :   py=TypesafePtr();
+     338       55788 :   pz=TypesafePtr();
+     339       55788 : }
+     340             : 
+     341             : template <class T>
+     342       51647 : void MDAtomsTyped<T>::setBox(const TypesafePtr & pp) {
+     343       51647 :   pp.get<const T*>({3,3}); // just check type and size and discard pointer
+     344       51647 :   box=pp.copy();
+     345       51647 : }
+     346             : 
+     347             : 
+     348             : template <class T>
+     349       55788 : void MDAtomsTyped<T>::setf(const TypesafePtr & ff) {
+     350       55788 :   ff.get<T*>(); // just check type and discard pointer
+     351       55788 :   f=ff.copy();
+     352       55788 :   fx=TypesafePtr();
+     353       55788 :   fy=TypesafePtr();
+     354       55788 :   fz=TypesafePtr();
+     355       55788 : }
+     356             : 
+     357             : template <class T>
+     358           3 : void MDAtomsTyped<T>::setp(const TypesafePtr & pp,int i) {
+     359           3 :   p=TypesafePtr();
+     360           3 :   pp.get<const T*>(); // just check type and discard pointer
+     361           3 :   if(i==0)px=pp.copy();
+     362           3 :   if(i==1)py=pp.copy();
+     363           3 :   if(i==2)pz=pp.copy();
+     364           3 : }
+     365             : 
+     366             : template <class T>
+     367       45989 : void MDAtomsTyped<T>::setVirial(const TypesafePtr & pp) {
+     368       45989 :   pp.get<T*>({3,3}); // just check type and size and discard pointer
+     369       45987 :   virial=pp.copy();
+     370       45987 : }
+     371             : 
+     372             : 
+     373             : template <class T>
+     374           3 : void MDAtomsTyped<T>::setf(const TypesafePtr & ff,int i) {
+     375           3 :   f=TypesafePtr();;
+     376           3 :   ff.get<T*>(); // just check type and discard pointer
+     377           3 :   if(i==0)fx=ff.copy();
+     378           3 :   if(i==1)fy=ff.copy();
+     379           3 :   if(i==2)fz=ff.copy();
+     380           3 : }
+     381             : 
+     382             : template <class T>
+     383       55789 : void MDAtomsTyped<T>::setm(const TypesafePtr & m) {
+     384       55789 :   m.get<const T*>(); // just check type and discard pointer
+     385       55789 :   this->m=m.copy();
+     386       55789 : }
+     387             : 
+     388             : template <class T>
+     389       45883 : void MDAtomsTyped<T>::setc(const TypesafePtr & c) {
+     390       45883 :   c.get<const T*>(); // just check type and discard pointer
+     391       45883 :   this->c=c.copy();
+     392       45883 : }
+     393             : 
+     394      806145 : std::unique_ptr<MDAtomsBase> MDAtomsBase::create(unsigned p) {
+     395      806145 :   if(p==sizeof(double)) {
+     396      806144 :     return Tools::make_unique<MDAtomsTyped<double>>();
+     397           1 :   } else if (p==sizeof(float)) {
+     398           1 :     return Tools::make_unique<MDAtomsTyped<float>>();
+     399             :   }
+     400           0 :   plumed_error() << "Cannot create an MD interface with sizeof(real)==" << p;
+     401             : }
+     402             : 
+     403             : }
+     404             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ModuleMap.cpp.func-sort-c.html b/coverage/core/ModuleMap.cpp.func-sort-c.html new file mode 100644 index 0000000000..2f384276ea --- /dev/null +++ b/coverage/core/ModuleMap.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12getModuleMapB5cxx11Ev292
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ModuleMap.cpp.func.html b/coverage/core/ModuleMap.cpp.func.html new file mode 100644 index 0000000000..c652f9653c --- /dev/null +++ b/coverage/core/ModuleMap.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12getModuleMapB5cxx11Ev292
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ModuleMap.cpp.gcov.html b/coverage/core/ModuleMap.cpp.gcov.html new file mode 100644 index 0000000000..52ed621fad --- /dev/null +++ b/coverage/core/ModuleMap.cpp.gcov.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - plumed test coverage - core/ModuleMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ModuleMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2024-2024 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ModuleMap.h"
+      23             : 
+      24             : namespace PLMD {
+      25         292 : const std::map<std::string,std::string> & getModuleMap() {
+      26             :   static const std::map<std::string,std::string> actionToModule= {
+      27             : #include "ModuleMap.inc"
+      28         584 :   };
+      29         292 :   return actionToModule;
+      30             : }
+      31             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func-sort-c.html b/coverage/core/PlumedMain.cpp.func-sort-c.html new file mode 100644 index 0000000000..3a49546f2d --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func-sort-c.html @@ -0,0 +1,240 @@ + + + + + + + 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:64472189.3 %
Date:2024-05-27 13:05:14Functions:394292.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain21activateParseOnlyModeEv0
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMDL9testThrowEPKc38
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE358
_ZNK4PLMD10PlumedMain7getWorkEv450
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv813
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE883
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE884
_ZN4PLMD10PlumedMain4initEv1007
_ZN4PLMD10PlumedMain6fflushEv1539
_ZNK4PLMD10PlumedMain13parseOnlyModeEv1820
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3798
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev4168
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4536
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4833
_ZN4PLMD10PlumedMain6getLogEv14302
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14463
_ZN4PLMD10PlumedMain4calcEv254029
_ZN4PLMD10PlumedMain11performCalcEv254039
_ZN4PLMD10PlumedMain6updateEv254118
_ZN4PLMD10PlumedMain11prepareCalcEv256099
_ZN4PLMD10PlumedMain17backwardPropagateEv256173
_ZN4PLMD10PlumedMain9shareDataEv256183
_ZN4PLMD10PlumedMain13justCalculateEv256297
_ZN4PLMD10PlumedMain8waitDataEv256297
_ZN4PLMD10PlumedMain19prepareDependenciesEv256426
_ZN4PLMD10PlumedMainD0Ev804455
_ZN4PLMD10PlumedMainC2Ev805268
_ZN4PLMD10PlumedMainD2Ev805268
_ZN4PLMD10PlumedMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1118951
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8804428
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8805343
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func.html b/coverage/core/PlumedMain.cpp.func.html new file mode 100644 index 0000000000..b512ec14b9 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func.html @@ -0,0 +1,240 @@ + + + + + + + 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:64472189.3 %
Date:2024-05-27 13:05:14Functions:394292.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4536
_ZN4PLMD10PlumedMain11performCalcEv254039
_ZN4PLMD10PlumedMain11prepareCalcEv256099
_ZN4PLMD10PlumedMain13justCalculateEv256297
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE883
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE884
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE358
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14463
_ZN4PLMD10PlumedMain17backwardPropagateEv256173
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZN4PLMD10PlumedMain19prepareDependenciesEv256426
_ZN4PLMD10PlumedMain21activateParseOnlyModeEv0
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8804428
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8805343
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv813
_ZN4PLMD10PlumedMain3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1118951
_ZN4PLMD10PlumedMain4calcEv254029
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3798
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain4initEv1007
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain6fflushEv1539
_ZN4PLMD10PlumedMain6getLogEv14302
_ZN4PLMD10PlumedMain6updateEv254118
_ZN4PLMD10PlumedMain8waitDataEv256297
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4833
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain9shareDataEv256183
_ZN4PLMD10PlumedMainC2Ev805268
_ZN4PLMD10PlumedMainD0Ev804455
_ZN4PLMD10PlumedMainD2Ev805268
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev4168
_ZN4PLMDL9testThrowEPKc38
_ZNK4PLMD10PlumedMain13parseOnlyModeEv1820
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZNK4PLMD10PlumedMain7getWorkEv450
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.gcov.html b/coverage/core/PlumedMain.cpp.gcov.html new file mode 100644 index 0000000000..60866e03f3 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.gcov.html @@ -0,0 +1,1240 @@ + + + + + + + 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:64472189.3 %
Date:2024-05-27 13:05:14Functions:394292.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 "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          38 : [[noreturn]] static void testThrow(const char* what) {
+      70          76 :   auto words=Tools::getWords(what);
+      71          38 :   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          39 :   __PLUMED_THROW_MSG(PLMD::ExceptionError);
+      75          38 :   __PLUMED_THROW_MSG(PLMD::ExceptionDebug);
+      76          37 :   __PLUMED_THROW_MSG(PLMD::Exception);
+      77          36 :   __PLUMED_THROW_MSG(PLMD::lepton::Exception);
+      78          34 :   __PLUMED_THROW_NOMSG(std::bad_exception);
+      79             : #ifdef __PLUMED_LIBCXX11
+      80          33 :   __PLUMED_THROW_NOMSG(std::bad_array_new_length);
+      81             : #endif
+      82          32 :   __PLUMED_THROW_NOMSG(std::bad_alloc);
+      83             : #ifdef __PLUMED_LIBCXX11
+      84          31 :   __PLUMED_THROW_NOMSG(std::bad_function_call);
+      85          30 :   __PLUMED_THROW_NOMSG(std::bad_weak_ptr);
+      86             : #endif
+      87          29 :   __PLUMED_THROW_NOMSG(std::bad_cast);
+      88          28 :   __PLUMED_THROW_NOMSG(std::bad_typeid);
+      89          27 :   __PLUMED_THROW_MSG(std::underflow_error);
+      90          26 :   __PLUMED_THROW_MSG(std::overflow_error);
+      91          25 :   __PLUMED_THROW_MSG(std::range_error);
+      92          24 :   __PLUMED_THROW_MSG(std::runtime_error);
+      93          23 :   __PLUMED_THROW_MSG(std::out_of_range);
+      94          22 :   __PLUMED_THROW_MSG(std::length_error);
+      95          21 :   __PLUMED_THROW_MSG(std::domain_error);
+      96          20 :   __PLUMED_THROW_MSG(std::invalid_argument);
+      97          19 :   __PLUMED_THROW_MSG(std::logic_error);
+      98             : 
+      99             : #ifdef __PLUMED_LIBCXX11
+     100          18 :   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          14 :   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          13 :   if(words[0]=="int") {
+     124           1 :     int value=0;
+     125           1 :     if(words.size()>1) Tools::convert(words[1],value);
+     126           1 :     throw value;
+     127             :   }
+     128             : 
+     129          12 :   if(words[0]=="test_nested1") {
+     130             :     try {
+     131          12 :       throw Exception(std::string("inner ")+what);
+     132           6 :     } catch(...) {
+     133             :       try {
+     134          18 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     135           6 :       } catch(...) {
+     136          18 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     137           6 :       }
+     138           6 :     }
+     139             :   }
+     140             : 
+     141           6 :   if(words[0]=="test_nested2") {
+     142             :     try {
+     143           3 :       throw std::bad_alloc();
+     144           3 :     } catch(...) {
+     145             :       try {
+     146           9 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     147           3 :       } catch(...) {
+     148           9 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     149           3 :       }
+     150           3 :     }
+     151             :   }
+     152             : 
+     153           3 :   if(words[0]=="test_nested3") {
+     154             :     try {
+     155           2 :       throw "inner";
+     156           2 :     } catch(...) {
+     157             :       try {
+     158           6 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     159           2 :       } catch(...) {
+     160           6 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     161           2 :       }
+     162           2 :     }
+     163             :   }
+     164             : 
+     165           2 :   plumed_error() << "unknown exception " << what;
+     166          38 : }
+     167             : 
+     168             : namespace {
+     169             : // This is an internal tool used to count how many PlumedMain objects have been created
+     170             : // and if they were correctly destroyed.
+     171             : // When using debug options, it leads to a crash
+     172             : // Otherwise, it just prints a message
+     173             : class CountInstances {
+     174             :   std::atomic<int> counter{};
+     175             : public:
+     176             :   void increase() noexcept {
+     177             :     ++counter;
+     178             :   }
+     179             :   void decrease() noexcept {
+     180             :     --counter;
+     181             :   }
+     182        4168 :   ~CountInstances() {
+     183        4168 :     if(counter!=0) {
+     184           0 :       std::cerr<<"WARNING: internal inconsistency in allocated PlumedMain instances (" <<counter<< ")\n";
+     185             : #ifndef NDEBUG
+     186             :       std::abort();
+     187             : #endif
+     188             :     }
+     189        4168 :   }
+     190             : };
+     191             : static CountInstances countInstances;
+     192             : }
+     193             : 
+     194             : 
+     195      805268 : PlumedMain::PlumedMain():
+     196      805268 :   initialized(false),
+     197             : // automatically write on log in destructor
+     198      805268 :   stopwatch_fwd(log),
+     199      805268 :   step(0),
+     200      805268 :   active(false),
+     201      805268 :   mydatafetcher(DataFetchingObject::create(sizeof(double),*this)),
+     202      805268 :   endPlumed(false),
+     203      805268 :   atoms_fwd(*this),
+     204      805268 :   actionSet_fwd(*this),
+     205      805268 :   bias(0.0),
+     206      805268 :   work(0.0),
+     207      805268 :   exchangeStep(false),
+     208      805268 :   restart(false),
+     209      805268 :   doCheckPoint(false),
+     210      805268 :   doParseOnly(false),
+     211      805268 :   stopNow(false),
+     212      805268 :   novirial(false),
+     213      805268 :   detailedTimers(false),
+     214     1610536 :   gpuDeviceId(-1)
+     215             : {
+     216      805268 :   increaseReferenceCounter();
+     217      805268 :   log.link(comm);
+     218     1610536 :   log.setLinePrefix("PLUMED: ");
+     219             :   // this is at last so as to avoid inconsistencies if an exception is thrown
+     220             :   countInstances.increase(); // noexcept
+     221      805268 : }
+     222             : 
+     223             : // destructor needed to delete forward declarated objects
+     224     1609723 : PlumedMain::~PlumedMain() {
+     225             :   countInstances.decrease();
+     226     3220259 : }
+     227             : 
+     228             : /////////////////////////////////////////////////////////////
+     229             : //  MAIN INTERPRETER
+     230             : 
+     231             : #define CHECK_INIT(ini,word) plumed_massert(ini,"cmd(\"" + word +"\") should be only used after plumed initialization")
+     232             : #define CHECK_NOTINIT(ini,word) plumed_massert(!(ini),"cmd(\"" + word +"\") should be only used before plumed initialization")
+     233             : #define CHECK_NOTNULL(val,word) plumed_massert(val,"NULL pointer received in cmd(\"" + word + "\")");
+     234             : 
+     235             : 
+     236     1118951 : void PlumedMain::cmd(const std::string & word,const TypesafePtr & val) {
+     237             : 
+     238             : // Enumerate all possible commands:
+     239             :   enum {
+     240             : #include "PlumedMainEnum.inc"
+     241             :   };
+     242             : 
+     243             : // Static object (initialized once) containing the map of commands:
+     244             :   const static std::unordered_map<std::string, int> word_map = {
+     245             : #include "PlumedMainMap.inc"
+     246     1454939 :   };
+     247             : 
+     248             :   try {
+     249             : 
+     250     1118951 :     auto ss=stopwatch.startPause();
+     251             : 
+     252     1118951 :     std::vector<std::string> words=Tools::getWords(word);
+     253     1118951 :     unsigned nw=words.size();
+     254     1118951 :     if(nw==0) {
+     255             :       // do nothing
+     256             :     } else {
+     257             :       int iword=-1;
+     258             :       double d;
+     259             :       const auto it=word_map.find(words[0]);
+     260     1118951 :       if(it!=word_map.end()) iword=it->second;
+     261     1118944 :       switch(iword) {
+     262       51647 :       case cmd_setBox:
+     263       51647 :         CHECK_INIT(initialized,word);
+     264       51647 :         CHECK_NOTNULL(val,word);
+     265       51647 :         atoms.setBox(val);
+     266             :         break;
+     267       55788 :       case cmd_setPositions:
+     268       55788 :         CHECK_INIT(initialized,word);
+     269       55788 :         atoms.setPositions(val);
+     270             :         break;
+     271       55792 :       case cmd_setMasses:
+     272       55792 :         CHECK_INIT(initialized,word);
+     273       55792 :         atoms.setMasses(val);
+     274             :         break;
+     275       45883 :       case cmd_setCharges:
+     276       45883 :         CHECK_INIT(initialized,word);
+     277       45883 :         atoms.setCharges(val);
+     278             :         break;
+     279           1 :       case cmd_setPositionsX:
+     280           1 :         CHECK_INIT(initialized,word);
+     281           1 :         atoms.setPositions(val,0);
+     282             :         break;
+     283           1 :       case cmd_setPositionsY:
+     284           1 :         CHECK_INIT(initialized,word);
+     285           1 :         atoms.setPositions(val,1);
+     286             :         break;
+     287           1 :       case cmd_setPositionsZ:
+     288           1 :         CHECK_INIT(initialized,word);
+     289           1 :         atoms.setPositions(val,2);
+     290             :         break;
+     291       45989 :       case cmd_setVirial:
+     292       45989 :         CHECK_INIT(initialized,word);
+     293       45989 :         CHECK_NOTNULL(val,word);
+     294       45989 :         atoms.setVirial(val);
+     295             :         break;
+     296        9792 :       case cmd_setEnergy:
+     297        9792 :         CHECK_INIT(initialized,word);
+     298        9792 :         CHECK_NOTNULL(val,word);
+     299        9792 :         atoms.setEnergy(val);
+     300             :         break;
+     301       55788 :       case cmd_setForces:
+     302       55788 :         CHECK_INIT(initialized,word);
+     303       55788 :         atoms.setForces(val);
+     304             :         break;
+     305           1 :       case cmd_setForcesX:
+     306           1 :         CHECK_INIT(initialized,word);
+     307           1 :         atoms.setForces(val,0);
+     308             :         break;
+     309           1 :       case cmd_setForcesY:
+     310           1 :         CHECK_INIT(initialized,word);
+     311           1 :         atoms.setForces(val,1);
+     312             :         break;
+     313           1 :       case cmd_setForcesZ:
+     314           1 :         CHECK_INIT(initialized,word);
+     315           1 :         atoms.setForces(val,2);
+     316             :         break;
+     317      254029 :       case cmd_calc:
+     318      254029 :         CHECK_INIT(initialized,word);
+     319      254029 :         calc();
+     320             :         break;
+     321          99 :       case cmd_prepareDependencies:
+     322          99 :         CHECK_INIT(initialized,word);
+     323          99 :         prepareDependencies();
+     324             :         break;
+     325          84 :       case cmd_shareData:
+     326          84 :         CHECK_INIT(initialized,word);
+     327          84 :         shareData();
+     328             :         break;
+     329        2070 :       case cmd_prepareCalc:
+     330        2070 :         CHECK_INIT(initialized,word);
+     331        2070 :         prepareCalc();
+     332             :         break;
+     333          10 :       case cmd_performCalc:
+     334          10 :         CHECK_INIT(initialized,word);
+     335          10 :         performCalc();
+     336             :         break;
+     337        2134 :       case cmd_performCalcNoUpdate:
+     338        2134 :         CHECK_INIT(initialized,word);
+     339        2134 :         performCalcNoUpdate();
+     340             :         break;
+     341          10 :       case cmd_performCalcNoForces:
+     342          10 :         CHECK_INIT(initialized,word);
+     343          10 :         performCalcNoForces();
+     344             :         break;
+     345          79 :       case cmd_update:
+     346          79 :         CHECK_INIT(initialized,word);
+     347          79 :         update();
+     348             :         break;
+     349        6090 :       case cmd_setStep:
+     350        6090 :         CHECK_INIT(initialized,word);
+     351        6096 :         CHECK_NOTNULL(val,word);
+     352        6087 :         step=val.get<int>();
+     353        6087 :         atoms.startStep();
+     354             :         break;
+     355           0 :       case cmd_setStepLong:
+     356           0 :         CHECK_INIT(initialized,word);
+     357           0 :         CHECK_NOTNULL(val,word);
+     358           0 :         step=val.get<long int>();
+     359           0 :         atoms.startStep();
+     360             :         break;
+     361      250057 :       case cmd_setStepLongLong:
+     362      250057 :         CHECK_INIT(initialized,word);
+     363      250057 :         CHECK_NOTNULL(val,word);
+     364      250057 :         step=val.get<long long int>();
+     365      250057 :         atoms.startStep();
+     366             :         break;
+     367             :       // words used less frequently:
+     368        1140 :       case cmd_setAtomsNlocal:
+     369        1140 :         CHECK_INIT(initialized,word);
+     370        1140 :         CHECK_NOTNULL(val,word);
+     371        1140 :         atoms.setAtomsNlocal(val.get<int>());
+     372             :         break;
+     373         988 :       case cmd_setAtomsGatindex:
+     374         988 :         CHECK_INIT(initialized,word);
+     375         988 :         atoms.setAtomsGatindex(val,false);
+     376             :         break;
+     377           0 :       case cmd_setAtomsFGatindex:
+     378           0 :         CHECK_INIT(initialized,word);
+     379           0 :         atoms.setAtomsGatindex(val,true);
+     380             :         break;
+     381         152 :       case cmd_setAtomsContiguous:
+     382         152 :         CHECK_INIT(initialized,word);
+     383         152 :         CHECK_NOTNULL(val,word);
+     384         152 :         atoms.setAtomsContiguous(val.get<int>());
+     385             :         break;
+     386         116 :       case cmd_createFullList:
+     387         116 :         CHECK_INIT(initialized,word);
+     388         116 :         CHECK_NOTNULL(val,word);
+     389         116 :         atoms.createFullList(val);
+     390             :         break;
+     391         116 :       case cmd_getFullList:
+     392         116 :         CHECK_INIT(initialized,word);
+     393         116 :         CHECK_NOTNULL(val,word);
+     394         116 :         atoms.getFullList(val);
+     395             :         break;
+     396         116 :       case cmd_clearFullList:
+     397         116 :         CHECK_INIT(initialized,word);
+     398         116 :         atoms.clearFullList();
+     399             :         break;
+     400             :       /* ADDED WITH API==6 */
+     401          64 :       case cmd_getDataRank:
+     402          64 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     403         128 :         if( nw==2 ) DataFetchingObject::get_rank( actionSet, words[1], "", val);
+     404           0 :         else DataFetchingObject::get_rank( actionSet, words[1], words[2], val);
+     405             :         break;
+     406             :       /* ADDED WITH API==6 */
+     407           0 :       case cmd_getDataShape:
+     408           0 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     409           0 :         if( nw==2 ) DataFetchingObject::get_shape( actionSet, words[1], "", val );
+     410           0 :         else DataFetchingObject::get_shape( actionSet, words[1], words[2], val );
+     411             :         break;
+     412             :       /* ADDED WITH API==6 */
+     413          64 :       case cmd_setMemoryForData:
+     414          64 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     415         128 :         if( nw==2 ) mydatafetcher->setData( words[1], "", val );
+     416           0 :         else mydatafetcher->setData( words[1], words[2], val );
+     417             :         break;
+     418             :       /* ADDED WITH API==6 */
+     419             :       case cmd_setErrorHandler:
+     420             :       {
+     421           0 :         if(val) error_handler=*static_cast<const plumed_error_handler*>(val.get<const void*>());
+     422           0 :         else error_handler.handler=NULL;
+     423             :       }
+     424             :       break;
+     425           0 :       case cmd_read:
+     426           0 :         CHECK_INIT(initialized,word);
+     427           0 :         if(val)readInputFile(val.get<const char*>());
+     428           0 :         else   readInputFile("plumed.dat");
+     429             :         break;
+     430         274 :       case cmd_readInputLine:
+     431         274 :         CHECK_INIT(initialized,word);
+     432         274 :         CHECK_NOTNULL(val,word);
+     433         274 :         readInputLine(val.get<const char*>());
+     434         234 :         break;
+     435           1 :       case cmd_readInputLines:
+     436           1 :         CHECK_INIT(initialized,word);
+     437           1 :         CHECK_NOTNULL(val,word);
+     438           1 :         readInputLines(val.get<const char*>());
+     439           1 :         break;
+     440           1 :       case cmd_clear:
+     441           1 :         CHECK_INIT(initialized,word);
+     442           1 :         actionSet.clearDelete();
+     443             :         break;
+     444             :       case cmd_getApiVersion:
+     445          42 :         CHECK_NOTNULL(val,word);
+     446          42 :         val.set(int(10));
+     447             :         break;
+     448             :       // commands which can be used only before initialization:
+     449        1007 :       case cmd_init:
+     450        1007 :         CHECK_NOTINIT(initialized,word);
+     451        1007 :         init();
+     452             :         break;
+     453         878 :       case cmd_setRealPrecision:
+     454         878 :         CHECK_NOTINIT(initialized,word);
+     455         878 :         CHECK_NOTNULL(val,word);
+     456         878 :         atoms.setRealPrecision(val.get<int>());
+     457        1754 :         mydatafetcher=DataFetchingObject::create(val.get<int>(),*this);
+     458         877 :         break;
+     459         810 :       case cmd_setMDLengthUnits:
+     460         810 :         CHECK_NOTINIT(initialized,word);
+     461         810 :         CHECK_NOTNULL(val,word);
+     462         810 :         atoms.MD2double(val,d);
+     463         810 :         atoms.setMDLengthUnits(d);
+     464             :         break;
+     465         810 :       case cmd_setMDChargeUnits:
+     466         810 :         CHECK_NOTINIT(initialized,word);
+     467         810 :         CHECK_NOTNULL(val,word);
+     468         810 :         atoms.MD2double(val,d);
+     469         810 :         atoms.setMDChargeUnits(d);
+     470             :         break;
+     471         810 :       case cmd_setMDMassUnits:
+     472         810 :         CHECK_NOTINIT(initialized,word);
+     473         810 :         CHECK_NOTNULL(val,word);
+     474         810 :         atoms.MD2double(val,d);
+     475         810 :         atoms.setMDMassUnits(d);
+     476             :         break;
+     477          45 :       case cmd_setMDEnergyUnits:
+     478          45 :         CHECK_NOTINIT(initialized,word);
+     479          45 :         CHECK_NOTNULL(val,word);
+     480          45 :         atoms.MD2double(val,d);
+     481          45 :         atoms.setMDEnergyUnits(d);
+     482             :         break;
+     483           6 :       case cmd_setMDTimeUnits:
+     484           6 :         CHECK_NOTINIT(initialized,word);
+     485           6 :         CHECK_NOTNULL(val,word);
+     486           6 :         atoms.MD2double(val,d);
+     487           6 :         atoms.setMDTimeUnits(d);
+     488             :         break;
+     489           0 :       case cmd_setNaturalUnits:
+     490             :         // set the boltzman constant for MD in natural units (kb=1)
+     491             :         // only needed in LJ codes if the MD is passing temperatures to plumed (so, not yet...)
+     492             :         // use as cmd("setNaturalUnits")
+     493           0 :         CHECK_NOTINIT(initialized,word);
+     494           0 :         atoms.setMDNaturalUnits(true);
+     495             :         break;
+     496          52 :       case cmd_setNoVirial:
+     497          52 :         CHECK_NOTINIT(initialized,word);
+     498          52 :         novirial=true;
+     499          52 :         break;
+     500         865 :       case cmd_setPlumedDat:
+     501         865 :         CHECK_NOTINIT(initialized,word);
+     502         865 :         CHECK_NOTNULL(val,word);
+     503         865 :         plumedDat=val.get<const char*>();
+     504             :         break;
+     505         339 :       case cmd_setMPIComm:
+     506         339 :         CHECK_NOTINIT(initialized,word);
+     507         339 :         comm.Set_comm(val);
+     508         339 :         atoms.setDomainDecomposition(comm);
+     509             :         break;
+     510           0 :       case cmd_setMPIFComm:
+     511           0 :         CHECK_NOTINIT(initialized,word);
+     512           0 :         comm.Set_fcomm(val);
+     513           0 :         atoms.setDomainDecomposition(comm);
+     514             :         break;
+     515           0 :       case cmd_setMPImultiSimComm:
+     516           0 :         CHECK_NOTINIT(initialized,word);
+     517           0 :         multi_sim_comm.Set_comm(val);
+     518             :         break;
+     519         990 :       case cmd_setNatoms:
+     520         990 :         CHECK_NOTINIT(initialized,word);
+     521         990 :         CHECK_NOTNULL(val,word);
+     522         990 :         atoms.setNatoms(val.get<int>());
+     523             :         break;
+     524         866 :       case cmd_setTimestep:
+     525         866 :         CHECK_NOTINIT(initialized,word);
+     526         866 :         CHECK_NOTNULL(val,word);
+     527         866 :         atoms.setTimeStep(val);
+     528             :         break;
+     529             :       /* ADDED WITH API==2 */
+     530          59 :       case cmd_setKbT:
+     531          59 :         CHECK_NOTINIT(initialized,word);
+     532          59 :         CHECK_NOTNULL(val,word);
+     533          59 :         atoms.setKbT(val);
+     534             :         break;
+     535             :       /* ADDED WITH API==3 */
+     536           8 :       case cmd_setRestart:
+     537           8 :         CHECK_NOTINIT(initialized,word);
+     538           8 :         CHECK_NOTNULL(val,word);
+     539           8 :         if(val.get<int>()!=0) restart=true;
+     540             :         break;
+     541             :       /* ADDED WITH API==4 */
+     542           0 :       case cmd_doCheckPoint:
+     543           0 :         CHECK_INIT(initialized,word);
+     544           0 :         CHECK_NOTNULL(val,word);
+     545           0 :         doCheckPoint = false;
+     546           0 :         if(val.get<int>()!=0) doCheckPoint = true;
+     547             :         break;
+     548             :       /* ADDED WITH API==6 */
+     549             :       case cmd_setNumOMPthreads:
+     550           0 :         CHECK_NOTNULL(val,word);
+     551             :         {
+     552           0 :           auto nt=val.get<unsigned>();
+     553             :           if(nt==0) nt=1;
+     554           0 :           OpenMP::setNumThreads(nt);
+     555             :         }
+     556             :         break;
+     557             :       /* ADDED WITH API==10 */
+     558             :       case cmd_setGpuDeviceId:
+     559           0 :         CHECK_NOTNULL(val,word);
+     560             :         {
+     561           0 :           auto id=val.get<int>();
+     562           0 :           if(id>=0) gpuDeviceId=id;
+     563             :         }
+     564             :         break;
+     565             :       /* ADDED WITH API==6 */
+     566             :       /* only used for testing */
+     567             :       case cmd_throw:
+     568          38 :         CHECK_NOTNULL(val,word);
+     569          38 :         testThrow(val.get<const char*>());
+     570             :       /* ADDED WITH API==10 */
+     571             :       case cmd_setNestedExceptions:
+     572          25 :         CHECK_NOTNULL(val,word);
+     573          25 :         if(val.get<int>()!=0) nestedExceptions=true;
+     574           1 :         else nestedExceptions=false;
+     575             :         break;
+     576             :       /* STOP API */
+     577         863 :       case cmd_setMDEngine:
+     578         863 :         CHECK_NOTINIT(initialized,word);
+     579         863 :         CHECK_NOTNULL(val,word);
+     580         863 :         MDEngine=val.get<const char*>();
+     581             :         break;
+     582         850 :       case cmd_setLog:
+     583         850 :         CHECK_NOTINIT(initialized,word);
+     584         850 :         log.link(val.get<FILE*>());
+     585             :         break;
+     586          53 :       case cmd_setLogFile:
+     587          53 :         CHECK_NOTINIT(initialized,word);
+     588          53 :         CHECK_NOTNULL(val,word);
+     589         152 :         log.open(val.get<const char*>());
+     590          53 :         break;
+     591             :       // other commands that should be used after initialization:
+     592      253956 :       case cmd_setStopFlag:
+     593      253956 :         CHECK_INIT(initialized,word);
+     594      253956 :         CHECK_NOTNULL(val,word);
+     595      253956 :         val.get<int*>(); // just check type and discard pointer
+     596      253955 :         stopFlag=val.copy();
+     597      253955 :         break;
+     598           0 :       case cmd_getExchangesFlag:
+     599           0 :         CHECK_INIT(initialized,word);
+     600           0 :         CHECK_NOTNULL(val,word);
+     601           0 :         exchangePatterns.getFlag(*val.get<int*>()); // note: getFlag changes the value of the reference!
+     602             :         break;
+     603           0 :       case cmd_setExchangesSeed:
+     604           0 :         CHECK_INIT(initialized,word);
+     605           0 :         CHECK_NOTNULL(val,word);
+     606           0 :         exchangePatterns.setSeed(val.get<int>());
+     607             :         break;
+     608           0 :       case cmd_setNumberOfReplicas:
+     609           0 :         CHECK_INIT(initialized,word);
+     610           0 :         CHECK_NOTNULL(val,word);
+     611           0 :         exchangePatterns.setNofR(val.get<int>());
+     612             :         break;
+     613           0 :       case cmd_getExchangesList:
+     614           0 :         CHECK_INIT(initialized,word);
+     615           0 :         CHECK_NOTNULL(val,word);
+     616           0 :         exchangePatterns.getList(val.get<int*>());
+     617           0 :         break;
+     618         813 :       case cmd_runFinalJobs:
+     619         813 :         CHECK_INIT(initialized,word);
+     620         813 :         runJobsAtEndOfCalculation();
+     621             :         break;
+     622          96 :       case cmd_isEnergyNeeded:
+     623          96 :         CHECK_INIT(initialized,word);
+     624          96 :         CHECK_NOTNULL(val,word);
+     625          96 :         if(atoms.isEnergyNeeded()) val.set(int(1));
+     626          96 :         else                       val.set(int(0));
+     627             :         break;
+     628        2172 :       case cmd_getBias:
+     629        2172 :         CHECK_INIT(initialized,word);
+     630        2172 :         CHECK_NOTNULL(val,word);
+     631        2172 :         atoms.double2MD(getBias()/(atoms.getMDUnits().getEnergy()/atoms.getUnits().getEnergy()),val);
+     632        2172 :         break;
+     633             :       case cmd_checkAction:
+     634           2 :         CHECK_NOTNULL(val,word);
+     635           2 :         plumed_assert(nw==2);
+     636           3 :         val.set(int(actionRegister().check(words[1]) ? 1:0));
+     637             :         break;
+     638             :       case cmd_setExtraCV:
+     639          30 :         CHECK_NOTNULL(val,word);
+     640          30 :         plumed_assert(nw==2);
+     641          30 :         atoms.setExtraCV(words[1],val);
+     642             :         break;
+     643             :       case cmd_setExtraCVForce:
+     644          30 :         CHECK_NOTNULL(val,word);
+     645          30 :         plumed_assert(nw==2);
+     646          30 :         atoms.setExtraCVForce(words[1],val);
+     647             :         break;
+     648             :       /* ADDED WITH API==10 */
+     649             :       case cmd_isExtraCVNeeded:
+     650          10 :         CHECK_NOTNULL(val,word);
+     651          10 :         plumed_assert(nw==2);
+     652          10 :         if(atoms.isExtraCVNeeded(words[1])) val.set(int(1));
+     653           6 :         else                                val.set(int(0));
+     654             :         break;
+     655        1077 :       case cmd_GREX:
+     656        1077 :         if(!grex) grex=Tools::make_unique<GREX>(*this);
+     657        1077 :         plumed_massert(grex,"error allocating grex");
+     658             :         {
+     659        1077 :           std::string kk=words[1];
+     660        1248 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+words[i];
+     661        2154 :           grex->cmd(kk.c_str(),val);
+     662             :         }
+     663        1077 :         break;
+     664       12906 :       case cmd_CLTool:
+     665       12906 :         CHECK_NOTINIT(initialized,word);
+     666       12906 :         if(!cltool) cltool=Tools::make_unique<CLToolMain>();
+     667             :         {
+     668       12906 :           std::string kk=words[1];
+     669       12906 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+words[i];
+     670       25812 :           cltool->cmd(kk.c_str(),val);
+     671             :         }
+     672             :         break;
+     673             :       /* ADDED WITH API==7 */
+     674             :       case cmd_convert:
+     675             :       {
+     676             :         double v;
+     677          57 :         plumed_assert(words.size()==2);
+     678          57 :         if(Tools::convertNoexcept(words[1],v)) atoms.double2MD(v,val);
+     679             :       }
+     680          57 :       break;
+     681           7 :       default:
+     682          21 :         plumed_merror("cannot interpret cmd(\"" + word + "\"). check plumed developers manual to see the available commands.");
+     683             :         break;
+     684             :       }
+     685             :     }
+     686             : 
+     687     1119149 :   } catch (...) {
+     688          99 :     if(log.isOpen()) {
+     689             :       try {
+     690          54 :         log<<"\n################################################################################\n";
+     691          54 :         log<<Tools::concatenateExceptionMessages();
+     692          54 :         log<<"\n################################################################################\n";
+     693          54 :         log.flush();
+     694           0 :       } catch(...) {
+     695             :         // ignore errors here.
+     696             :         // in any case, we are rethrowing this below
+     697           0 :       }
+     698             :     }
+     699          99 :     throw;
+     700          99 :   }
+     701     1118852 : }
+     702             : 
+     703             : ////////////////////////////////////////////////////////////////////////
+     704             : 
+     705        1007 : void PlumedMain::init() {
+     706             : // check that initialization just happens once
+     707        1007 :   initialized=true;
+     708        1007 :   atoms.init();
+     709        1007 :   if(!log.isOpen()) log.link(stdout);
+     710        1007 :   log<<"PLUMED is starting\n";
+     711        3021 :   log<<"Version: "<<config::getVersionLong()<<" (git: "<<config::getVersionGit()<<") "
+     712        4028 :      <<"compiled on " <<config::getCompilationDate() << " at " << config::getCompilationTime() << "\n";
+     713        1007 :   log<<"Please cite these papers when using PLUMED ";
+     714        2014 :   log<<cite("The PLUMED consortium, Nat. Methods 16, 670 (2019)");
+     715        2014 :   log<<cite("Tribello, Bonomi, Branduardi, Camilloni, and Bussi, Comput. Phys. Commun. 185, 604 (2014)");
+     716        1007 :   log<<"\n";
+     717        1007 :   log<<"For further information see the PLUMED web page at http://www.plumed.org\n";
+     718        1007 :   log<<"Root: "<<config::getPlumedRoot()<<"\n";
+     719        2014 :   log<<"For installed feature, see "<<config::getPlumedRoot() + "/src/config/config.txt\n";
+     720        1007 :   log.printf("Molecular dynamics engine: %s\n",MDEngine.c_str());
+     721        1007 :   log.printf("Precision of reals: %d\n",atoms.getRealPrecision());
+     722        1788 :   log.printf("Running over %d %s\n",comm.Get_size(),(comm.Get_size()>1?"nodes":"node"));
+     723        1007 :   log<<"Number of threads: "<<OpenMP::getNumThreads()<<"\n";
+     724        1007 :   log<<"Cache line size: "<<OpenMP::getCachelineSize()<<"\n";
+     725        1007 :   log.printf("Number of atoms: %d\n",atoms.getNatoms());
+     726        1007 :   if(grex) log.printf("GROMACS-like replica exchange is on\n");
+     727        1007 :   log.printf("File suffix: %s\n",getSuffix().c_str());
+     728        1007 :   if(plumedDat.length()>0) {
+     729         865 :     readInputFile(plumedDat);
+     730             :     plumedDat="";
+     731             :   }
+     732        1007 :   atoms.updateUnits();
+     733        1007 :   log.printf("Timestep: %f\n",atoms.getTimeStep());
+     734        1007 :   if(atoms.getKbT()>0.0)
+     735          53 :     log.printf("KbT: %f\n",atoms.getKbT());
+     736             :   else {
+     737         954 :     log.printf("KbT has not been set by the MD engine\n");
+     738         954 :     log.printf("It should be set by hand where needed\n");
+     739             :   }
+     740        1007 :   log<<"Relevant bibliography:\n";
+     741        1007 :   log<<citations;
+     742        1007 :   log<<"Please read and cite where appropriate!\n";
+     743        1007 :   log<<"Finished setup\n";
+     744        1007 : }
+     745             : 
+     746         883 : void PlumedMain::readInputFile(const std::string & str) {
+     747         883 :   plumed_assert(initialized);
+     748         883 :   log<<"FILE: "<<str<<"\n";
+     749         883 :   IFile ifile;
+     750         883 :   ifile.link(*this);
+     751         883 :   ifile.open(str);
+     752         883 :   ifile.allowNoEOL();
+     753         883 :   readInputFile(ifile);
+     754         883 :   log<<"END FILE: "<<str<<"\n";
+     755         883 :   log.flush();
+     756             : 
+     757         883 : }
+     758             : 
+     759         884 : void PlumedMain::readInputFile(IFile & ifile) {
+     760             :   std::vector<std::string> words;
+     761       14963 :   while(Tools::getParsedLine(ifile,words) && !endPlumed) readInputWords(words);
+     762         884 :   endPlumed=false;
+     763         884 :   pilots=actionSet.select<ActionPilot*>();
+     764         884 : }
+     765             : 
+     766         358 : void PlumedMain::readInputLine(const std::string & str) {
+     767         358 :   plumed_assert(initialized);
+     768         358 :   if(str.empty()) return;
+     769         358 :   std::vector<std::string> words=Tools::getWords(str);
+     770         358 :   citations.clear();
+     771         358 :   readInputWords(words);
+     772         318 :   if(!citations.empty()) {
+     773           2 :     log<<"Relevant bibliography:\n";
+     774           2 :     log<<citations;
+     775           2 :     log<<"Please read and cite where appropriate!\n";
+     776             :   }
+     777         358 : }
+     778             : 
+     779           1 : void PlumedMain::readInputLines(const std::string & str) {
+     780           1 :   plumed_assert(initialized);
+     781           1 :   if(str.empty()) return;
+     782             : 
+     783           1 :   log<<"FILE: (temporary)\n";
+     784             : 
+     785             :   // Open a temporary file
+     786           1 :   auto fp=std::tmpfile();
+     787           1 :   plumed_assert(fp);
+     788             : 
+     789             :   // make sure file is closed (and thus deleted) also if an exception occurs
+     790           1 :   auto deleter=[](FILE* fp) { std::fclose(fp); };
+     791             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     792             : 
+     793           1 :   auto ret=std::fputs(str.c_str(),fp);
+     794           1 :   plumed_assert(ret!=EOF);
+     795             : 
+     796           1 :   std::rewind(fp);
+     797             : 
+     798           1 :   IFile ifile;
+     799           1 :   ifile.link(*this);
+     800           1 :   ifile.link(fp);
+     801           1 :   ifile.allowNoEOL();
+     802             : 
+     803           1 :   readInputFile(ifile);
+     804           1 :   log<<"END FILE: (temporary)\n";
+     805           1 : }
+     806             : 
+     807       14463 : void PlumedMain::readInputWords(const std::vector<std::string> & words) {
+     808       14463 :   plumed_assert(initialized);
+     809       14463 :   if(words.empty())return;
+     810       14307 :   else if(words[0]=="_SET_SUFFIX") {
+     811           3 :     plumed_assert(words.size()==2);
+     812             :     setSuffix(words[1]);
+     813             :   } else {
+     814       14304 :     std::vector<std::string> interpreted(words);
+     815       14304 :     Tools::interpretLabel(interpreted);
+     816       28570 :     auto action=actionRegister().create(ActionOptions(*this,interpreted));
+     817       14266 :     if(!action) {
+     818             :       std::string msg;
+     819             :       msg ="ERROR\nI cannot understand line:";
+     820          10 :       for(unsigned i=0; i<interpreted.size(); ++i) msg+=" "+interpreted[i];
+     821             :       msg+="\nMaybe a missing space or a typo?";
+     822           2 :       log << msg;
+     823           2 :       log.flush();
+     824           4 :       plumed_merror(msg);
+     825             :     }
+     826       14264 :     action->checkRead();
+     827       14264 :     actionSet.emplace_back(std::move(action));
+     828       14306 :   };
+     829             : 
+     830       28534 :   pilots=actionSet.select<ActionPilot*>();
+     831             : }
+     832             : 
+     833             : ////////////////////////////////////////////////////////////////////////
+     834             : 
+     835           0 : void PlumedMain::exit(int c) {
+     836           0 :   comm.Abort(c);
+     837           0 : }
+     838             : 
+     839       14302 : Log& PlumedMain::getLog() {
+     840       14302 :   return log;
+     841             : }
+     842             : 
+     843      254029 : void PlumedMain::calc() {
+     844      254029 :   prepareCalc();
+     845      254029 :   performCalc();
+     846      254029 : }
+     847             : 
+     848      256099 : void PlumedMain::prepareCalc() {
+     849      256099 :   prepareDependencies();
+     850      256099 :   shareData();
+     851      256099 : }
+     852             : 
+     853             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+     854             : // here we have the main steps in "calc()"
+     855             : // they can be called individually, but the standard thing is to
+     856             : // traverse them in this order:
+     857      256426 : void PlumedMain::prepareDependencies() {
+     858             : 
+     859             : // Stopwatch is stopped when sw goes out of scope
+     860      256426 :   auto sw=stopwatch.startStop("1 Prepare dependencies");
+     861             : 
+     862             : // activate all the actions which are on step
+     863             : // activation is recursive and enables also the dependencies
+     864             : // before doing that, the prepare() method is called to see if there is some
+     865             : // new/changed dependency (up to now, only useful for dependences on virtual atoms,
+     866             : // which can be dynamically changed).
+     867             : 
+     868             : // First switch off all actions
+     869     2089597 :   for(const auto & p : actionSet) {
+     870     1833171 :     p->deactivate();
+     871             :   }
+     872             : 
+     873             : // for optimization, an "active" flag remains false if no action at all is active
+     874      256426 :   active=mydatafetcher->activate();
+     875     1604078 :   for(unsigned i=0; i<pilots.size(); ++i) {
+     876     1347652 :     if(pilots[i]->onStep()) {
+     877     1277737 :       pilots[i]->activate();
+     878     1277737 :       active=true;
+     879             :     }
+     880             :   };
+     881             : 
+     882             : // also, if one of them is the total energy, tell to atoms that energy should be collected
+     883     2089597 :   for(const auto & p : actionSet) {
+     884     1833171 :     if(p->isActive()) {
+     885     1651033 :       if(p->checkNeedsGradients()) p->setOption("GRADIENTS");
+     886             :     }
+     887             :   }
+     888             : 
+     889      256426 : }
+     890             : 
+     891      256183 : void PlumedMain::shareData() {
+     892             : // atom positions are shared (but only if there is something to do)
+     893      256183 :   if(!active)return;
+     894             : // Stopwatch is stopped when sw goes out of scope
+     895      254535 :   auto sw=stopwatch.startStop("2 Sharing data");
+     896      254535 :   if(atoms.getNatoms()>0) atoms.share();
+     897      254535 : }
+     898             : 
+     899        2134 : void PlumedMain::performCalcNoUpdate() {
+     900        2134 :   waitData();
+     901        2134 :   justCalculate();
+     902        2134 :   backwardPropagate();
+     903        2134 : }
+     904             : 
+     905          10 : void PlumedMain::performCalcNoForces() {
+     906          10 :   waitData();
+     907          10 :   justCalculate();
+     908          10 : }
+     909             : 
+     910      254039 : void PlumedMain::performCalc() {
+     911      254039 :   waitData();
+     912      254039 :   justCalculate();
+     913      254039 :   backwardPropagate();
+     914      254039 :   update();
+     915      254039 :   mydatafetcher->finishDataGrab();
+     916      254039 : }
+     917             : 
+     918      256297 : void PlumedMain::waitData() {
+     919      256297 :   if(!active)return;
+     920             : // Stopwatch is stopped when sw goes out of scope
+     921      254649 :   auto sw=stopwatch.startStop("3 Waiting for data");
+     922      254649 :   if(atoms.getNatoms()>0) atoms.wait();
+     923      254649 : }
+     924             : 
+     925      256297 : void PlumedMain::justCalculate() {
+     926      256297 :   if(!active)return;
+     927             : // Stopwatch is stopped when sw goes out of scope
+     928      254649 :   auto sw=stopwatch.startStop("4 Calculating (forward loop)");
+     929      254649 :   bias=0.0;
+     930      254649 :   work=0.0;
+     931             : 
+     932      254649 :   int iaction=0;
+     933             : // calculate the active actions in order (assuming *backward* dependence)
+     934     2077444 :   for(const auto & pp : actionSet) {
+     935             :     Action* p(pp.get());
+     936             :     try {
+     937     1822795 :       if(p->isActive()) {
+     938             : // Stopwatch is stopped when sw goes out of scope.
+     939             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+     940     1650083 :         Stopwatch::Handler sw;
+     941     1650083 :         if(detailedTimers) {
+     942             :           std::string actionNumberLabel;
+     943        1690 :           Tools::convert(iaction,actionNumberLabel);
+     944        1690 :           const unsigned m=actionSet.size();
+     945        5070 :           unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+     946        1690 :           const int pad=k-actionNumberLabel.length();
+     947        2815 :           for(int i=0; i<pad; i++) actionNumberLabel=" "+actionNumberLabel;
+     948        1690 :           sw=stopwatch.startStop("4A "+actionNumberLabel+" "+p->getLabel());
+     949             :         }
+     950     1650083 :         ActionWithValue*av=dynamic_cast<ActionWithValue*>(p);
+     951     1650083 :         ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(p);
+     952             :         {
+     953     1650083 :           if(av) av->clearInputForces();
+     954     1650083 :           if(av) av->clearDerivatives();
+     955             :         }
+     956             :         {
+     957     1650083 :           if(aa) aa->clearOutputForces();
+     958     1650083 :           if(aa) if(aa->isActive()) aa->retrieveAtoms();
+     959             :         }
+     960     1650083 :         if(p->checkNumericalDerivatives()) p->calculateNumericalDerivatives();
+     961     1649516 :         else p->calculate();
+     962             :         // This retrieves components called bias
+     963     1650083 :         if(av) {
+     964     1390052 :           bias+=av->getOutputQuantity("bias");
+     965     1390052 :           work+=av->getOutputQuantity("work");
+     966     1390052 :           av->setGradientsIfNeeded();
+     967             :         }
+     968     1650083 :         ActionWithVirtualAtom*avv=dynamic_cast<ActionWithVirtualAtom*>(p);
+     969     1650083 :         if(avv)avv->setGradientsIfNeeded();
+     970     1650083 :       }
+     971           0 :     } catch(...) {
+     972           0 :       plumed_error_nested() << "An error happened while calculating " << p->getLabel();
+     973           0 :     }
+     974     1822795 :     iaction++;
+     975             :   }
+     976      254649 : }
+     977             : 
+     978           0 : void PlumedMain::justApply() {
+     979           0 :   backwardPropagate();
+     980           0 :   update();
+     981           0 : }
+     982             : 
+     983      256173 : void PlumedMain::backwardPropagate() {
+     984      256173 :   if(!active)return;
+     985      254525 :   int iaction=0;
+     986             : // Stopwatch is stopped when sw goes out of scope
+     987      254525 :   auto sw=stopwatch.startStop("5 Applying (backward loop)");
+     988             : // apply them in reverse order
+     989     2076366 :   for(auto pp=actionSet.rbegin(); pp!=actionSet.rend(); ++pp) {
+     990             :     const auto & p(pp->get());
+     991     1821841 :     if(p->isActive()) {
+     992             : 
+     993             : // Stopwatch is stopped when sw goes out of scope.
+     994             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+     995     1649321 :       Stopwatch::Handler sw;
+     996     1649321 :       if(detailedTimers) {
+     997             :         std::string actionNumberLabel;
+     998        1690 :         Tools::convert(iaction,actionNumberLabel);
+     999        1690 :         const unsigned m=actionSet.size();
+    1000        5070 :         unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+    1001        1690 :         const int pad=k-actionNumberLabel.length();
+    1002        2815 :         for(int i=0; i<pad; i++) actionNumberLabel=" "+actionNumberLabel;
+    1003        1690 :         sw=stopwatch.startStop("5A "+actionNumberLabel+" "+p->getLabel());
+    1004             :       }
+    1005             : 
+    1006     1649321 :       p->apply();
+    1007     1649321 :       ActionAtomistic*a=dynamic_cast<ActionAtomistic*>(p);
+    1008             : // still ActionAtomistic has a special treatment, since they may need to add forces on atoms
+    1009     1649321 :       if(a) a->applyForces();
+    1010             : 
+    1011     1649321 :     }
+    1012     1821841 :     iaction++;
+    1013             :   }
+    1014             : 
+    1015             : // Stopwatch is stopped when sw goes out of scope.
+    1016             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1017      254525 :   Stopwatch::Handler sw1;
+    1018      254525 :   if(detailedTimers) sw1=stopwatch.startStop("5B Update forces");
+    1019             : // this is updating the MD copy of the forces
+    1020      254525 :   if(atoms.getNatoms()>0) atoms.updateForces();
+    1021      254525 : }
+    1022             : 
+    1023      254118 : void PlumedMain::update() {
+    1024      254118 :   if(!active)return;
+    1025             : 
+    1026             : // Stopwatch is stopped when sw goes out of scope
+    1027      252470 :   auto sw=stopwatch.startStop("6 Update");
+    1028             : 
+    1029             : // update step (for statistics, etc)
+    1030      252470 :   updateFlags.push(true);
+    1031     2067824 :   for(const auto & p : actionSet) {
+    1032     1815354 :     p->beforeUpdate();
+    1033     3457830 :     if(p->isActive() && p->checkUpdate() && updateFlagsTop()) p->update();
+    1034             :   }
+    1035      504944 :   while(!updateFlags.empty()) updateFlags.pop();
+    1036             :   if(!updateFlags.empty()) plumed_merror("non matching changes in the update flags");
+    1037             : // Check that no action has told the calculation to stop
+    1038      252470 :   if(stopNow) {
+    1039          65 :     if(stopFlag) stopFlag.set(int(1));
+    1040           0 :     else plumed_merror("your md code cannot handle plumed stop events - add a call to plumed.comm(stopFlag,stopCondition)");
+    1041             :   }
+    1042             : 
+    1043             : // flush by default every 10000 steps
+    1044             : // hopefully will not affect performance
+    1045             : // also if receive checkpointing signal
+    1046      252470 :   if(step%10000==0||doCheckPoint) {
+    1047         978 :     fflush();
+    1048         978 :     log.flush();
+    1049       15654 :     for(const auto & p : actionSet) p->fflush();
+    1050             :   }
+    1051      252470 : }
+    1052             : 
+    1053           2 : void PlumedMain::load(const std::string& ss) {
+    1054           2 :   if(DLLoader::installed()) {
+    1055           2 :     std::string s=ss;
+    1056           2 :     size_t n=s.find_last_of(".");
+    1057           3 :     std::string extension="";
+    1058           2 :     std::string base=s;
+    1059           4 :     if(n!=std::string::npos && n<s.length()-1) extension=s.substr(n+1);
+    1060           4 :     if(n!=std::string::npos && n<s.length())   base=s.substr(0,n);
+    1061           2 :     if(extension=="cpp") {
+    1062             : // full path command, including environment setup
+    1063             : // this will work even if plumed is not in the execution path or if it has been
+    1064             : // installed with a name different from "plumed"
+    1065           4 :       std::string cmd=config::getEnvCommand()+" \""+config::getPlumedRoot()+"\"/scripts/mklib.sh "+s;
+    1066           2 :       log<<"Executing: "<<cmd;
+    1067           2 :       if(comm.Get_size()>0) log<<" (only on master node)";
+    1068           2 :       log<<"\n";
+    1069           2 :       if(comm.Get_rank()==0) {
+    1070           2 :         int ret=std::system(cmd.c_str());
+    1071           3 :         if(ret!=0) plumed_error() <<"An error happened while executing command "<<cmd<<"\n";
+    1072             :       }
+    1073           1 :       comm.Barrier();
+    1074           2 :       base="./"+base;
+    1075             :     }
+    1076           2 :     s=base+"."+config::getSoExt();
+    1077           1 :     void *p=dlloader.load(s);
+    1078           1 :     if(!p) {
+    1079           0 :       plumed_error()<<"I cannot load library " << ss << " " << dlloader.error();
+    1080             :     }
+    1081           2 :     log<<"Loading shared library "<<s.c_str()<<"\n";
+    1082           1 :     log<<"Here is the new list of available actions\n";
+    1083           1 :     log<<actionRegister();
+    1084           0 :   } else plumed_error()<<"While loading library "<< ss << " loading was not enabled, please check if dlopen was found at configure time";
+    1085           1 : }
+    1086             : 
+    1087        2805 : double PlumedMain::getBias() const {
+    1088        2805 :   return bias;
+    1089             : }
+    1090             : 
+    1091         450 : double PlumedMain::getWork() const {
+    1092         450 :   return work;
+    1093             : }
+    1094             : 
+    1095          73 : FILE* PlumedMain::fopen(const char *path, const char *mode) {
+    1096          73 :   std::string mmode(mode);
+    1097          73 :   std::string ppath(path);
+    1098          73 :   std::string suffix(getSuffix());
+    1099          73 :   std::string ppathsuf=ppath+suffix;
+    1100          73 :   FILE*fp=std::fopen(const_cast<char*>(ppathsuf.c_str()),const_cast<char*>(mmode.c_str()));
+    1101          73 :   if(!fp) fp=std::fopen(const_cast<char*>(ppath.c_str()),const_cast<char*>(mmode.c_str()));
+    1102          73 :   plumed_massert(fp,"file " + ppath + " cannot be found");
+    1103          73 :   return fp;
+    1104             : }
+    1105             : 
+    1106          91 : int PlumedMain::fclose(FILE*fp) {
+    1107          91 :   return std::fclose(fp);
+    1108             : }
+    1109             : 
+    1110        3798 : std::string PlumedMain::cite(const std::string&item) {
+    1111        3798 :   return citations.cite(item);
+    1112             : }
+    1113             : 
+    1114        1539 : void PlumedMain::fflush() {
+    1115        4799 :   for(const auto  & p : files) {
+    1116        3260 :     p->flush();
+    1117             :   }
+    1118        1539 : }
+    1119             : 
+    1120        4536 : void PlumedMain::insertFile(FileBase&f) {
+    1121        4536 :   files.insert(&f);
+    1122        4536 : }
+    1123             : 
+    1124        4833 : void PlumedMain::eraseFile(FileBase&f) {
+    1125        4833 :   files.erase(&f);
+    1126        4833 : }
+    1127             : 
+    1128          65 : void PlumedMain::stop() {
+    1129          65 :   stopNow=true;
+    1130          65 : }
+    1131             : 
+    1132         813 : void PlumedMain::runJobsAtEndOfCalculation() {
+    1133       14561 :   for(const auto & p : actionSet) {
+    1134       13748 :     p->runFinalJobs();
+    1135             :   }
+    1136         813 : }
+    1137             : 
+    1138     8805343 : unsigned PlumedMain::increaseReferenceCounter() noexcept {
+    1139     8805343 :   return ++referenceCounter;
+    1140             : }
+    1141             : 
+    1142     8804428 : unsigned PlumedMain::decreaseReferenceCounter() noexcept {
+    1143     8804428 :   return --referenceCounter;
+    1144             : }
+    1145             : 
+    1146          42 : unsigned PlumedMain::useCountReferenceCounter() const noexcept {
+    1147          42 :   return referenceCounter;
+    1148             : }
+    1149             : 
+    1150           0 : void PlumedMain::activateParseOnlyMode() {
+    1151           0 :   doParseOnly=true;
+    1152           0 : }
+    1153             : 
+    1154        1820 : bool PlumedMain::parseOnlyMode() const {
+    1155        1820 :   return doParseOnly;
+    1156             : }
+    1157             : 
+    1158             : #ifdef __PLUMED_HAS_PYTHON
+    1159             : // This is here to stop cppcheck throwing an error
+    1160             : #endif
+    1161             : 
+    1162             : }
+    1163             : 
+    1164             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.func-sort-c.html b/coverage/core/PlumedMain.h.func-sort-c.html new file mode 100644 index 0000000000..09e9120e68 --- /dev/null +++ b/coverage/core/PlumedMain.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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:161888.9 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.func.html b/coverage/core/PlumedMain.h.func.html new file mode 100644 index 0000000000..e220c3fc66 --- /dev/null +++ b/coverage/core/PlumedMain.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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:161888.9 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_use_count42
_ZL16translate_nested24plumed_nothrow_handler_x45
plumed_plumedmain_cmd_safe95
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc111
plumed_plumedmain_cmd357
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev4168
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev4168
plumed_plumedmain_cmd_safe_nothrow14786
_ZL19getenvTypesafeDebugv14881
plumed_plumedmain_create804353
plumed_plumedmain_finalize804353
plumed_symbol_table_init808492
plumed_plumedmain_create_reference8000075
plumed_plumedmain_delete_reference8804428
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.func.html b/coverage/core/PlumedMainInitializer.cpp.func.html new file mode 100644 index 0000000000..8861b2cf42 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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:17121181.0 %
Date:2024-05-27 13:05:14Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
_ZL16translate_nested24plumed_nothrow_handler_x45
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc111
_ZL19getenvTypesafeDebugv14881
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev4168
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev4168
plumed_plumedmain_cmd357
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe95
plumed_plumedmain_cmd_safe_nothrow14786
plumed_plumedmain_create804353
plumed_plumedmain_create_reference8000075
plumed_plumedmain_delete_reference8804428
plumed_plumedmain_finalize804353
plumed_plumedmain_use_count42
plumed_symbol_table_init808492
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.gcov.html b/coverage/core/PlumedMainInitializer.cpp.gcov.html new file mode 100644 index 0000000000..97fd6fa8e1 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.gcov.html @@ -0,0 +1,494 @@ + + + + + + + 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:17121181.0 %
Date:2024-05-27 13:05:14Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PlumedMainInitializer.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "lepton/Exception.h"
+      26             : #include <cstdlib>
+      27             : #include <cstring>
+      28             : #include <iostream>
+      29             : #if defined __PLUMED_HAS_DLOPEN
+      30             : #include <dlfcn.h>
+      31             : #endif
+      32             : #include <exception>
+      33             : #include <stdexcept>
+      34             : #include <ios>
+      35             : #include <new>
+      36             : #include <typeinfo>
+      37             : #ifdef __PLUMED_LIBCXX11
+      38             : #include <system_error>
+      39             : #include <future>
+      40             : #include <memory>
+      41             : #include <functional>
+      42             : #endif
+      43             : #include "tools/TypesafePtr.h"
+      44             : #include "tools/Log.h"
+      45             : #include "tools/Tools.h"
+      46             : 
+      47             : 
+      48       14881 : static bool getenvTypesafeDebug() noexcept {
+      49       14881 :   static const auto* res=std::getenv("PLUMED_TYPESAFE_DEBUG");
+      50       14881 :   return res;
+      51             : }
+      52             : 
+      53           0 : static void typesafeDebug(const char*key,plumed_safeptr_x safe) noexcept {
+      54           0 :   std::fprintf(stderr,"+++ PLUMED_TYPESAFE_DEBUG %s %p %zu",key,safe.ptr,safe.nelem);
+      55           0 :   const size_t* shape=safe.shape;
+      56           0 :   if(shape) {
+      57           0 :     std::fprintf(stderr," (");
+      58           0 :     while(*shape!=0) {
+      59           0 :       std::fprintf(stderr," %zu",*shape);
+      60           0 :       shape++;
+      61             :     }
+      62           0 :     std::fprintf(stderr," )");
+      63             :   }
+      64           0 :   std::fprintf(stderr," %zx %p\n",safe.flags,safe.opt);
+      65           0 : }
+      66             : 
+      67             : // create should never throw
+      68             : // in case of a problem, it logs the error and return a null pointer
+      69             : // when loaded by an interface >=2.5, this will result in a non valid plumed object.
+      70             : // earlier interfaces will just give a segfault or a failed assertion.
+      71      804353 : extern "C" void*plumed_plumedmain_create() {
+      72             :   try {
+      73      804353 :     return new PLMD::PlumedMain;
+      74           0 :   } catch(const std::exception & e) {
+      75           0 :     std::cerr<<"+++ an error happened while creating a plumed object\n";
+      76           0 :     std::cerr<<e.what()<<std::endl;
+      77             :     return nullptr;
+      78           0 :   } catch(...) {
+      79           0 :     std::cerr<<"+++ an unknown error happened while creating a plumed object"<<std::endl;
+      80             :     return nullptr;
+      81           0 :   }
+      82             : }
+      83             : 
+      84     8000075 : extern "C" unsigned plumed_plumedmain_create_reference(void*plumed) {
+      85     8000075 :   plumed_massert(plumed,"trying to create a reference to a plumed object which is not initialized");
+      86             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      87     8000075 :   return p->increaseReferenceCounter();
+      88             : }
+      89             : 
+      90     8804428 : extern "C" unsigned plumed_plumedmain_delete_reference(void*plumed) {
+      91     8804428 :   plumed_massert(plumed,"trying to delete a reference to a plumed object which is not initialized");
+      92             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      93     8804428 :   return p->decreaseReferenceCounter();
+      94             : }
+      95             : 
+      96          42 : extern "C" unsigned plumed_plumedmain_use_count(void*plumed) {
+      97          42 :   plumed_massert(plumed,"trying to delete a reference to a plumed object which is not initialized");
+      98             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      99          42 :   return p->useCountReferenceCounter();
+     100             : }
+     101             : 
+     102         357 : extern "C" void plumed_plumedmain_cmd(void*plumed,const char*key,const void*val) {
+     103         357 :   plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     104             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     105         714 :   p->cmd(key,PLMD::TypesafePtr::unchecked(val));
+     106         357 : }
+     107             : 
+     108             : extern "C" {
+     109          95 :   static void plumed_plumedmain_cmd_safe(void*plumed,const char*key,plumed_safeptr_x safe) {
+     110          95 :     plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     111             :     auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     112          95 :     if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     113         190 :     p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     114          95 :   }
+     115             : }
+     116             : 
+     117             : /// Internal tool
+     118             : /// Throws the currently managed exception and call the nothrow handler.
+     119             : /// If nested is not null, it is passed and then gets populated with a pointer that should
+     120             : /// be called on the nested exception
+     121             : /// If msg is not null, it overrides the message. Can be used to build a concatenated message.
+     122         111 : static void translate_current(plumed_nothrow_handler_x nothrow,void**nested=nullptr,const char*msg=nullptr) {
+     123         111 :   const void* opt[5]= {"n",nested,nullptr,nullptr,nullptr};
+     124             :   try {
+     125             :     // this function needs to be called while catching an exception
+     126             :     // cppcheck-suppress rethrowNoCurrentException
+     127         111 :     throw;
+     128         111 :   } catch(const PLMD::ExceptionTypeError & e) {
+     129           8 :     if(!msg) msg=e.what();
+     130           8 :     nothrow.handler(nothrow.ptr,20300,msg,opt);
+     131          63 :   } catch(const PLMD::ExceptionError & e) {
+     132          55 :     if(!msg) msg=e.what();
+     133          55 :     nothrow.handler(nothrow.ptr,20200,msg,opt);
+     134          56 :   } catch(const PLMD::ExceptionDebug & e) {
+     135           1 :     if(!msg) msg=e.what();
+     136           1 :     nothrow.handler(nothrow.ptr,20100,msg,opt);
+     137          22 :   } catch(const PLMD::Exception & e) {
+     138          21 :     if(!msg) msg=e.what();
+     139          21 :     nothrow.handler(nothrow.ptr,20000,msg,opt);
+     140          22 :   } catch(const PLMD::lepton::Exception & e) {
+     141           1 :     if(!msg) msg=e.what();
+     142           1 :     nothrow.handler(nothrow.ptr,19900,msg,opt);
+     143             :     // 11000 to 12000 are "bad exceptions". message will be copied without new allocations
+     144           2 :   } catch(const std::bad_exception & e) {
+     145           1 :     if(!msg) msg=e.what();
+     146           1 :     nothrow.handler(nothrow.ptr,11500,msg,opt);
+     147             : #ifdef __PLUMED_LIBCXX11
+     148           2 :   } catch(const std::bad_array_new_length & e) {
+     149           1 :     if(!msg) msg=e.what();
+     150           1 :     nothrow.handler(nothrow.ptr,11410,msg,opt);
+     151             : #endif
+     152           4 :   } catch(const std::bad_alloc & e) {
+     153           3 :     if(!msg) msg=e.what();
+     154           3 :     nothrow.handler(nothrow.ptr,11400,msg,opt);
+     155             : #ifdef __PLUMED_LIBCXX11
+     156           4 :   } catch(const std::bad_function_call & e) {
+     157           1 :     if(!msg) msg=e.what();
+     158           1 :     nothrow.handler(nothrow.ptr,11300,msg,opt);
+     159           2 :   } catch(const std::bad_weak_ptr & e) {
+     160           1 :     if(!msg) msg=e.what();
+     161           1 :     nothrow.handler(nothrow.ptr,11200,msg,opt);
+     162             : #endif
+     163           2 :   } catch(const std::bad_cast & e) {
+     164           1 :     if(!msg) msg=e.what();
+     165           1 :     nothrow.handler(nothrow.ptr,11100,msg,opt);
+     166           2 :   } catch(const std::bad_typeid & e) {
+     167           1 :     if(!msg) msg=e.what();
+     168           1 :     nothrow.handler(nothrow.ptr,11000,msg,opt);
+     169             :     // not implemented yet: std::regex_error
+     170             :     // we do not allow regex yet due to portability problems with gcc 4.8
+     171             :     // as soon as we transition to using <regex> it should be straightforward to add
+     172           2 :   } catch(const std::ios_base::failure & e) {
+     173           1 :     if(!msg) msg=e.what();
+     174             : #ifdef __PLUMED_LIBCXX11
+     175           1 :     int value=e.code().value();
+     176           1 :     opt[2]="c"; // "c" passes the error code.
+     177           1 :     opt[3]=&value;
+     178           1 :     if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10230,msg,opt);
+     179           1 :     else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10231,msg,opt);
+     180           1 :     else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10232,msg,opt);
+     181           0 :     else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10233,msg,opt);
+     182             :     else
+     183             : #endif
+     184             :       // 10239 represents std::ios_base::failure with default constructur
+     185           0 :       nothrow.handler(nothrow.ptr,10239,msg,opt);
+     186             : #ifdef __PLUMED_LIBCXX11
+     187           5 :   } catch(const std::system_error & e) {
+     188           4 :     if(!msg) msg=e.what();
+     189           4 :     int value=e.code().value();
+     190           4 :     opt[2]="c"; // "c" passes the error code.
+     191           4 :     opt[3]=&value;
+     192           4 :     if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10220,msg,opt);
+     193           3 :     else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10221,msg,opt);
+     194           2 :     else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10222,msg,opt);
+     195           1 :     else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10223,msg,opt);
+     196             :     // fallback to generic runtime_error
+     197           0 :     else nothrow.handler(nothrow.ptr,10200,msg,opt);
+     198             : #endif
+     199           5 :   } catch(const std::underflow_error &e) {
+     200           1 :     if(!msg) msg=e.what();
+     201           1 :     nothrow.handler(nothrow.ptr,10215,msg,opt);
+     202           2 :   } catch(const std::overflow_error &e) {
+     203           1 :     if(!msg) msg=e.what();
+     204           1 :     nothrow.handler(nothrow.ptr,10210,msg,opt);
+     205           2 :   } catch(const std::range_error &e) {
+     206           1 :     if(!msg) msg=e.what();
+     207           1 :     nothrow.handler(nothrow.ptr,10205,msg,opt);
+     208           2 :   } catch(const std::runtime_error & e) {
+     209           1 :     if(!msg) msg=e.what();
+     210           1 :     nothrow.handler(nothrow.ptr,10200,msg,opt);
+     211             :     // not implemented yet: std::future_error
+     212             :     // not clear how useful it would be.
+     213           2 :   } catch(const std::out_of_range & e) {
+     214           1 :     if(!msg) msg=e.what();
+     215           1 :     nothrow.handler(nothrow.ptr,10120,msg,opt);
+     216           2 :   } catch(const std::length_error & e) {
+     217           1 :     if(!msg) msg=e.what();
+     218           1 :     nothrow.handler(nothrow.ptr,10115,msg,opt);
+     219           2 :   } catch(const std::domain_error & e) {
+     220           1 :     if(!msg) msg=e.what();
+     221           1 :     nothrow.handler(nothrow.ptr,10110,msg,opt);
+     222           2 :   } catch(const std::invalid_argument & e) {
+     223           1 :     if(!msg) msg=e.what();
+     224           1 :     nothrow.handler(nothrow.ptr,10105,msg,opt);
+     225           2 :   } catch(const std::logic_error & e) {
+     226           1 :     if(!msg) msg=e.what();
+     227           1 :     nothrow.handler(nothrow.ptr,10100,msg,opt);
+     228             :     // generic exception. message will be copied without new allocations
+     229             :     // reports all non caught exceptions that are derived from std::exception
+     230             :     // for instance, boost exceptions would end up here
+     231           1 :   } catch(const std::exception & e) {
+     232           0 :     if(!msg) msg=e.what();
+     233           0 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     234           1 :   } catch(const char* m) {
+     235           1 :     if(!msg) msg=m;
+     236           1 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     237           1 :   } catch(const std::string & s) {
+     238           0 :     if(!msg) msg=s.c_str();
+     239           0 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     240           1 :   } catch (...) {
+     241             :     // if exception cannot be translated, we add a bad_exception to the stack
+     242           1 :     nothrow.handler(nothrow.ptr,11500,"plumed could not translate exception",opt);
+     243           1 :   }
+     244         111 : }
+     245             : 
+     246          45 : static void translate_nested(plumed_nothrow_handler_x nothrow) {
+     247             :   try {
+     248          45 :     throw;
+     249          45 :   } catch (const std::nested_exception & e) {
+     250             : // If this exception has a nested one:
+     251          12 :     auto nothrow_nested=nothrow;
+     252          12 :     nothrow_nested.ptr=nullptr;
+     253             : // translate the current exception asking the wrapper to allocate a new exception
+     254          12 :     translate_current(nothrow,&nothrow_nested.ptr);
+     255             : // if the wrapper cannot allocate the exception, this will be a nullptr
+     256          12 :     if(nothrow_nested.ptr) {
+     257             :       try {
+     258             : // transfer control to the nested exception
+     259          12 :         e.rethrow_nested();
+     260          12 :       } catch (...) {
+     261             : // recursively translate it
+     262          12 :         translate_nested(nothrow_nested);
+     263          12 :       }
+     264             :     }
+     265          45 :   } catch (...) {
+     266             : // otherwise, just translate the current exception
+     267          33 :     translate_current(nothrow);
+     268          33 :   }
+     269          45 : }
+     270             : 
+     271             : extern "C" {
+     272       14786 :   static void plumed_plumedmain_cmd_safe_nothrow(void*plumed,const char*key,plumed_safeptr_x safe,plumed_nothrow_handler_x nothrow) {
+     273             : // This is a workaround for a suboptimal choice in PLUMED <2.8
+     274             : // In particular, the only way to bypass the exception handling process was to call the plumed_plumedmain_cmd_safe
+     275             : // function directly.
+     276             : // With this modification, it is possible to just call the plumed_plumedmain_cmd_safe_nothrow function
+     277             : // passing a null error handler.
+     278       14786 :     if(!nothrow.handler) {
+     279           0 :       plumed_plumedmain_cmd_safe(plumed,key,safe);
+     280           0 :       return;
+     281             :     }
+     282             :     auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     283             : // At library boundaries we translate exceptions to error codes.
+     284             : // This allows an exception to be catched also if the MD code
+     285             : // was linked against a different C++ library
+     286             :     try {
+     287       14786 :       plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     288       14786 :       if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     289       29572 :       p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     290          99 :     } catch(...) {
+     291          99 :       if(p->getNestedExceptions()) {
+     292          33 :         translate_nested(nothrow);
+     293             :       } else {
+     294             : // In this case, we just consider the latest thrown exception and
+     295             : // supplement it with a concatenated message so as not to
+     296             : // loose information.
+     297          66 :         auto msg=PLMD::Tools::concatenateExceptionMessages();
+     298          66 :         translate_current(nothrow,nullptr,msg.c_str());
+     299             :       }
+     300          99 :     }
+     301             :   }
+     302             : }
+     303             : 
+     304             : extern "C" {
+     305           0 :   static void plumed_plumedmain_cmd_nothrow(void*plumed,const char*key,const void*val,plumed_nothrow_handler_x nothrow) {
+     306             :     plumed_safeptr_x safe;
+     307           0 :     plumed_assert(nothrow.handler) << "Accepting a null pointer here would make the calling code non compatible with plumed 2.5 to 2.7";
+     308           0 :     safe.ptr=val;
+     309           0 :     safe.nelem=0;
+     310           0 :     safe.shape=NULL;
+     311           0 :     safe.flags=0;
+     312           0 :     safe.opt=NULL;
+     313           0 :     plumed_plumedmain_cmd_safe_nothrow(plumed,key,safe,nothrow);
+     314           0 :   }
+     315             : }
+     316             : 
+     317      804353 : extern "C" void plumed_plumedmain_finalize(void*plumed) {
+     318      804353 :   plumed_massert(plumed,"trying to deallocate a plumed object which is not initialized");
+     319             : // I think it is not possible to replace this delete with a smart pointer
+     320             : // since the ownership of this pointer is in a C structure. GB
+     321      804353 :   delete static_cast<PLMD::PlumedMain*>(plumed);
+     322      804353 : }
+     323             : 
+     324             : // values here should be consistent with those in plumed_symbol_table_init !!!!
+     325             : plumed_symbol_table_type_x plumed_symbol_table= {
+     326             :   4,
+     327             :   {plumed_plumedmain_create,plumed_plumedmain_cmd,plumed_plumedmain_finalize},
+     328             :   plumed_plumedmain_cmd_nothrow,
+     329             :   plumed_plumedmain_cmd_safe,
+     330             :   plumed_plumedmain_cmd_safe_nothrow,
+     331             :   plumed_plumedmain_create_reference,
+     332             :   plumed_plumedmain_delete_reference,
+     333             :   plumed_plumedmain_use_count
+     334             : };
+     335             : 
+     336             : // values here should be consistent with those above !!!!
+     337      808492 : extern "C" void plumed_symbol_table_init() {
+     338      808492 :   plumed_symbol_table.version=4;
+     339      808492 :   plumed_symbol_table.functions.create=plumed_plumedmain_create;
+     340      808492 :   plumed_symbol_table.functions.cmd=plumed_plumedmain_cmd;
+     341      808492 :   plumed_symbol_table.functions.finalize=plumed_plumedmain_finalize;
+     342      808492 :   plumed_symbol_table.cmd_nothrow=plumed_plumedmain_cmd_nothrow;
+     343      808492 :   plumed_symbol_table.cmd_safe=plumed_plumedmain_cmd_safe;
+     344      808492 :   plumed_symbol_table.cmd_safe_nothrow=plumed_plumedmain_cmd_safe_nothrow;
+     345      808492 :   plumed_symbol_table.create_reference=plumed_plumedmain_create_reference;
+     346      808492 :   plumed_symbol_table.delete_reference=plumed_plumedmain_delete_reference;
+     347      808492 :   plumed_symbol_table.use_count=plumed_plumedmain_use_count;
+     348      808492 : }
+     349             : 
+     350             : namespace PLMD {
+     351             : 
+     352             : #define plumed_convert_fptr(ptr,fptr) { ptr=NULL; std::memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
+     353             : 
+     354             : /// Static object which registers Plumed.
+     355             : /// This is a static object which, during its construction at startup,
+     356             : /// registers the pointers to plumed_plumedmain_create, plumed_plumedmain_cmd and plumed_plumedmain_finalize
+     357             : /// to the plumed_kernel_register function.
+     358             : /// Registration is only required with plumed loader <=2.4, but we do it anyway in order to maintain
+     359             : /// backward compatibility. Notice that as of plumed 2.5 the plumed_kernel_register is found
+     360             : /// using dlsym, in order to allow the libplumedKernel library to be loadable also when
+     361             : /// the plumed_kernel_register symbol is not available.
+     362             : namespace {
+     363             : class PlumedMainInitializer {
+     364             :   const bool debug;
+     365             : public:
+     366        4168 :   PlumedMainInitializer():
+     367        4168 :     debug(std::getenv("PLUMED_LOAD_DEBUG"))
+     368             :   {
+     369             : // make sure static plumed_function_pointers is initialized here
+     370        4168 :     plumed_symbol_table_init();
+     371        4168 :     if(debug) std::fprintf(stderr,"+++ Initializing PLUMED with plumed_symbol_table version %i at %p\n",plumed_symbol_table.version,(void*)&plumed_symbol_table);
+     372             : #if defined(__PLUMED_HAS_DLOPEN)
+     373        4168 :     if(std::getenv("PLUMED_LOAD_SKIP_REGISTRATION")) {
+     374           0 :       if(debug) std::fprintf(stderr,"+++ Skipping registration +++\n");
+     375           0 :       return;
+     376             :     }
+     377             :     typedef plumed_plumedmain_function_holder_x* (*plumed_kernel_register_type_x)(const plumed_plumedmain_function_holder_x*);
+     378             :     plumed_kernel_register_type_x plumed_kernel_register=nullptr;
+     379             :     void* handle=nullptr;
+     380             : #if defined(__PLUMED_HAS_RTLD_DEFAULT)
+     381        4168 :     if(debug) std::fprintf(stderr,"+++ Registering functions. Looking in RTLD_DEFAULT +++\n");
+     382        4168 :     void* dls=dlsym(RTLD_DEFAULT,"plumed_kernel_register");
+     383             : #else
+     384             :     handle=dlopen(NULL,RTLD_LOCAL);
+     385             :     if(debug) std::fprintf(stderr,"+++ Registering functions. dlopen handle at %p +++\n",handle);
+     386             :     void* dls=dlsym(handle,"plumed_kernel_register");
+     387             : #endif
+     388        4168 :     *(void **)(&plumed_kernel_register)=dls;
+     389        4168 :     if(debug) {
+     390           0 :       if(plumed_kernel_register) {
+     391           0 :         std::fprintf(stderr,"+++ plumed_kernel_register found at %p +++\n",dls);
+     392             :       }
+     393           0 :       else std::fprintf(stderr,"+++ plumed_kernel_register not found +++\n");
+     394             :     }
+     395             :     void*createp;
+     396             :     void*cmdp;
+     397             :     void*finalizep;
+     398             :     plumed_convert_fptr(createp,plumed_symbol_table.functions.create);
+     399             :     plumed_convert_fptr(cmdp,plumed_symbol_table.functions.cmd);
+     400             :     plumed_convert_fptr(finalizep,plumed_symbol_table.functions.finalize);
+     401        4168 :     if(plumed_kernel_register && debug) std::fprintf(stderr,"+++ Registering functions at %p (%p,%p,%p) +++\n",
+     402             :           (void*)&plumed_symbol_table.functions,createp,cmdp,finalizep);
+     403        4168 :     if(plumed_kernel_register) (*plumed_kernel_register)(&plumed_symbol_table.functions);
+     404             : // Notice that handle could be null in the following cases:
+     405             : // - if we use RTLD_DEFAULT
+     406             : // - on Linux if we don't use RTLD_DEFAULT, since dlopen(NULL,RTLD_LOCAL) returns a null pointer.
+     407             :     if(handle) dlclose(handle);
+     408             : #endif
+     409             :   }
+     410        4168 :   ~PlumedMainInitializer() {
+     411        4168 :     if(debug) std::fprintf(stderr,"+++ Finalizing PLUMED with plumed_symbol_table at %p\n",(void*)&plumed_symbol_table);
+     412        4168 :   }
+     413             : } PlumedMainInitializerRegisterMe;
+     414             : }
+     415             : 
+     416             : }
+     417             : 
+     418             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func-sort-c.html b/coverage/core/TargetDist.cpp.func-sort-c.html new file mode 100644 index 0000000000..e8ad9b1445 --- /dev/null +++ b/coverage/core/TargetDist.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func.html b/coverage/core/TargetDist.cpp.func.html new file mode 100644 index 0000000000..d146784d32 --- /dev/null +++ b/coverage/core/TargetDist.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.gcov.html b/coverage/core/TargetDist.cpp.gcov.html new file mode 100644 index 0000000000..562e828aab --- /dev/null +++ b/coverage/core/TargetDist.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/core/Value.cpp.func-sort-c.html b/coverage/core/Value.cpp.func-sort-c.html new file mode 100644 index 0000000000..8f62c5ab60 --- /dev/null +++ b/coverage/core/Value.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD5Value15getPntrToActionEv4773
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27988
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb48516
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE965124
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151484
_ZN4PLMD5Value16setupPeriodicityEv1183494
_ZNK4PLMD5Value10isPeriodicEv1666714
_ZN4PLMD5Value14setNotPeriodicEv3529016
_ZN4PLMD5ValueC2Ev3561022
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.func.html b/coverage/core/Value.cpp.func.html new file mode 100644 index 0000000000..7575cce8d6 --- /dev/null +++ b/coverage/core/Value.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD5Value14setNotPeriodicEv3529016
_ZN4PLMD5Value15getPntrToActionEv4773
_ZN4PLMD5Value16setupPeriodicityEv1183494
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151484
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb48516
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZN4PLMD5ValueC2Ev3561022
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE965124
_ZNK4PLMD5Value10isPeriodicEv1666714
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27988
_ZNK4PLMD5Value9getDomainERdS1_34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.gcov.html b/coverage/core/Value.cpp.gcov.html new file mode 100644 index 0000000000..3b6e3c8ca5 --- /dev/null +++ b/coverage/core/Value.cpp.gcov.html @@ -0,0 +1,276 @@ + + + + + + + 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-05-27 13:05: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       48516 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv):
+      65       48516 :   action(av),
+      66       48516 :   value_set(false),
+      67       48516 :   value(0.0),
+      68       48516 :   inputForce(0.0),
+      69       48516 :   hasForce(false),
+      70       48516 :   name(name),
+      71       48516 :   hasDeriv(withderiv),
+      72       48516 :   periodicity(unset),
+      73       48516 :   min(0.0),
+      74       48516 :   max(0.0),
+      75       48516 :   max_minus_min(0.0),
+      76       48516 :   inv_max_minus_min(0.0)
+      77             : {
+      78       48516 : }
+      79             : 
+      80     1183494 : void Value::setupPeriodicity() {
+      81     1183494 :   if( min==0 && max==0 ) {
+      82       32010 :     periodicity=notperiodic;
+      83             :   } else {
+      84     1151484 :     periodicity=periodic;
+      85     1151484 :     max_minus_min=max-min;
+      86     1151484 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+      87     1151484 :     inv_max_minus_min=1.0/max_minus_min;
+      88             :   }
+      89     1183494 : }
+      90             : 
+      91     1666714 : bool Value::isPeriodic()const {
+      92     1666714 :   plumed_massert(periodicity!=unset,"periodicity should be set");
+      93     1666714 :   return periodicity==periodic;
+      94             : }
+      95             : 
+      96      965124 : bool Value::applyForce(std::vector<double>& forces ) const {
+      97      965124 :   if( !hasForce ) return false;
+      98             :   plumed_dbg_massert( derivatives.size()==forces.size()," forces array has wrong size" );
+      99      115265 :   const unsigned N=derivatives.size();
+     100    48883113 :   for(unsigned i=0; i<N; ++i) forces[i]=inputForce*derivatives[i];
+     101             :   return true;
+     102             : }
+     103             : 
+     104     3529016 : void Value::setNotPeriodic() {
+     105     3529016 :   min=0; max=0; periodicity=notperiodic;
+     106     3529016 : }
+     107             : 
+     108     1151484 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
+     109     1151484 :   str_min=pmin;
+     110     1151484 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
+     111     1151484 :   str_max=pmax;
+     112     1151484 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
+     113     1151484 :   setupPeriodicity();
+     114     1151484 : }
+     115             : 
+     116       27988 : void Value::getDomain(std::string&minout,std::string&maxout) const {
+     117       27988 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     118       27988 :   minout=str_min;
+     119       27988 :   maxout=str_max;
+     120       27988 : }
+     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 :     const 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        4773 : ActionWithValue* Value::getPntrToAction() {
+     174        4773 :   plumed_assert( action!=NULL );
+     175        4773 :   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.16
+
+ + + diff --git a/coverage/core/Value.h.func-sort-c.html b/coverage/core/Value.h.func-sort-c.html new file mode 100644 index 0000000000..978cdb0330 --- /dev/null +++ b/coverage/core/Value.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value22getNumberOfDerivativesEv329870
_ZN4PLMD5Value16applyPeriodicityEv44363594
_ZNK4PLMD5Value10differenceEdd155957776
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.func.html b/coverage/core/Value.h.func.html new file mode 100644 index 0000000000..2a5d841a5e --- /dev/null +++ b/coverage/core/Value.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value16applyPeriodicityEv44363594
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value10differenceEdd155957776
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value22getNumberOfDerivativesEv329870
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.gcov.html b/coverage/core/Value.h.gcov.html new file mode 100644 index 0000000000..0f7cd01a77 --- /dev/null +++ b/coverage/core/Value.h.gcov.html @@ -0,0 +1,392 @@ + + + + + + + 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-05-27 13:05: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    44363594 : void Value::applyPeriodicity() {
+     159    44363594 :   if(periodicity==periodic) {
+     160    30706194 :     value=min+difference(min,value);
+     161    30706194 :     if(value<min)value+=max_minus_min;
+     162             :   }
+     163    44363594 : }
+     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    44352884 :   value_set=true;
+     196    44352884 :   value=v;
+     197    44164121 :   applyPeriodicity();
+     198    42537229 : }
+     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     3225736 :   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     8652403 :   return name;
+     220             : }
+     221             : 
+     222             : inline
+     223      329870 : unsigned Value::getNumberOfDerivatives() const {
+     224      329870 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
+     225      329870 :   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    20355568 :   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  4102751000 :   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    22653065 :   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     2081407 :   hasForce=false;
+     264     2081407 :   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      188505 :   hasForce=true;
+     277      188505 :   inputForce+=f;
+     278        2623 : }
+     279             : 
+     280             : inline
+     281             : double Value::getForce() const {
+     282        4823 :   return inputForce;
+     283             : }
+     284             : /// d2-d1
+     285             : inline
+     286   155957776 : double Value::difference(double d1,double d2)const {
+     287   155957776 :   if(periodicity==notperiodic) {
+     288    90588954 :     return d2-d1;
+     289    65368822 :   } else if(periodicity==periodic) {
+     290    65368822 :     double s=(d2-d1)*inv_max_minus_min;
+     291             :     // remember: pbc brings the difference in a range of -0.5:0.5
+     292    65368822 :     s=Tools::pbc(s);
+     293    65368822 :     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.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func-sort-c.html b/coverage/core/WithCmd.h.func-sort-c.html new file mode 100644 index 0000000000..66669d4d4d --- /dev/null +++ b/coverage/core/WithCmd.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrEmPKm276090
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func.html b/coverage/core/WithCmd.h.func.html new file mode 100644 index 0000000000..adcdcd194a --- /dev/null +++ b/coverage/core/WithCmd.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrEmPKm276090
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.gcov.html b/coverage/core/WithCmd.h.gcov.html new file mode 100644 index 0000000000..bbaf2d10dd --- /dev/null +++ b/coverage/core/WithCmd.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-05-27 13:05: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      276090 :   void cmd(const std::string& key,const TypesafePtr & val,std::size_t nelem, const std::size_t* shape=nullptr) {
+      40      276090 :     cmd(key,TypesafePtr::setNelemAndShape(val,nelem,shape));
+      41      276090 :   }
+      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.16
+
+ + + diff --git a/coverage/core/index-sort-f.html b/coverage/core/index-sort-f.html new file mode 100644 index 0000000000..f48d2af791 --- /dev/null +++ b/coverage/core/index-sort-f.html @@ -0,0 +1,533 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3237376785.9 %
Date:2024-05-27 13:05:14Functions:43153580.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionSetup.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.7%91.7%
+
91.7 %166 / 18149.3 %33 / 67
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
ActionAtomistic.cpp +
91.9%91.9%
+
91.9 %171 / 18677.3 %17 / 22
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
Value.cpp +
86.6%86.6%
+
86.6 %103 / 11981.2 %13 / 16
DataFetchingObject.cpp +
68.1%68.1%
+
68.1 %47 / 6981.2 %13 / 16
Colvar.cpp +
100.0%
+
100.0 %42 / 4283.3 %5 / 6
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
GenericMolInfo.cpp +
85.6%85.6%
+
85.6 %190 / 22283.3 %15 / 18
ActionWithValue.cpp +
89.6%89.6%
+
89.6 %112 / 12583.3 %25 / 30
Action.cpp +
79.2%79.2%
+
79.2 %122 / 15483.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
PlumedMainInitializer.cpp +
81.0%81.0%
+
81.0 %171 / 21187.5 %14 / 16
ActionSet.h +
100.0%
+
100.0 %18 / 1888.0 %22 / 25
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
ActionRegister.cpp +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
ActionWithArguments.cpp +
91.4%91.4%
+
91.4 %148 / 16291.7 %11 / 12
PlumedMain.cpp +
89.3%89.3%
+
89.3 %644 / 72192.9 %39 / 42
Atoms.cpp +
94.4%94.4%
+
94.4 %404 / 42895.0 %57 / 60
Action.h +
94.5%94.5%
+
94.5 %69 / 7396.2 %25 / 26
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
ActionWithVirtualAtom.h +
100.0%
+
100.0 %9 / 9-0 / 0
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
WithCmd.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionAtomistic.h +
100.0%
+
100.0 %34 / 34100.0 %4 / 4
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
Value.h +
95.3%95.3%
+
95.3 %41 / 43100.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.16
+
+ + + diff --git a/coverage/core/index-sort-l.html b/coverage/core/index-sort-l.html new file mode 100644 index 0000000000..c531a40bb2 --- /dev/null +++ b/coverage/core/index-sort-l.html @@ -0,0 +1,533 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3237376785.9 %
Date:2024-05-27 13:05:14Functions:43153580.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionSetup.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 +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
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
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
Action.cpp +
79.2%79.2%
+
79.2 %122 / 15483.3 %25 / 30
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
PlumedMainInitializer.cpp +
81.0%81.0%
+
81.0 %171 / 21187.5 %14 / 16
GenericMolInfo.cpp +
85.6%85.6%
+
85.6 %190 / 22283.3 %15 / 18
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
Value.cpp +
86.6%86.6%
+
86.6 %103 / 11981.2 %13 / 16
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
PlumedMain.cpp +
89.3%89.3%
+
89.3 %644 / 72192.9 %39 / 42
ActionWithValue.cpp +
89.6%89.6%
+
89.6 %112 / 12583.3 %25 / 30
ActionWithArguments.cpp +
91.4%91.4%
+
91.4 %148 / 16291.7 %11 / 12
MDAtoms.cpp +
91.7%91.7%
+
91.7 %166 / 18149.3 %33 / 67
ActionAtomistic.cpp +
91.9%91.9%
+
91.9 %171 / 18677.3 %17 / 22
Atoms.cpp +
94.4%94.4%
+
94.4 %404 / 42895.0 %57 / 60
Action.h +
94.5%94.5%
+
94.5 %69 / 7396.2 %25 / 26
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
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
DataFetchingObject.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
WithCmd.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
ActionWithVirtualAtom.h +
100.0%
+
100.0 %9 / 9-0 / 0
ActionSetup.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionWithArguments.h +
100.0%
+
100.0 %15 / 15100.0 %5 / 5
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
ActionSet.h +
100.0%
+
100.0 %18 / 1888.0 %22 / 25
Colvar.h +
100.0%
+
100.0 %29 / 29100.0 %7 / 7
ActionAtomistic.h +
100.0%
+
100.0 %34 / 34100.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.16
+
+ + + diff --git a/coverage/core/index.html b/coverage/core/index.html new file mode 100644 index 0000000000..c9e653865e --- /dev/null +++ b/coverage/core/index.html @@ -0,0 +1,533 @@ + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3237376785.9 %
Date:2024-05-27 13:05:14Functions:43153580.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Action.cpp +
79.2%79.2%
+
79.2 %122 / 15483.3 %25 / 30
Action.h +
94.5%94.5%
+
94.5 %69 / 7396.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.9%91.9%
+
91.9 %171 / 18677.3 %17 / 22
ActionAtomistic.h +
100.0%
+
100.0 %34 / 34100.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 +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionSet.h +
100.0%
+
100.0 %18 / 1888.0 %22 / 25
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.6%89.6%
+
89.6 %112 / 12583.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 %9 / 9-0 / 0
Atoms.cpp +
94.4%94.4%
+
94.4 %404 / 42895.0 %57 / 60
Atoms.h +
95.8%95.8%
+
95.8 %23 / 24100.0 %2 / 2
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
Colvar.cpp +
100.0%
+
100.0 %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 +
85.6%85.6%
+
85.6 %190 / 22283.3 %15 / 18
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
MDAtoms.cpp +
91.7%91.7%
+
91.7 %166 / 18149.3 %33 / 67
ModuleMap.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
PlumedMain.cpp +
89.3%89.3%
+
89.3 %644 / 72192.9 %39 / 42
PlumedMain.h +
88.9%88.9%
+
88.9 %16 / 18-0 / 0
PlumedMainInitializer.cpp +
81.0%81.0%
+
81.0 %171 / 21187.5 %14 / 16
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.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.func-sort-c.html b/coverage/crystallization/BondOrientation.cpp.func-sort-c.html new file mode 100644 index 0000000000..48bdc9bff9 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.func.html b/coverage/crystallization/BondOrientation.cpp.func.html new file mode 100644 index 0000000000..835a796526 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_127BondOrientationRegisterMe50D2Ev4168
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.gcov.html b/coverage/crystallization/BondOrientation.cpp.gcov.html new file mode 100644 index 0000000000..a334b2be1e --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(BondOrientation,"BOND_DIRECTIONS")
+      51             : 
+      52           4 : void BondOrientation::registerKeywords( Keywords& keys ) {
+      53           4 :   VectorMultiColvar::registerKeywords( keys );
+      54           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the vectors you wish to calculate. "
+      55             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one vector will be "
+      56             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      57             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+      58             :            "action will depend on what functions of the distribution you choose to calculate.");
+      59           8 :   keys.reset_style("ATOMS","atoms");
+      60           8 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+      61           8 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+      62             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+      63           8 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+      64             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+      65           8 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      66           8 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      67           8 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      68           8 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      69           8 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      70             :            "The following provides information on the \\ref switchingfunction that are available. "
+      71             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      72           8 :   keys.use("VMEAN"); keys.use("VSUM");
+      73           4 : }
+      74             : 
+      75           2 : BondOrientation::BondOrientation( const ActionOptions& ao ):
+      76             :   Action(ao),
+      77           2 :   VectorMultiColvar(ao)
+      78             : {
+      79             :   // Read atoms
+      80           2 :   weightHasDerivatives=true;
+      81             :   std::vector<AtomNumber> all_atoms;
+      82           4 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+      83           2 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+      84           2 :   setupMultiColvarBase( all_atoms );
+      85             :   // Read in the switching function
+      86           4 :   std::string sw, errors; parse("SWITCH",sw);
+      87           2 :   if(sw.length()>0) {
+      88           2 :     switchingFunction.set(sw,errors);
+      89             :   } else {
+      90           0 :     double r_0=-1.0, d_0; int nn, mm;
+      91           0 :     parse("NN",nn); parse("MM",mm);
+      92           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      93           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      94           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      95             :   }
+      96           2 :   log.printf("  orientation of those bonds with lengths are less than %s\n",( switchingFunction.description() ).c_str() );
+      97             :   // Set the link cell cutoff
+      98           2 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      99           2 :   double rcut = switchingFunction.get_dmax(); rcut2 = rcut*rcut;
+     100             :   // Set the dimensionality of the vectors
+     101           2 :   setVectorDimensionality(3);
+     102           2 : }
+     103             : 
+     104         150 : double BondOrientation::calculateWeight( const unsigned& current, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     105         150 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double distm=distance.modulo2();
+     106         150 :   if( distm>rcut2 ) return 0.0;
+     107          60 :   double df, ww=switchingFunction.calculateSqr( distm, df );
+     108             :   // Derivatives of weights
+     109          60 :   addAtomDerivatives( 0, 0, -df*weight*distance, myatoms );
+     110          60 :   addAtomDerivatives( 0, 1, df*weight*distance, myatoms );
+     111          60 :   myatoms.addBoxDerivatives( 0, (-df)*weight*Tensor(distance,distance) );
+     112          60 :   return ww;
+     113             : }
+     114             : 
+     115          60 : void BondOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+     116          60 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     117             : 
+     118          60 :   addAtomDerivatives( 2, 0, Vector(-1.0,0,0), myatoms );
+     119          60 :   addAtomDerivatives( 2, 1, Vector(+1.0,0,0), myatoms );
+     120          60 :   myatoms.addBoxDerivatives( 2, Tensor(distance,Vector(-1.0,0,0)) );
+     121          60 :   myatoms.addValue( 2, distance[0] );
+     122             : 
+     123          60 :   addAtomDerivatives( 3, 0, Vector(0,-1.0,0), myatoms );
+     124          60 :   addAtomDerivatives( 3, 1, Vector(0,+1.0,0), myatoms );
+     125          60 :   myatoms.addBoxDerivatives( 3, Tensor(distance,Vector(0,-1.0,0)) );
+     126          60 :   myatoms.addValue( 3, distance[1] );
+     127             : 
+     128          60 :   addAtomDerivatives( 4, 0, Vector(0,0,-1.0), myatoms );
+     129          60 :   addAtomDerivatives( 4, 1, Vector(0,0,+1.0), myatoms );
+     130          60 :   myatoms.addBoxDerivatives( 4, Tensor(distance,Vector(0,0,-1.0)) );
+     131          60 :   myatoms.addValue( 4, distance[2] );
+     132          60 : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html b/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..927d03e537 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.func.html b/coverage/crystallization/CubicHarmonicBase.cpp.func.html new file mode 100644 index 0000000000..0bd4230082 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html b/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html new file mode 100644 index 0000000000..382420ff1b --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-05-27 13:05: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          12 : void CubicHarmonicBase::registerKeywords( Keywords& keys ) {
+      34          12 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      35          36 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      36          24 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      37          24 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      38          24 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      39          24 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      40          24 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      41             :            "The following provides information on the \\ref switchingfunction that are available. "
+      42             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      43          24 :   keys.add("compulsory","PHI","0.0","The Euler rotational angle phi");
+      44          24 :   keys.add("compulsory","THETA","0.0","The Euler rotational angle theta");
+      45          24 :   keys.add("compulsory","PSI","0.0","The Euler rotational angle psi");
+      46          24 :   keys.addFlag("UNORMALIZED",false,"calculate the sum of the components of the vector rather than the mean");
+      47             :   // Use actionWithDistributionKeywords
+      48          48 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      49          48 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      50          36 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      51          12 : }
+      52             : 
+      53           6 : CubicHarmonicBase::CubicHarmonicBase(const ActionOptions&ao):
+      54             :   Action(ao),
+      55           6 :   MultiColvarBase(ao)
+      56             : {
+      57             :   // Read in the switching function
+      58          12 :   std::string sw, errors; parse("SWITCH",sw);
+      59           6 :   if(sw.length()>0) {
+      60           6 :     switchingFunction.set(sw,errors);
+      61           6 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+      62             :   } else {
+      63           0 :     double r_0=-1.0, d_0; int nn, mm;
+      64           0 :     parse("NN",nn); parse("MM",mm);
+      65           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      66           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      67           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      68             :   }
+      69             : 
+      70          18 :   double phi, theta, psi; parse("PHI",phi); parse("THETA",theta); parse("PSI",psi);
+      71           6 :   log.printf("  creating rotation matrix with Euler angles phi=%f, theta=%f and psi=%f\n",phi,theta,psi);
+      72             :   // Calculate the rotation matrix http://mathworld.wolfram.com/EulerAngles.html
+      73           6 :   rotationmatrix[0][0]=std::cos(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::sin(psi);
+      74           6 :   rotationmatrix[0][1]=std::cos(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::sin(psi);
+      75           6 :   rotationmatrix[0][2]=std::sin(psi)*std::sin(theta);
+      76             : 
+      77           6 :   rotationmatrix[1][0]=-std::sin(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::cos(psi);
+      78           6 :   rotationmatrix[1][1]=-std::sin(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::cos(psi);
+      79           6 :   rotationmatrix[1][2]=std::cos(psi)*std::sin(theta);
+      80             : 
+      81           6 :   rotationmatrix[2][0]=std::sin(theta)*std::sin(phi);
+      82           6 :   rotationmatrix[2][1]=-std::sin(theta)*std::cos(phi);
+      83           6 :   rotationmatrix[2][2]=std::cos(theta);
+      84             : 
+      85             : 
+      86           6 :   log.printf("  measure crystallinity around central atom.  Includes those atoms within %s\n",( switchingFunction.description() ).c_str() );
+      87           6 :   parseFlag("UNORMALIZED",unormalized);
+      88           6 :   if( unormalized ) log.printf("  output sum of vector functions \n");
+      89           6 :   else log.printf("  output mean of vector functions \n");
+      90             :   // Set the link cell cutoff
+      91           6 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+      92           6 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      93             :   // And setup the ActionWithVessel
+      94           6 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      95           6 : }
+      96             : 
+      97       26142 : double CubicHarmonicBase::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      98       26142 :   double dfunc; Vector rotatedis;
+      99             : 
+     100             :   // Calculate the coordination number
+     101       26142 :   Vector myder, rotateder, fder; unsigned nat=myatoms.getNumberOfAtoms();
+     102             : 
+     103     2517483 :   for(unsigned i=1; i<nat; ++i) {
+     104             :     Vector& distance=myatoms.getPosition(i);
+     105             : 
+     106             :     double d2;
+     107     3953726 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     108     1462385 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     109     3193615 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     110             :          d2>epsilon ) {
+     111             : 
+     112      328678 :       double sw = switchingFunction.calculateSqr( d2, dfunc );
+     113             : 
+     114      328678 :       rotatedis[0]=rotationmatrix[0][0]*distance[0]
+     115      328678 :                    +rotationmatrix[0][1]*distance[1]
+     116      328678 :                    +rotationmatrix[0][2]*distance[2];
+     117      328678 :       rotatedis[1]=rotationmatrix[1][0]*distance[0]
+     118      328678 :                    +rotationmatrix[1][1]*distance[1]
+     119      328678 :                    +rotationmatrix[1][2]*distance[2];
+     120      328678 :       rotatedis[2]=rotationmatrix[2][0]*distance[0]
+     121      328678 :                    +rotationmatrix[2][1]*distance[1]
+     122      328678 :                    +rotationmatrix[2][2]*distance[2];
+     123             : 
+     124      328678 :       double tmp = calculateCubicHarmonic( rotatedis, d2, rotateder );
+     125             : 
+     126      328678 :       myder[0]=rotationmatrix[0][0]*rotateder[0]
+     127      328678 :                +rotationmatrix[1][0]*rotateder[1]
+     128      328678 :                +rotationmatrix[2][0]*rotateder[2];
+     129      328678 :       myder[1]=rotationmatrix[0][1]*rotateder[0]
+     130      328678 :                +rotationmatrix[1][1]*rotateder[1]
+     131      328678 :                +rotationmatrix[2][1]*rotateder[2];
+     132      328678 :       myder[2]=rotationmatrix[0][2]*rotateder[0]
+     133      328678 :                +rotationmatrix[1][2]*rotateder[1]
+     134      328678 :                +rotationmatrix[2][2]*rotateder[2];
+     135             : 
+     136      328678 :       fder = (+dfunc)*tmp*distance + sw*myder;
+     137             : 
+     138      328678 :       accumulateSymmetryFunction( 1, i, sw*tmp, fder, Tensor(distance,-fder), myatoms );
+     139      328678 :       accumulateSymmetryFunction( -1, i, sw, (+dfunc)*distance, (-dfunc)*Tensor(distance,distance), myatoms );
+     140             :     }
+     141             :   }
+     142             :   // values -> der of... value [0], weight[1], x coord [2], y, z... [more magic]
+     143       26142 :   updateActiveAtoms( myatoms );
+     144       26142 :   if( !unormalized ) myatoms.getUnderlyingMultiValue().quotientRule( 1, 1 );
+     145       26142 :   return myatoms.getValue(1); // this is equivalent to getting an "atomic" CV
+     146             : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html b/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html new file mode 100644 index 0000000000..59ed71aacc --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.func.html b/coverage/crystallization/CubicHarmonicBase.h.func.html new file mode 100644 index 0000000000..c1ef1267f0 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.gcov.html b/coverage/crystallization/CubicHarmonicBase.h.gcov.html new file mode 100644 index 0000000000..afb44d43eb --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html b/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html new file mode 100644 index 0000000000..0d844dd54a --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:22624094.2 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe2176createERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERS2_IS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESaISH_EERd10
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv17
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceESt6vectorINS_13VectorGenericILj3EEESaIS4_EE17
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe217C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe217D2Ev4168
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.func.html b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html new file mode 100644 index 0000000000..7b1ba02d01 --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:22624094.2 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe2176createERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe217C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_134EnvironmentSimilarityRegisterMe217D2Ev4168
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv17
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceESt6vectorINS_13VectorGenericILj3EEESaIS4_EE17
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERS2_IS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESaISH_EERd10
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html new file mode 100644 index 0000000000..aaeaa70bff --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html @@ -0,0 +1,644 @@ + + + + + + + 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:22624094.2 %
Date:2024-05-27 13:05: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             : If multiple chemical species are involved in the calculation, it is possible to provide the atom types (names) both for atoms in the reference environments and in the simulation box.
+     100             : This information is provided in pdb files using the atom name field.
+     101             : The comparison between environments is performed taking into account whether the atom names match.
+     102             : 
+     103             : \par Examples
+     104             : 
+     105             : The following input calculates the ENVIRONMENTSIMILARITY kernel for 250 atoms in the system
+     106             : using the BCC atomic environment as target, and then calculates and prints the average value
+     107             :  for this quantity.
+     108             : 
+     109             : \plumedfile
+     110             : ENVIRONMENTSIMILARITY SPECIES=1-250 SIGMA=0.05 LATTICE_CONSTANTS=0.423 CRYSTAL_STRUCTURE=BCC MEAN LABEL=es
+     111             : 
+     112             : PRINT ARG=es.mean FILE=COLVAR
+     113             : \endplumedfile
+     114             : 
+     115             : The next example compares the environments of the 96 selected atoms with a user specified reference
+     116             : environment. The reference environment is contained in the env1.pdb file. Once the kernel is computed
+     117             :  the average and the number of atoms with a kernel larger than 0.5 are computed.
+     118             : 
+     119             : \plumedfile
+     120             : ENVIRONMENTSIMILARITY ...
+     121             :  SPECIES=1-288:3
+     122             :  SIGMA=0.05
+     123             :  CRYSTAL_STRUCTURE=CUSTOM
+     124             :  REFERENCE=env1.pdb
+     125             :  LABEL=es
+     126             :  MEAN
+     127             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     128             : ... ENVIRONMENTSIMILARITY
+     129             : 
+     130             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     131             : \endplumedfile
+     132             : 
+     133             : The next example is similar to the one above but in this case 4 reference environments are specified.
+     134             :  Each reference environment is given in a separate pdb file.
+     135             : 
+     136             : \plumedfile
+     137             : ENVIRONMENTSIMILARITY ...
+     138             :  SPECIES=1-288:3
+     139             :  SIGMA=0.05
+     140             :  CRYSTAL_STRUCTURE=CUSTOM
+     141             :  REFERENCE_1=env1.pdb
+     142             :  REFERENCE_2=env2.pdb
+     143             :  REFERENCE_3=env3.pdb
+     144             :  REFERENCE_4=env4.pdb
+     145             :  LABEL=es
+     146             :  MEAN
+     147             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     148             : ... ENVIRONMENTSIMILARITY
+     149             : 
+     150             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     151             : \endplumedfile
+     152             : 
+     153             : The following examples illustrates the use of pdb files to provide information about different chemical species:
+     154             : \plumedfile
+     155             : ENVIRONMENTSIMILARITY ...
+     156             :  SPECIES=1-6
+     157             :  SIGMA=0.05
+     158             :  CRYSTAL_STRUCTURE=CUSTOM
+     159             :  REFERENCE=env.pdb
+     160             :  LABEL=es
+     161             :  MEAN
+     162             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     163             :  ATOM_NAMES_FILE=atom-names.pdb
+     164             : ... ENVIRONMENTSIMILARITY
+     165             : \endplumedfile
+     166             : Here the file env.pdb is:
+     167             : \verbatim
+     168             : ATOM      1    O MOL     1      -2.239  -1.296  -0.917  1.00  0.00           O
+     169             : ATOM      2    O MOL     1       0.000   0.000   2.751  1.00  0.00           O
+     170             : \endverbatim
+     171             : where atoms are of type O, and the atom-names.pdb file is:
+     172             : \verbatim
+     173             : ATOM      1  O       X   1       0.000   2.593   4.126  0.00  0.00           O
+     174             : ATOM      2  H       X   1       0.000   3.509   3.847  0.00  0.00           H
+     175             : ATOM      3  H       X   1       0.000   2.635   5.083  0.00  0.00           H
+     176             : ATOM      4  O       X   1       0.000   2.593  11.462  0.00  0.00           O
+     177             : ATOM      5  H       X   1       0.000   3.509  11.183  0.00  0.00           H
+     178             : ATOM      6  H       X   1       0.000   2.635  12.419  0.00  0.00           H
+     179             : \endverbatim
+     180             : where atoms are of type O and H.
+     181             : In this case, all atoms are used as centers, but only neighbors of type O are taken into account.
+     182             : 
+     183             : */
+     184             : //+ENDPLUMEDOC
+     185             : 
+     186             : 
+     187             : class EnvironmentSimilarity : public multicolvar::MultiColvarBase {
+     188             : private:
+     189             :   // All global variables end with underscore
+     190             :   // square of cutoff, square of broadening parameter
+     191             :   double rcut2_, sigmaSqr_;
+     192             :   // lambda parameter for softmax function
+     193             :   double lambda_;
+     194             :   // Array of Vectors to store the reference environments, i.e. the templates
+     195             :   std::vector<std::vector<Vector>> environments_;
+     196             :   // Array of strings to store the atom names of reference environments
+     197             :   std::vector<std::vector<std::string>> environmentsAtomNames_;
+     198             :   // Use of atom names reference file
+     199             :   std::vector<std::string> atomNames_;
+     200             : public:
+     201             :   static void registerKeywords( Keywords& keys );
+     202             :   explicit EnvironmentSimilarity(const ActionOptions&);
+     203             : // active methods:
+     204             :   virtual double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+     205             : // Returns the number of coordinates of the field
+     206          17 :   bool isPeriodic() { return false; }
+     207             : // Calculates maximum distance in an environment
+     208             :   double maxDistance(std::vector<Vector> environment);
+     209             :   // Parse everything connected to the definition of the reference environments
+     210             :   // First argument is the array of Vectors that stores the reference environments
+     211             :   // Second argument is the array of strings that stores the atom names of reference environments
+     212             :   // Third argument is the maximum distance in the ref environments and sets the
+     213             :   // cutoff for the cell lists
+     214             :   void parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments,  std::vector<std::vector<std::string>>& environmentsAtomNames, double& max_dist);
+     215             : };
+     216             : 
+     217       12524 : PLUMED_REGISTER_ACTION(EnvironmentSimilarity,"ENVIRONMENTSIMILARITY")
+     218             : 
+     219          12 : void EnvironmentSimilarity::registerKeywords( Keywords& keys ) {
+     220          12 :   MultiColvarBase::registerKeywords( keys );
+     221          36 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     222          24 :   keys.add("compulsory","SIGMA","0.1","Broadening parameter");
+     223          24 :   keys.add("compulsory","CRYSTAL_STRUCTURE","FCC","Targeted crystal structure. Options are: "
+     224             :            "SC: simple cubic, "
+     225             :            "BCC: body center cubic, "
+     226             :            "FCC: face centered cubic, "
+     227             :            "HCP: hexagonal closed pack, "
+     228             :            "DIAMOND: cubic diamond, "
+     229             :            "CUSTOM: user defined "
+     230             :            " ");
+     231          24 :   keys.add("optional","LATTICE_CONSTANTS","Lattice constants. Two comma separated values for HCP, "
+     232             :            "one value for all other CRYSTAL_STRUCTURES.");
+     233          24 :   keys.add("compulsory","LAMBDA","100","Lambda parameter");
+     234          24 :   keys.add("optional","REFERENCE","PDB file with relative distances from central atom."
+     235             :            " Use this keyword if you are targeting a single reference environment.");
+     236          24 :   keys.add("numbered","REFERENCE_","PDB files with relative distances from central atom."
+     237             :            " Each file corresponds to one template."
+     238             :            " Use these keywords if you are targeting more than one reference environment.");
+     239          24 :   keys.add("optional","ATOM_NAMES_FILE","PDB file with atom names for all atoms in SPECIES."
+     240             :            " Atoms in reference environments will be compared only if atom names match.");
+     241             :   // Use actionWithDistributionKeywords
+     242          48 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     243          48 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     244          36 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     245          12 : }
+     246             : 
+     247          10 : EnvironmentSimilarity::EnvironmentSimilarity(const ActionOptions&ao):
+     248             :   Action(ao),
+     249          10 :   MultiColvarBase(ao)
+     250             : {
+     251          10 :   log.printf("  Please read and cite ");
+     252          20 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     253          10 :   log.printf("\n");
+     254             : 
+     255             :   // Parse everything connected to the definition of the reference environments
+     256             :   double max_dist_ref_vector;
+     257          10 :   parseReferenceEnvironments(environments_, environmentsAtomNames_, max_dist_ref_vector);
+     258             : 
+     259             :   double sigma;
+     260          10 :   parse("SIGMA", sigma);
+     261          10 :   log.printf("  representing local density as a sum of Gaussians with standard deviation %f\n",sigma);
+     262          10 :   sigmaSqr_=sigma*sigma;
+     263             : 
+     264          10 :   lambda_=100;
+     265          20 :   parse("LAMBDA", lambda_);
+     266          10 :   if (environments_.size()>1) log.printf("  using a soft max function with lambda %f\n",lambda_);
+     267             : 
+     268             :   // Set the link cell cutoff
+     269          10 :   double rcut = max_dist_ref_vector + 3*sigma;
+     270          10 :   setLinkCellCutoff( rcut );
+     271          10 :   rcut2_ = rcut * rcut;
+     272             : 
+     273             :   // And setup the ActionWithVessel
+     274          10 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms ); checkRead();
+     275             : 
+     276          10 :   plumed_massert(atomNames_.empty() || atomNames_.size()==getNumberOfAtoms(),"mismatch between atoms in SPECIES and ATOM_NAMES_FILE");
+     277          10 : }
+     278             : 
+     279       30144 : double EnvironmentSimilarity::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     280       30144 :   if (environments_.size()==1 && atomNames_.empty() ) {
+     281             :     // One reference environment case - no atom names
+     282      155464 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     283             :       const Vector& distance=myatoms.getPosition(i);
+     284             :       double d2;
+     285      232452 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     286       77840 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     287      194068 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     288             :            d2>epsilon ) {
+     289             :         // Iterate over atoms in the reference environment
+     290      236856 :         for(unsigned k=0; k<environments_[0].size(); ++k) {
+     291      220400 :           Vector distanceFromRef=distance-environments_[0][k];
+     292      220400 :           double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[0].size() ;
+     293      220400 :           accumulateSymmetryFunction( 1, i, value, -(value/(2*sigmaSqr_))*distanceFromRef, (value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     294             :         }
+     295             :       }
+     296             :     }
+     297             :     return myatoms.getValue(1);
+     298       29292 :   } else if (atomNames_.empty()) {
+     299             :     // More than one reference environment case - no atom names
+     300       29196 :     std::vector<double> values(environments_.size()); //value for each template
+     301             :     // First time calculate sums
+     302     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     303             :       const Vector& distance=myatoms.getPosition(i);
+     304             :       double d2;
+     305     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     306     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     307     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     308             :            d2>epsilon ) {
+     309             :         // Iterate over templates
+     310     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     311             :           // Iterate over atoms in the template
+     312     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     313     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     314     3921936 :             values[j] += std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     315             :           }
+     316             :         }
+     317             :       }
+     318             :     }
+     319             :     double sum=0;
+     320      145188 :     for(unsigned j=0; j<environments_.size(); ++j) {
+     321      115992 :       values[j] = std::exp(lambda_*values[j]);
+     322      115992 :       sum += values[j];
+     323             :     }
+     324             :     // Second time find derivatives
+     325     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     326             :       const Vector& distance=myatoms.getPosition(i);
+     327             :       double d2;
+     328     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     329     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     330     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     331             :            d2>epsilon ) {
+     332             :         // Iterate over reference environment
+     333     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     334             :           // Iterate over atoms in the reference environment
+     335     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     336     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     337     3921936 :             double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     338     3921936 :             accumulateSymmetryFunction( 1, i, value, -(values[j]/sum)*(value/(2*sigmaSqr_))*distanceFromRef, (values[j]/sum)*(value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     339             :           }
+     340             :         }
+     341             :       }
+     342             :     }
+     343       29196 :     return std::log(sum)/lambda_;
+     344             :   } else {
+     345             :     // Reference environments with atom names
+     346          96 :     std::vector<double> values(environments_.size()); //value for each template
+     347             :     // First time calculate sums
+     348       27648 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     349             :       const Vector& distance=myatoms.getPosition(i);
+     350             :       double d2;
+     351       42816 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     352       15264 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     353       33216 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     354             :            d2>epsilon ) {
+     355             :         // Iterate over templates
+     356        9600 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     357             :           // Iterate over atoms in the template
+     358       38400 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     359       30720 :             if (atomNames_[myatoms.getIndex(i)]==environmentsAtomNames_[j][k]) {
+     360        6144 :               Vector distanceFromRef=distance-environments_[j][k];
+     361        6144 :               values[j] += std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     362             :             }
+     363             :           }
+     364             :         }
+     365             :       }
+     366             :     }
+     367             :     double sum=0;
+     368         480 :     for(unsigned j=0; j<environments_.size(); ++j) {
+     369         384 :       values[j] = std::exp(lambda_*values[j]);
+     370         384 :       sum += values[j];
+     371             :     }
+     372             :     // Second time find derivatives
+     373       27648 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     374             :       const Vector& distance=myatoms.getPosition(i);
+     375             :       double d2;
+     376       42816 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     377       15264 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     378       33216 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     379             :            d2>epsilon ) {
+     380             :         // Iterate over reference environment
+     381        9600 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     382             :           // Iterate over atoms in the reference environment
+     383       38400 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     384       30720 :             if (atomNames_[myatoms.getIndex(i)]==environmentsAtomNames_[j][k]) {
+     385        6144 :               Vector distanceFromRef=distance-environments_[j][k];
+     386        6144 :               double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     387        6144 :               accumulateSymmetryFunction( 1, i, value, -(values[j]/sum)*(value/(2*sigmaSqr_))*distanceFromRef, (values[j]/sum)*(value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     388             :             }
+     389             :           }
+     390             :         }
+     391             :       }
+     392             :     }
+     393          96 :     return std::log(sum)/lambda_;
+     394             :   }
+     395             : }
+     396             : 
+     397          17 : double EnvironmentSimilarity::maxDistance( std::vector<Vector> environment ) {
+     398             :   double max_dist = 0.0;
+     399          85 :   for(unsigned i=0; i<environment.size(); ++i) {
+     400          68 :     double norm=environment[i].modulo();
+     401          68 :     if (norm>max_dist) max_dist=norm;
+     402             :   }
+     403          17 :   return max_dist;
+     404             : }
+     405             : 
+     406          10 : void EnvironmentSimilarity::parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments, std::vector<std::vector<std::string>>& environmentsAtomNames, double& max_dist) {
+     407             :   std::vector<double> lattice_constants;
+     408          20 :   parseVector("LATTICE_CONSTANTS", lattice_constants);
+     409             :   std::string crystal_structure;
+     410          20 :   parse("CRYSTAL_STRUCTURE", crystal_structure);
+     411             :   // find crystal structure
+     412          10 :   if (crystal_structure == "FCC") {
+     413           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for FCC");
+     414           1 :     environments.resize(1);
+     415           1 :     environments[0].resize(12);
+     416           1 :     environments[0][0]  = Vector(+0.5,+0.5,+0.0)*lattice_constants[0];
+     417           1 :     environments[0][1]  = Vector(-0.5,-0.5,+0.0)*lattice_constants[0];
+     418           1 :     environments[0][2]  = Vector(+0.5,-0.5,+0.0)*lattice_constants[0];
+     419           1 :     environments[0][3]  = Vector(-0.5,+0.5,+0.0)*lattice_constants[0];
+     420           1 :     environments[0][4]  = Vector(+0.5,+0.0,+0.5)*lattice_constants[0];
+     421           1 :     environments[0][5]  = Vector(-0.5,+0.0,-0.5)*lattice_constants[0];
+     422           1 :     environments[0][6]  = Vector(-0.5,+0.0,+0.5)*lattice_constants[0];
+     423           1 :     environments[0][7]  = Vector(+0.5,+0.0,-0.5)*lattice_constants[0];
+     424           1 :     environments[0][8]  = Vector(+0.0,+0.5,+0.5)*lattice_constants[0];
+     425           1 :     environments[0][9]  = Vector(+0.0,-0.5,-0.5)*lattice_constants[0];
+     426           1 :     environments[0][10] = Vector(+0.0,-0.5,+0.5)*lattice_constants[0];
+     427           1 :     environments[0][11] = Vector(+0.0,+0.5,-0.5)*lattice_constants[0];
+     428           1 :     max_dist = std::sqrt(2)*lattice_constants[0]/2.;
+     429           9 :   } else if (crystal_structure == "SC") {
+     430           0 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for SC");
+     431           0 :     environments.resize(1);
+     432           0 :     environments[0].resize(6);
+     433           0 :     environments[0][0]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     434           0 :     environments[0][1]  = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     435           0 :     environments[0][2]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     436           0 :     environments[0][3]  = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     437           0 :     environments[0][4]  = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     438           0 :     environments[0][5]  = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     439           0 :     max_dist = lattice_constants[0];
+     440           9 :   } else if (crystal_structure == "BCC") {
+     441           2 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for BCC");
+     442           2 :     environments.resize(1);
+     443           2 :     environments[0].resize(14);
+     444           2 :     environments[0][0]  = Vector(+0.5,+0.5,+0.5)*lattice_constants[0];
+     445           2 :     environments[0][1]  = Vector(-0.5,-0.5,-0.5)*lattice_constants[0];
+     446           2 :     environments[0][2]  = Vector(-0.5,+0.5,+0.5)*lattice_constants[0];
+     447           2 :     environments[0][3]  = Vector(+0.5,-0.5,+0.5)*lattice_constants[0];
+     448           2 :     environments[0][4]  = Vector(+0.5,+0.5,-0.5)*lattice_constants[0];
+     449           2 :     environments[0][5]  = Vector(-0.5,-0.5,+0.5)*lattice_constants[0];
+     450           2 :     environments[0][6]  = Vector(+0.5,-0.5,-0.5)*lattice_constants[0];
+     451           2 :     environments[0][7]  = Vector(-0.5,+0.5,-0.5)*lattice_constants[0];
+     452           2 :     environments[0][8]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     453           2 :     environments[0][9]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     454           2 :     environments[0][10] = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     455           2 :     environments[0][11] = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     456           2 :     environments[0][12] = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     457           2 :     environments[0][13] = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     458           2 :     max_dist = lattice_constants[0];
+     459           7 :   } else if (crystal_structure == "HCP") {
+     460           1 :     if (lattice_constants.size() != 2) error("Number of LATTICE_CONSTANTS arguments must be two for HCP");
+     461           1 :     environments.resize(2);
+     462           1 :     environments[0].resize(12);
+     463           1 :     environments[1].resize(12);
+     464             :     double sqrt3=std::sqrt(3);
+     465           1 :     environments[0][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     466           1 :     environments[0][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     467           1 :     environments[0][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     468           1 :     environments[0][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     469           1 :     environments[0][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     470           1 :     environments[0][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     471           1 :     environments[0][6]  = Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     472           1 :     environments[0][7]  = Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     473           1 :     environments[0][8]  = Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     474           1 :     environments[0][9]  = Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     475           1 :     environments[0][10] = Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     476           1 :     environments[0][11] = Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     477           1 :     environments[1][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     478           1 :     environments[1][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     479           1 :     environments[1][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     480           1 :     environments[1][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     481           1 :     environments[1][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     482           1 :     environments[1][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     483           1 :     environments[1][6]  = Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     484           1 :     environments[1][7]  = Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     485           1 :     environments[1][8]  = Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     486           1 :     environments[1][9]  = Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     487           1 :     environments[1][10] = Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     488           1 :     environments[1][11] = Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     489           1 :     max_dist = lattice_constants[0];
+     490           6 :   } else if (crystal_structure == "DIAMOND") {
+     491           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for DIAMOND");
+     492           1 :     environments.resize(2);
+     493           1 :     environments[0].resize(4); environments[1].resize(4);
+     494           1 :     environments[0][0]  = Vector(+1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     495           1 :     environments[0][1]  = Vector(-1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     496           1 :     environments[0][2]  = Vector(+1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     497           1 :     environments[0][3]  = Vector(-1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     498           1 :     environments[1][0]  = Vector(+1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     499           1 :     environments[1][1]  = Vector(-1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     500           1 :     environments[1][2]  = Vector(+1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     501           1 :     environments[1][3]  = Vector(-1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     502           1 :     max_dist = std::sqrt(3)*lattice_constants[0]/4.0;
+     503           5 :   } else if (crystal_structure == "CUSTOM") {
+     504             :     std::string reffile;
+     505          10 :     parse("REFERENCE",reffile);
+     506           5 :     if (!reffile.empty()) {
+     507             :       // Case with one reference environment
+     508           1 :       environments.resize(1); environmentsAtomNames.resize(1);
+     509           1 :       PDB pdb;
+     510           2 :       if( !pdb.read(reffile,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     511           0 :         error("missing input file " + reffile );
+     512           1 :       unsigned natoms=pdb.getPositions().size();
+     513           1 :       environments[0].resize( natoms ); environmentsAtomNames[0].resize( natoms );
+     514           5 :       for(unsigned i=0; i<natoms; ++i) environments[0][i]=pdb.getPositions()[i];
+     515           5 :       for(unsigned i=0; i<natoms; ++i) environmentsAtomNames[0][i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     516           1 :       max_dist=maxDistance(environments[0]);
+     517           1 :       log.printf("  reading %d reference vectors from %s \n", natoms, reffile.c_str() );
+     518           1 :     } else {
+     519             :       // Case with several reference environments
+     520           4 :       max_dist=0;
+     521          16 :       for(unsigned int i=1;; i++) {
+     522          40 :         if(!parseNumbered("REFERENCE_",i,reffile) ) {break;}
+     523          16 :         PDB pdb;
+     524          32 :         if( !pdb.read(reffile,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     525           0 :           error("missing input file " + reffile );
+     526          16 :         unsigned natoms=pdb.getPositions().size();
+     527             :         std::vector<Vector> environment; std::vector<std::string> environmentAtomNames;
+     528          16 :         environment.resize( natoms ); environmentAtomNames.resize( natoms);
+     529          80 :         for(unsigned i=0; i<natoms; ++i) environment[i]=pdb.getPositions()[i];
+     530          80 :         for(unsigned i=0; i<natoms; ++i) environmentAtomNames[i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     531          16 :         environments.push_back(environment);
+     532          16 :         environmentsAtomNames.push_back(environmentAtomNames);
+     533          16 :         double norm = maxDistance(environment);
+     534          16 :         if (norm>max_dist) max_dist=norm;
+     535          16 :         log.printf("  Reference environment %d : reading %d reference vectors from %s \n", i, natoms, reffile.c_str() );
+     536          32 :       }
+     537             :     }
+     538           5 :     if (environments.size()==0) error("No environments have been found! Please specify a PDB file in the REFERENCE "
+     539             :                                         "or in the REFERENCE_1, REFERENCE_2, etc keywords");
+     540           5 :     log.printf("  Number of reference environments is %lu\n",environments.size() );
+     541           5 :     log.printf("  Number of vectors per reference environment is %lu\n",environments[0].size() );
+     542             :     std::string atomNamesFile;
+     543          10 :     parse("ATOM_NAMES_FILE",atomNamesFile);
+     544           5 :     if (!atomNamesFile.empty()) {
+     545           1 :       PDB pdb;
+     546           2 :       if( !pdb.read(atomNamesFile,plumed.getAtoms().usingNaturalUnits(),0.1/plumed.getAtoms().getUnits().getLength()) )
+     547           0 :         error("missing input file " + atomNamesFile);
+     548           1 :       unsigned natoms=pdb.getPositions().size();
+     549           1 :       atomNames_.resize( natoms );
+     550         385 :       for(unsigned i=0; i<natoms; ++i) atomNames_[i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     551           1 :       log.printf("  Read %d atoms from atom names file %s \n", natoms, atomNamesFile.c_str() );
+     552           1 :       log.printf("  Atoms in environments will be considered only if atom names match.\n");
+     553           1 :     } else {
+     554           4 :       log.printf("  No atom names file has been given. Atoms in reference environments will be matched disregarding atom type.\n");
+     555             :     }
+     556             :   } else {
+     557           0 :     error("CRYSTAL_STRUCTURE=" + crystal_structure + " does not match any structures in the database");
+     558             :   }
+     559             : 
+     560          10 :   log.printf("  targeting the %s crystal structure",crystal_structure.c_str());
+     561          10 :   if (lattice_constants.size()>0) log.printf(" with lattice constants %f\n",lattice_constants[0]);
+     562           5 :   else log.printf("\n");
+     563             : 
+     564          10 :   log.printf("  maximum distance in the reference environment is %f\n",max_dist);
+     565          10 : }
+     566             : 
+     567             : }
+     568             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.func-sort-c.html b/coverage/crystallization/Fccubic.cpp.func-sort-c.html new file mode 100644 index 0000000000..dab382924d --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe846createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84D2Ev4168
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.func.html b/coverage/crystallization/Fccubic.cpp.func.html new file mode 100644 index 0000000000..54e3eaf4b7 --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe846createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_119FccubicRegisterMe84D2Ev4168
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.gcov.html b/coverage/crystallization/Fccubic.cpp.gcov.html new file mode 100644 index 0000000000..01a4d5e9a4 --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(Fccubic,"FCCUBIC")
+      85             : 
+      86           6 : void Fccubic::registerKeywords( Keywords& keys ) {
+      87           6 :   CubicHarmonicBase::registerKeywords( keys );
+      88          12 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
+      89           6 : }
+      90             : 
+      91           4 : Fccubic::Fccubic(const ActionOptions&ao):
+      92             :   Action(ao),
+      93           4 :   CubicHarmonicBase(ao)
+      94             : {
+      95             :   // Scaling factors such that '1' corresponds to fcc lattice
+      96             :   // and '0' corresponds to isotropic (liquid)
+      97           4 :   parse("ALPHA",alpha);
+      98           4 :   a1 = 80080. / (2717. + 16*alpha); b1 = 16.*(alpha-143)/(2717+16*alpha);
+      99           4 :   log.printf("  setting alpha parameter equal to %f \n",alpha);
+     100             :   // And setup the ActionWithVessel
+     101           4 :   checkRead();
+     102           4 : }
+     103             : 
+     104      320614 : double Fccubic::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+     105      320614 :   double x2 = distance[0]*distance[0];
+     106      320614 :   double x4 = x2*x2;
+     107             : 
+     108      320614 :   double y2 = distance[1]*distance[1];
+     109      320614 :   double y4 = y2*y2;
+     110             : 
+     111      320614 :   double z2 = distance[2]*distance[2];
+     112      320614 :   double z4 = z2*z2;
+     113             : 
+     114      320614 :   double r8 = pow( d2, 4 );
+     115             :   double r12 = pow( d2, 6 );
+     116             : 
+     117      320614 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
+     118             : 
+     119      320614 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
+     120      320614 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
+     121      320614 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
+     122      320614 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
+     123             : 
+     124      320614 :   myder[0]=4*a1*distance[0]*(t0-t3);
+     125      320614 :   myder[1]=4*a1*distance[1]*(t1-t3);
+     126      320614 :   myder[2]=4*a1*distance[2]*(t2-t3);
+     127             : 
+     128      320614 :   return a1*tmp+b1;
+     129             : }
+     130             : 
+     131             : }
+     132             : }
+     133             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.func-sort-c.html b/coverage/crystallization/Gradient.cpp.func-sort-c.html new file mode 100644 index 0000000000..4d2cf8fc55 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62D2Ev4168
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.func.html b/coverage/crystallization/Gradient.cpp.func.html new file mode 100644 index 0000000000..4c1cc251a9 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_120GradientRegisterMe62D2Ev4168
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.gcov.html b/coverage/crystallization/Gradient.cpp.gcov.html new file mode 100644 index 0000000000..63b9a12580 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.gcov.html @@ -0,0 +1,243 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(Gradient,"GRADIENT")
+      63             : 
+      64           4 : void Gradient::registerKeywords( Keywords& keys ) {
+      65           4 :   VolumeGradientBase::registerKeywords( keys );
+      66           8 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin in our calculation");
+      67           8 :   keys.add("compulsory","DIR","xyz","the directions in which we are calculating the gradient.  Should be x, y, z, xy, xz, yz or xyz");
+      68           8 :   keys.add("compulsory","NBINS","number of bins to use in each direction for the calculation of the gradient");
+      69           8 :   keys.add("compulsory","SIGMA","1.0","the width of the function to be used for kernel density estimation");
+      70           8 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      71           4 : }
+      72             : 
+      73           2 : Gradient::Gradient(const ActionOptions&ao):
+      74             :   Action(ao),
+      75             :   VolumeGradientBase(ao),
+      76           2 :   nbins(3)
+      77             : {
+      78             :   std::vector<AtomNumber> atom;
+      79           4 :   parseAtomList("ORIGIN",atom);
+      80           2 :   if( atom.size()!=1 ) error("should only be one atom specified");
+      81           2 :   log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+      82             : 
+      83           4 :   std::string direction; parse("DIR",direction);
+      84           2 :   std::vector<unsigned> tbins; parseVector("NBINS",tbins);
+      85           4 :   for(unsigned i=0; i<tbins.size(); ++i) {
+      86           2 :     if( tbins[i]<2 ) error("Number of grid points should be greater than 1");
+      87             :   }
+      88             : 
+      89           2 :   if( direction=="x" ) {
+      90           2 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      91           2 :     nbins[0]=tbins[0]; nbins[1]=0; nbins[2]=0;
+      92           0 :   } else if( direction=="y" ) {
+      93           0 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      94           0 :     nbins[0]=0; nbins[1]=tbins[0]; nbins[2]=0;
+      95           0 :   } else if( direction=="z" ) {
+      96           0 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      97           0 :     nbins[0]=0; nbins[1]=0; nbins[2]=tbins[0];
+      98           0 :   } else if( direction=="xy" ) {
+      99           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     100           0 :     nbins[0]=tbins[0]; nbins[1]=tbins[1]; nbins[2]=0;
+     101           0 :   } else if( direction=="xz" ) {
+     102           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     103           0 :     nbins[0]=tbins[0]; nbins[1]=0; nbins[2]=tbins[1];
+     104           0 :   } else if( direction=="yz" ) {
+     105           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     106           0 :     nbins[0]=0; nbins[1]=tbins[0]; nbins[2]=tbins[1];
+     107           0 :   } else if( direction=="xyz" ) {
+     108           0 :     if( tbins.size()!=3 ) error("mismatch between number of bins and direction");
+     109           0 :     nbins[0]=tbins[0]; nbins[1]=tbins[1]; nbins[2]=tbins[2];
+     110             :   } else {
+     111           0 :     error( direction + " is not valid gradient direction");
+     112             :   }
+     113             : 
+     114             :   // Find number of quantities
+     115           2 :   if( getPntrToMultiColvar()->isDensity() ) vend=2;
+     116           1 :   else if( getPntrToMultiColvar()->getNumberOfQuantities()==2 ) vend=2;
+     117           0 :   else vend = getPntrToMultiColvar()->getNumberOfQuantities();
+     118           2 :   nquantities = vend + nbins[0] + nbins[1] + nbins[2];
+     119             : 
+     120             :   // Output some nice information
+     121           2 :   std::string functype=getPntrToMultiColvar()->getName();
+     122          27 :   std::transform( functype.begin(), functype.end(), functype.begin(), [](unsigned char c) { return std::tolower(c); } );
+     123           2 :   log.printf("  calculating gradient of %s in %s direction \n",functype.c_str(), direction.c_str() );
+     124           4 :   log<<"  Bibliography:"<<plumed.cite("Giberti, Tribello and Parrinello, J. Chem. Theory Comput., 9, 2526 (2013)")<<"\n";
+     125             : 
+     126           4 :   parse("SIGMA",sigma); parse("KERNEL",kerneltype);
+     127           2 :   checkRead(); requestAtoms(atom);
+     128             : 
+     129             :   // And setup the vessel
+     130           2 :   std::string input; addVessel( "GRADIENT", input, -1 );
+     131             :   // And resize everything
+     132           2 :   readVesselKeywords();
+     133           2 : }
+     134             : 
+     135         232 : void Gradient::setupRegions() {
+     136             : //  if( !getPbc().isOrthorombic() ) error("cell must be orthorhombic when using gradient");
+     137         232 : }
+     138             : 
+     139       11600 : void Gradient::calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const {
+     140             :   // Setup the bead
+     141       11600 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
+     142             : 
+     143       11600 :   Vector cpos = pbcDistance( getPosition(0), getPntrToMultiColvar()->getCentralAtomPos( curr ) );
+     144             :   // Note we use the pbc from base multicolvar so that we get numerical derivatives correct
+     145       11600 :   Vector oderiv, fpos = (getPntrToMultiColvar()->getPbc()).realToScaled( cpos );
+     146             : 
+     147       11600 :   Vector deriv; unsigned nbase=vend; std::vector<Vector> refder(1); Tensor vir; vir.zero();
+     148       46400 :   for(unsigned idir=0; idir<3; ++idir) {
+     149       34800 :     deriv[0]=deriv[1]=deriv[2]=0.0;
+     150       34800 :     double delx = 1.0 / static_cast<double>( nbins[idir] );
+     151       81200 :     for(unsigned jbead=0; jbead<nbins[idir]; ++jbead) {
+     152             :       // Calculate what box we are in
+     153       46400 :       bead.set( -0.5+jbead*delx, -0.5+(jbead+1)*delx, sigma );
+     154       46400 :       double weight=bead.calculate( fpos[0], deriv[idir] );
+     155       46400 :       oderiv = (getPntrToMultiColvar()->getPbc()).realToScaled( deriv );
+     156             :       // Set and derivatives
+     157       46400 :       refder[0]=-oderiv; // vir = -Tensor(cpos,oderiv);
+     158       46400 :       setNumberInVolume( nbase+jbead, curr, weight, oderiv, vir, refder, outvals );
+     159             : //          addReferenceAtomDerivatives( nbase+jbead, 0, -oderiv );
+     160             : //          addBoxDerivatives( nbase+jbead, -Tensor(cpos,oderiv) );
+     161             :     }
+     162       34800 :     nbase += nbins[idir];
+     163             :   }
+     164       11600 : }
+     165             : 
+     166             : }
+     167             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.func-sort-c.html b/coverage/crystallization/Gradient.h.func-sort-c.html new file mode 100644 index 0000000000..32ec65f7f5 --- /dev/null +++ b/coverage/crystallization/Gradient.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.func.html b/coverage/crystallization/Gradient.h.func.html new file mode 100644 index 0000000000..95a1db1779 --- /dev/null +++ b/coverage/crystallization/Gradient.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.gcov.html b/coverage/crystallization/Gradient.h.gcov.html new file mode 100644 index 0000000000..0aca525f0d --- /dev/null +++ b/coverage/crystallization/Gradient.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.func-sort-c.html b/coverage/crystallization/GradientVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..0816e2a494 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_124GradientVesselRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev4168
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.func.html b/coverage/crystallization/GradientVessel.cpp.func.html new file mode 100644 index 0000000000..231a085a81 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev4168
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD15crystallization14GradientVessel16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization14GradientVessel16value_descriptorB5cxx11Ev2
_ZN4PLMD15crystallization14GradientVessel6finishERKSt6vectorIdSaIdEE232
_ZN4PLMD15crystallization14GradientVessel6resizeEv4
_ZN4PLMD15crystallization14GradientVesselC2ERKNS_10vesselbase13VesselOptionsE2
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.gcov.html b/coverage/crystallization/GradientVessel.cpp.gcov.html new file mode 100644 index 0000000000..dec451db90 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_VESSEL(GradientVessel,"GRADIENT")
+      48             : 
+      49           2 : void GradientVessel::registerKeywords( Keywords& keys ) {
+      50           2 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      51           2 : }
+      52             : 
+      53        4168 : void GradientVessel::reserveKeyword( Keywords& keys ) {
+      54        8336 :   keys.reserve("vessel","GRADIENT","calculate the gradient");
+      55        8336 :   keys.addOutputComponent("gradient","GRADIENT","the gradient");
+      56        4168 : }
+      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.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html b/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html new file mode 100644 index 0000000000..f5d030a3cf --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.func.html b/coverage/crystallization/InterMolecularTorsions.cpp.func.html new file mode 100644 index 0000000000..37ee7e7a86 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe966createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_134InterMolecularTorsionsRegisterMe96D2Ev4168
_ZN4PLMD15crystallization22InterMolecularTorsions10isPeriodicEv0
_ZN4PLMD15crystallization22InterMolecularTorsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD15crystallization22InterMolecularTorsions16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization22InterMolecularTorsionsC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization22InterMolecularTorsions15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD15crystallization22InterMolecularTorsions7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html b/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html new file mode 100644 index 0000000000..36198dcb19 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(InterMolecularTorsions,"INTERMOLECULARTORSIONS")
+      97             : 
+      98           2 : void InterMolecularTorsions::registerKeywords( Keywords& keys ) {
+      99           2 :   MultiColvarBase::registerKeywords( keys );
+     100           4 :   keys.add("atoms","MOLS","The molecules you would like to calculate the torsional angles between. This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     101           4 :   keys.add("atoms-1","MOLSA","In this version of the input the torsional angles between all pairs of atoms including one atom from MOLSA one atom from MOLSB will be computed. "
+     102             :            "This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     103           4 :   keys.add("atoms-1","MOLSB","In this version of the input the torsional angles between all pairs of atoms including one atom from MOLSA one atom from MOLSB will be computed. "
+     104             :            "This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     105           4 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     106           4 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     107           4 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     108           4 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     109           4 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     110             :            "The following provides information on the \\ref switchingfunction that are available. "
+     111             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     112             :   // Use actionWithDistributionKeywords
+     113           2 :   keys.remove("LOWMEM");
+     114           4 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     115           2 : }
+     116             : 
+     117           0 : InterMolecularTorsions::InterMolecularTorsions(const ActionOptions& ao):
+     118             :   Action(ao),
+     119           0 :   MultiColvarBase(ao)
+     120             : {
+     121           0 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     122           0 :     if( getBaseMultiColvar(i)->getNumberOfQuantities()!=5 ) error("input multicolvar does not calculate molecular orientations");
+     123             :   }
+     124             :   // The weight of this does have derivatives
+     125           0 :   weightHasDerivatives=true;
+     126             : 
+     127             :   // Read in the switching function
+     128           0 :   std::string sw, errors; parse("SWITCH",sw);
+     129           0 :   if(sw.length()>0) {
+     130           0 :     switchingFunction.set(sw,errors);
+     131             :   } else {
+     132           0 :     double r_0=-1.0, d_0; int nn, mm;
+     133           0 :     parse("NN",nn); parse("MM",mm);
+     134           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     135           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     136           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     137             :   }
+     138           0 :   log.printf("  calculating number of links with atoms separation of %s\n",( switchingFunction.description() ).c_str() );
+     139           0 :   std::vector<AtomNumber> all_atoms; readTwoGroups( "MOLS", "MOLSA", "MOLSB", all_atoms );
+     140           0 :   setupMultiColvarBase( all_atoms ); setLinkCellCutoff( switchingFunction.get_dmax() );
+     141             : 
+     142           0 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     143           0 :     if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     144             :   }
+     145             : 
+     146             :   // Create holders for the collective variable
+     147           0 :   readVesselKeywords();
+     148           0 :   plumed_assert( getNumberOfVessels()==0 );
+     149           0 :   std::string input; addVessel( "SUM", input, -1 );
+     150           0 :   readVesselKeywords();
+     151           0 : }
+     152             : 
+     153           0 : double InterMolecularTorsions::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     154           0 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     155           0 :   double dfunc, sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
+     156             : 
+     157           0 :   if( !doNotCalculateDerivatives() ) {
+     158           0 :     addAtomDerivatives( 0, 0, (-dfunc)*weight*distance, myatoms );
+     159           0 :     addAtomDerivatives( 0, 1, (dfunc)*weight*distance, myatoms );
+     160           0 :     myatoms.addBoxDerivatives( 0, (-dfunc)*weight*Tensor(distance,distance) );
+     161             :   }
+     162           0 :   return sw;
+     163             : }
+     164             : 
+     165           0 : double InterMolecularTorsions::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     166           0 :   Vector v1, v2, dv1, dv2, dconn, conn = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     167             : 
+     168             :   // Retrieve vectors
+     169           0 :   std::vector<double> orient0( 5 ), orient1( 5 );
+     170           0 :   getInputData( 0, true, myatoms, orient0 );
+     171           0 :   getInputData( 1, true, myatoms, orient1 );
+     172           0 :   for(unsigned i=0; i<3; ++i) { v1[i]=orient0[2+i]; v2[i]=orient1[2+i]; }
+     173           0 :   if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0;
+     174             : 
+     175             :   // Evaluate angle
+     176           0 :   Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 );
+     177           0 :   for(unsigned i=0; i<3; ++i) { orient0[i+2]=dv1[i]; orient1[i+2]=dv2[i]; }
+     178             : 
+     179             :   // And accumulate derivatives
+     180           0 :   if( !doNotCalculateDerivatives() ) {
+     181           0 :     MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+     182           0 :     mergeInputDerivatives( 1, 2, orient1.size(), 0, orient0, myder0, myatoms );
+     183           0 :     MultiValue& myder1=getInputDerivatives( 1, true, myatoms );
+     184           0 :     mergeInputDerivatives( 1, 2, orient0.size(), 1, orient1, myder1, myatoms );
+     185           0 :     addAtomDerivatives( 1, 0, -dconn, myatoms ); addAtomDerivatives( 1, 1, dconn, myatoms );
+     186           0 :     myatoms.addBoxDerivatives( 1, -extProduct( conn, dconn ) );
+     187             :   }
+     188             : 
+     189             :   return angle;
+     190             : }
+     191             : 
+     192             : }
+     193             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html b/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html new file mode 100644 index 0000000000..1acd79ade4 --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EEC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_43186
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.func.html b/coverage/crystallization/LocalSteinhardt.h.func.html new file mode 100644 index 0000000000..6badce9cad --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EEC1ERKNS_13ActionOptionsE5
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_43186
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.gcov.html b/coverage/crystallization/LocalSteinhardt.h.gcov.html new file mode 100644 index 0000000000..f1b140ddfa --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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          11 :   static void registerKeywords( Keywords& keys ) {
+      33          11 :     OrientationSphere::registerKeywords(keys);
+      34          11 :   }
+      35           5 :   explicit LocalSteinhardt(const ActionOptions& ao): Action(ao), OrientationSphere(ao)
+      36             :   {
+      37          12 :     for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      38           7 :       T* mc=dynamic_cast<T*>( getBaseMultiColvar(i) );
+      39           7 :       if(!mc) {
+      40           0 :         if( getBaseMultiColvar(i)->getNumberOfBaseMultiColvars()==0 ) {
+      41           0 :           error("input action is not calculating the correct vectors");
+      42             :         }
+      43           0 :         for(unsigned j=0; j<getBaseMultiColvar(i)->getNumberOfBaseMultiColvars(); ++j) {
+      44           0 :           T* mmc=dynamic_cast<T*>( getBaseMultiColvar(i)->getBaseMultiColvar(j) );
+      45           0 :           if( !mmc ) error("input action is not calculating the correct vectors");
+      46             :         }
+      47             :       }
+      48             :     }
+      49           5 :   }
+      50       43186 :   double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      51             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override {
+      52       43186 :     double dot=0; dconn.zero();
+      53     1166022 :     for(unsigned k=2; k<vec1.size(); ++k) {
+      54     1122836 :       dot+=vec1[k]*vec2[k]; dvec1[k]=vec2[k]; dvec2[k]=vec1[k];
+      55             :     }
+      56       43186 :     return dot;
+      57             :   }
+      58             : };
+      59             : 
+      60             : }
+      61             : }
+      62             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html b/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html new file mode 100644 index 0000000000..9aec4586c6 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64D2Ev4168
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.func.html b/coverage/crystallization/MoleculeOrientation.cpp.func.html new file mode 100644 index 0000000000..25bc68ec0c --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe646createERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_131MoleculeOrientationRegisterMe64D2Ev4168
_ZN4PLMD15crystallization19MoleculeOrientation16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization19MoleculeOrientationC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.gcov.html b/coverage/crystallization/MoleculeOrientation.cpp.gcov.html new file mode 100644 index 0000000000..086f033da9 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(MoleculeOrientation,"MOLECULES")
+      65             : 
+      66           6 : void MoleculeOrientation::registerKeywords( Keywords& keys ) {
+      67          12 :   VectorMultiColvar::registerKeywords( keys ); keys.use("MEAN"); keys.use("VMEAN");
+      68          12 :   keys.add("numbered","MOL","The numerical indices of the atoms in the molecule. The orientation of the molecule is equal to "
+      69             :            "the vector connecting the first two atoms specified.  If a third atom is specified its position "
+      70             :            "is used to specify where the molecule is.  If a third atom is not present the molecule is assumed "
+      71             :            "to be at the center of the vector connecting the first two atoms.");
+      72          12 :   keys.reset_style("MOL","atoms");
+      73           6 : }
+      74             : 
+      75           4 : MoleculeOrientation::MoleculeOrientation( const ActionOptions& ao ):
+      76             :   Action(ao),
+      77           4 :   VectorMultiColvar(ao)
+      78             : {
+      79             :   std::vector<AtomNumber> all_atoms;
+      80           8 :   readAtomsLikeKeyword("MOL",-1,all_atoms);
+      81           4 :   nvectors = std::floor( ablocks.size() / 2 );
+      82           4 :   if( ablocks.size()%2!=0 && 2*nvectors+1!=ablocks.size() ) error("number of atoms in molecule specification is wrong.  Should be two or three.");
+      83             : 
+      84           4 :   if( all_atoms.size()==0 ) error("No atoms were specified");
+      85           4 :   setVectorDimensionality( 3*nvectors ); setupMultiColvarBase( all_atoms );
+      86             : 
+      87           4 :   if( ablocks.size()==2*nvectors+1  ) {
+      88           4 :     std::vector<bool> catom_ind(ablocks.size(), false); catom_ind[ablocks.size()-1]=true;
+      89           4 :     setAtomsForCentralAtom( catom_ind );
+      90             :   }
+      91           4 : }
+      92             : 
+      93           0 : AtomNumber MoleculeOrientation::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      94             :   plumed_dbg_assert( iatom<atom_lab.size() );
+      95           0 :   plumed_assert( atom_lab[iatom].first==0 );
+      96           0 :   return ActionAtomistic::getAbsoluteIndex( ablocks[0][atom_lab[iatom].second] );
+      97             : }
+      98             : 
+      99       16584 : void MoleculeOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+     100       33168 :   for(unsigned i=0; i<nvectors; ++i) {
+     101       16584 :     Vector distance; distance=getSeparation( myatoms.getPosition(2*i+0), myatoms.getPosition(2*i+1) );
+     102             : 
+     103       16584 :     addAtomDerivatives( 2+3*i+0, 2*i+0, Vector(-1.0,0,0), myatoms );
+     104       16584 :     addAtomDerivatives( 2+3*i+0, 2*i+1, Vector(+1.0,0,0), myatoms );
+     105       16584 :     myatoms.addBoxDerivatives( 2+3*i+0, Tensor(distance,Vector(-1.0,0,0)) );
+     106       16584 :     myatoms.addValue( 2+3*i+0, distance[0] );
+     107             : 
+     108       16584 :     addAtomDerivatives( 2+3*i+1, 2*i+0, Vector(0,-1.0,0), myatoms );
+     109       16584 :     addAtomDerivatives( 2+3*i+1, 2*i+1, Vector(0,+1.0,0), myatoms );
+     110       16584 :     myatoms.addBoxDerivatives( 2+3*i+1, Tensor(distance,Vector(0,-1.0,0)) );
+     111       16584 :     myatoms.addValue( 2+3*i+1, distance[1] );
+     112             : 
+     113       16584 :     addAtomDerivatives( 2+3*i+2, 2*i+0, Vector(0,0,-1.0), myatoms );
+     114       16584 :     addAtomDerivatives( 2+3*i+2, 2*i+1, Vector(0,0,+1.0), myatoms );
+     115       16584 :     myatoms.addBoxDerivatives( 2+3*i+2, Tensor(distance,Vector(0,0,-1.0)) );
+     116       16584 :     myatoms.addValue( 2+3*i+2, distance[2] );
+     117             :   }
+     118       16584 : }
+     119             : 
+     120     1041228 : void MoleculeOrientation::normalizeVector( std::vector<double>& vals ) const {
+     121     2082456 :   for(unsigned i=0; i<nvectors; ++i) {
+     122             :     double norm=0;
+     123     4164912 :     for(unsigned j=0; j<3; ++j) norm += vals[2+3*i+j]*vals[2+3*i+j];
+     124     1041228 :     norm = sqrt(norm);
+     125             : 
+     126     1041228 :     double inorm = 1.0; if( norm>epsilon ) inorm = 1.0 / norm;
+     127     4164912 :     for(unsigned j=0; j<3; ++j) vals[2+3*i+j] = inorm*vals[2+3*i+j];
+     128             :   }
+     129     1041228 : }
+     130             : 
+     131        4992 : void MoleculeOrientation::normalizeVectorDerivatives( MultiValue& myvals ) const {
+     132        4992 :   std::vector<double> weight( nvectors ), wdf( nvectors );
+     133        9984 :   for(unsigned ivec=0; ivec<nvectors; ++ivec) {
+     134       19968 :     double v=0; for(unsigned jcomp=0; jcomp<3; ++jcomp) v += myvals.get( 2+3*ivec+jcomp )*myvals.get( 2+3*ivec+jcomp );
+     135        4992 :     v=sqrt(v); weight[ivec]=1.0; wdf[ivec]=1.0;
+     136        4992 :     if( v>epsilon ) { weight[ivec] = 1.0 / v; wdf[ivec] = 1.0 / ( v*v*v ); }
+     137             :   }
+     138             : 
+     139       54672 :   for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     140       49680 :     unsigned jder=myvals.getActiveIndex(j);
+     141       99360 :     for(unsigned ivec=0; ivec<nvectors; ++ivec) {
+     142      198720 :       double comp2=0.0; for(unsigned jcomp=0; jcomp<3; ++jcomp) comp2 += myvals.get(2+3*ivec+jcomp)*myvals.getDerivative( 2+3*ivec+jcomp, jder );
+     143      198720 :       for(unsigned jcomp=0; jcomp<3; ++jcomp) {
+     144      149040 :         myvals.setDerivative( 2+3*ivec+jcomp, jder, weight[ivec]*myvals.getDerivative( 2+3*ivec+jcomp, jder ) - wdf[ivec]*comp2*myvals.get(2+3*ivec+jcomp) );
+     145             :       }
+     146             :     }
+     147             :   }
+     148        4992 : }
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html b/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html new file mode 100644 index 0000000000..b16ced9d0d --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48D2Ev4168
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.func.html b/coverage/crystallization/MoleculePlane.cpp.func.html new file mode 100644 index 0000000000..cff715fc27 --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe486createERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_125MoleculePlaneRegisterMe48D2Ev4168
_ZN4PLMD15crystallization13MoleculePlane16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization13MoleculePlaneC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlaneC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
_ZNK4PLMD15crystallization13MoleculePlane29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.gcov.html b/coverage/crystallization/MoleculePlane.cpp.gcov.html new file mode 100644 index 0000000000..948b4fbfb1 --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(MoleculePlane,"PLANES")
+      49             : 
+      50           4 : void MoleculePlane::registerKeywords( Keywords& keys ) {
+      51           4 :   VectorMultiColvar::registerKeywords( keys ); keys.use("VMEAN");
+      52           8 :   keys.add("numbered","MOL","The numerical indices of the atoms in the molecule. If three atoms are specified the orientation "
+      53             :            "of the molecule is taken as the normal to the plane containing the vector connecting the first and "
+      54             :            "second atoms and the vector connecting the second and third atoms.  If four atoms are specified the "
+      55             :            "orientation of the molecule is taken as the normal to the plane containing the vector connecting the "
+      56             :            "first and second atoms and the vector connecting the third and fourth atoms. The molecule is always "
+      57             :            "assumed to lie at the geometric center for the three/four atoms.");
+      58           8 :   keys.reset_style("MOL","atoms");
+      59           4 : }
+      60             : 
+      61           2 : MoleculePlane::MoleculePlane( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63           2 :   VectorMultiColvar(ao)
+      64             : {
+      65             :   std::vector<AtomNumber> all_atoms;
+      66           4 :   readAtomsLikeKeyword("MOL",-1,all_atoms);
+      67           2 :   if( ablocks.size()!=3 && ablocks.size()!=4 ) error("number of atoms in molecule specification is wrong.  Should be three or four.");
+      68             : 
+      69           2 :   if( all_atoms.size()==0 ) error("No atoms were specified");
+      70           2 :   setVectorDimensionality( 3 ); setupMultiColvarBase( all_atoms );
+      71           2 : }
+      72             : 
+      73           0 : AtomNumber MoleculePlane::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      74             :   plumed_dbg_assert( iatom<atom_lab.size() );
+      75           0 :   plumed_assert( atom_lab[iatom].first==0 );
+      76           0 :   return ActionAtomistic::getAbsoluteIndex( ablocks[0][atom_lab[iatom].second] );
+      77             : }
+      78             : 
+      79        8888 : void MoleculePlane::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+      80        8888 :   Vector d1, d2, cp;
+      81        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+      82        8888 :     d1=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+      83        8888 :     d2=getSeparation( myatoms.getPosition(1), myatoms.getPosition(2) );
+      84             :   } else {
+      85           0 :     d1=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+      86           0 :     d2=getSeparation( myatoms.getPosition(2), myatoms.getPosition(3) );
+      87             :   }
+      88        8888 :   cp = crossProduct( d1, d2 );
+      89             : 
+      90        8888 :   addAtomDerivatives( 2, 0, crossProduct( Vector(-1.0,0,0), d2 ), myatoms );
+      91        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+      92        8888 :     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ) + crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+      93        8888 :     addAtomDerivatives( 2, 2, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
+      94             :   } else {
+      95           0 :     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ), myatoms );
+      96           0 :     addAtomDerivatives( 2, 2, crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+      97           0 :     addAtomDerivatives( 2, 3, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
+      98             :   }
+      99        8888 :   myatoms.addBoxDerivatives( 2, Tensor(d1,crossProduct(Vector(+1.0,0,0), d2)) + Tensor( d2, crossProduct(Vector(-1.0,0,0), d1)) );
+     100        8888 :   myatoms.addValue( 2, cp[0] );
+     101             : 
+     102        8888 :   addAtomDerivatives( 3, 0, crossProduct( Vector(0,-1.0,0), d2 ), myatoms );
+     103        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+     104        8888 :     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ) + crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     105        8888 :     addAtomDerivatives( 3, 2, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
+     106             :   } else {
+     107           0 :     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ), myatoms );
+     108           0 :     addAtomDerivatives( 3, 2, crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     109           0 :     addAtomDerivatives( 3, 3, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
+     110             :   }
+     111        8888 :   myatoms.addBoxDerivatives( 3, Tensor(d1,crossProduct(Vector(0,+1.0,0), d2)) + Tensor( d2, crossProduct(Vector(0,-1.0,0), d1)) );
+     112        8888 :   myatoms.addValue( 3, cp[1] );
+     113             : 
+     114        8888 :   addAtomDerivatives( 4, 0, crossProduct( Vector(0,0,-1.0), d2 ), myatoms );
+     115        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+     116        8888 :     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,+1.0), d2 ) + crossProduct( Vector(0,0,-1.0), d1 ), myatoms );
+     117        8888 :     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
+     118             :   } else {
+     119           0 :     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,-1.0), d2 ), myatoms);
+     120           0 :     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,-1.0), d1 ), myatoms);
+     121           0 :     addAtomDerivatives( 4, 3, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
+     122             :   }
+     123        8888 :   myatoms.addBoxDerivatives( 4, Tensor(d1,crossProduct(Vector(0,0,+1.0), d2)) + Tensor( d2, crossProduct(Vector(0,0,-1.0), d1)) );
+     124        8888 :   myatoms.addValue( 4, cp[2] );
+     125        8888 : }
+     126             : 
+     127             : // Vector MoleculePlane::getCentralAtom(){
+     128             : //   Vector com; com.zero();
+     129             : //   if( getNAtoms()==3 ){
+     130             : //       com+=(1.0/3.0)*getPosition(0);
+     131             : //       com+=(1.0/3.0)*getPosition(1);
+     132             : //       com+=(1.0/3.0)*getPosition(2);
+     133             : //       addCentralAtomDerivatives( 0, (1.0/3.0)*Tensor::identity() );
+     134             : //       addCentralAtomDerivatives( 1, (1.0/3.0)*Tensor::identity() );
+     135             : //       addCentralAtomDerivatives( 2, (1.0/3.0)*Tensor::identity() );
+     136             : //       return com;
+     137             : //   }
+     138             : //   com+=0.25*getPosition(0);
+     139             : //   com+=0.25*getPosition(1);
+     140             : //   com+=0.25*getPosition(2);
+     141             : //   com+=0.25*getPosition(3);
+     142             : //   addCentralAtomDerivatives( 0, 0.25*Tensor::identity() );
+     143             : //   addCentralAtomDerivatives( 1, 0.25*Tensor::identity() );
+     144             : //   addCentralAtomDerivatives( 2, 0.25*Tensor::identity() );
+     145             : //   addCentralAtomDerivatives( 3, 0.25*Tensor::identity() );
+     146             : //   return com;
+     147             : // }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html b/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html new file mode 100644 index 0000000000..c15d105ecb --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE21
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.func.html b/coverage/crystallization/OrientationSphere.cpp.func.html new file mode 100644 index 0000000000..2efc21d07a --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.gcov.html b/coverage/crystallization/OrientationSphere.cpp.gcov.html new file mode 100644 index 0000000000..e3a78683ff --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.gcov.html @@ -0,0 +1,207 @@ + + + + + + + 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-05-27 13:05: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          21 : void OrientationSphere::registerKeywords( Keywords& keys ) {
+      32          21 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      33          42 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      34          42 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      35          42 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      36          42 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      37          42 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      38             :            "The following provides information on the \\ref switchingfunction that are available. "
+      39             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      40             :   // Use actionWithDistributionKeywords
+      41          63 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      42          63 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      43          84 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      44          42 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      45          21 : }
+      46             : 
+      47          11 : OrientationSphere::OrientationSphere(const ActionOptions&ao):
+      48             :   Action(ao),
+      49          11 :   MultiColvarBase(ao)
+      50             : {
+      51          11 :   if( getNumberOfBaseMultiColvars()>1 ) warning("not sure if orientation sphere works with more than one base multicolvar - check numerical derivatives");
+      52             :   // Read in the switching function
+      53          22 :   std::string sw, errors; parse("SWITCH",sw);
+      54          11 :   if(sw.length()>0) {
+      55          11 :     switchingFunction.set(sw,errors);
+      56             :   } else {
+      57           0 :     double r_0=-1.0, d_0; int nn, mm;
+      58           0 :     parse("NN",nn); parse("MM",mm);
+      59           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      60           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      61           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      62             :   }
+      63          11 :   log.printf("  degree of overlap in orientation between central molecule and those within %s\n",( switchingFunction.description() ).c_str() );
+      64          22 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      65             :   // Set the link cell cutoff
+      66          11 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+      67          11 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      68          11 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      69          11 : }
+      70             : 
+      71        7782 : double OrientationSphere::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      72        7782 :   double sw, value=0, denom=0, dfunc; Vector ddistance;
+      73        7782 :   unsigned ncomponents=getBaseMultiColvar(0)->getNumberOfQuantities();
+      74        7782 :   std::vector<double> catom_orient( ncomponents ), this_orient( ncomponents );
+      75        7782 :   std::vector<double> this_der( ncomponents ), catom_der( ncomponents );
+      76             : 
+      77        7782 :   getInputData( 0, true, myatoms, catom_orient );
+      78        7782 :   MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+      79             : 
+      80     1379893 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+      81             :     Vector& distance=myatoms.getPosition(i);
+      82             :     double d2;
+      83     2611747 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+      84     1239636 :          (d2+=distance[1]*distance[1])<rcut2 &&
+      85     2501268 :          (d2+=distance[2]*distance[2])<rcut2 &&
+      86             :          d2>epsilon ) {
+      87             : 
+      88     1069658 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+      89             : 
+      90     1069658 :       getInputData( i, true, myatoms, this_orient );
+      91             :       // Calculate the dot product wrt to this position
+      92     1069658 :       double f_dot = computeVectorFunction( distance, catom_orient, this_orient, ddistance, catom_der, this_der );
+      93             : 
+      94     1069658 :       if( !doNotCalculateDerivatives() ) {
+      95      233625 :         for(unsigned k=2; k<catom_orient.size(); ++k) { this_der[k]*=sw; catom_der[k]*=sw; }
+      96       10227 :         MultiValue& myder1=getInputDerivatives( i, true, myatoms );
+      97       10227 :         mergeInputDerivatives( 1, 2, this_orient.size(), 0, catom_der, myder0, myatoms );
+      98       10227 :         mergeInputDerivatives( 1, 2, catom_der.size(), i, this_der, myder1, myatoms );
+      99       10227 :         addAtomDerivatives( 1, 0, f_dot*(-dfunc)*distance - sw*ddistance, myatoms );
+     100       10227 :         addAtomDerivatives( 1, i, f_dot*(dfunc)*distance + sw*ddistance, myatoms );
+     101       10227 :         myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) - sw*extProduct(distance,ddistance) );
+     102       10227 :         myder1.clearAll();
+     103             : 
+     104       10227 :         addAtomDerivatives( -1, 0, (-dfunc)*distance, myatoms );
+     105       10227 :         addAtomDerivatives( -1, i, (dfunc)*distance, myatoms );
+     106       10227 :         myatoms.addTemporyBoxDerivatives( (-dfunc)*Tensor(distance,distance) );
+     107             : 
+     108             :       }
+     109     1069658 :       value += sw*f_dot;
+     110     1069658 :       denom += sw;
+     111             :     }
+     112             :   }
+     113        7782 :   double rdenom, df2, pref=calculateCoordinationPrefactor( denom, df2 );
+     114        7782 :   if( std::fabs(denom)>epsilon ) { rdenom = 1.0 / denom; }
+     115           0 :   else { plumed_assert(std::fabs(value)<epsilon); rdenom=1.0; }
+     116             : 
+     117             :   // Now divide everything
+     118        7782 :   double rdenom2=rdenom*rdenom;
+     119        7782 :   updateActiveAtoms( myatoms ); MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     120       57486 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+     121       49704 :     unsigned ider=myvals.getActiveIndex(i);
+     122             :     double  dgd=myvals.getTemporyDerivative(ider);
+     123       49704 :     myvals.setDerivative( 1, ider, rdenom*(pref*myvals.getDerivative(1,ider)+value*df2*dgd) - (value*pref*dgd)*rdenom2 );
+     124             :   }
+     125             : 
+     126       15564 :   return pref*rdenom*value;
+     127             : }
+     128             : 
+     129             : }
+     130             : }
+     131             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.func-sort-c.html b/coverage/crystallization/OrientationSphere.h.func-sort-c.html new file mode 100644 index 0000000000..58691c54d2 --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.func.html b/coverage/crystallization/OrientationSphere.h.func.html new file mode 100644 index 0000000000..b504f251a4 --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.gcov.html b/coverage/crystallization/OrientationSphere.h.gcov.html new file mode 100644 index 0000000000..f943cec262 --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html b/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html new file mode 100644 index 0000000000..fdc576185f --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.func.html b/coverage/crystallization/PolymerAngles.cpp.func.html new file mode 100644 index 0000000000..7349bbb8cb --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe766createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_125PolymerAnglesRegisterMe76D2Ev4168
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.gcov.html b/coverage/crystallization/PolymerAngles.cpp.gcov.html new file mode 100644 index 0000000000..21b8d6e5e6 --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(PolymerAngles,"POLYMER_ANGLES")
+      77             : 
+      78           3 : void PolymerAngles::registerKeywords( Keywords& keys ) {
+      79           3 :   OrientationSphere::registerKeywords(keys);
+      80           3 : }
+      81             : 
+      82           1 : PolymerAngles::PolymerAngles(const ActionOptions& ao):
+      83             :   Action(ao),
+      84           1 :   OrientationSphere(ao)
+      85             : {
+      86           1 :   if( mybasemulticolvars.size()==0 ) error("SMAC must take multicolvar as input");
+      87           2 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+      88           1 :     if( (mybasemulticolvars[i]->getNumberOfQuantities()-2)%3!=0 ) error("POLYMER_ANGLES is only possible with three dimensional vectors");
+      89             :   }
+      90           1 : }
+      91             : 
+      92         616 : double PolymerAngles::computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      93             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+      94             : 
+      95         616 :   plumed_assert( (vec1.size()-2)==3 );
+      96        2464 :   double dot = 0; for(unsigned k=0; k<3; ++k) dot += vec1[2+k]*vec2[2+k];
+      97        2464 :   double ans = 1.5*dot*dot - 0.5; for(unsigned k=0; k<3; ++k) { dvec1[2+k]=3*dot*vec2[2+k]; dvec2[2+k]=3*dot*vec1[2+k]; }
+      98         616 :   return ans;
+      99             : }
+     100             : 
+     101             : }
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.func-sort-c.html b/coverage/crystallization/Q3.cpp.func-sort-c.html new file mode 100644 index 0000000000..b246162f04 --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe1876createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe1896createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe187C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe187D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe189C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe189D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.func.html b/coverage/crystallization/Q3.cpp.func.html new file mode 100644 index 0000000000..39bad1442e --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe1876createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe187C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q3RegisterMe187D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe1896createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe189C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q3RegisterMe189D2Ev4168
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.gcov.html b/coverage/crystallization/Q3.cpp.gcov.html new file mode 100644 index 0000000000..062ad093f7 --- /dev/null +++ b/coverage/crystallization/Q3.cpp.gcov.html @@ -0,0 +1,299 @@ + + + + + + + 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-05-27 13:05: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 q_3 vector on the central atom and the q_3 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       12504 : PLUMED_REGISTER_ACTION(Q3,"Q3")
+     188             : typedef LocalSteinhardt<Q3> LOCAL_Q3;
+     189       12504 : PLUMED_REGISTER_ACTION(LOCAL_Q3,"LOCAL_Q3")
+     190             : 
+     191           2 : void Q3::registerKeywords( Keywords& keys ) {
+     192           2 :   Steinhardt::registerKeywords( keys );
+     193           2 : }
+     194             : 
+     195           0 : Q3::Q3(const ActionOptions& ao ):
+     196             :   Action(ao),
+     197           0 :   Steinhardt(ao)
+     198             : {
+     199           0 :   setAngularMomentum(3);
+     200             : 
+     201             : // Spherical harmonics normalization:
+     202             : // even =  sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     203             : // odd  = -sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     204             : 
+     205           0 :   normaliz.resize( 4 );
+     206           0 :   normaliz[0] = sqrt( ( 7.0*6.0 ) / (4.0*pi*6.0) );
+     207           0 :   normaliz[1] = -sqrt( ( 7.0*2.0 ) / (4.0*pi*24.0) );
+     208           0 :   normaliz[2] = sqrt( ( 7.0*1.0) / (4.0*pi*120.0) );
+     209           0 :   normaliz[3] = -sqrt( ( 7.0*1.0) / (4.0*pi*720.0) );
+     210             : 
+     211             : // Legendre polynomial coefficients of order three
+     212             : 
+     213           0 :   coeff_poly.resize( 4 );
+     214           0 :   coeff_poly[0]=0.0;
+     215           0 :   coeff_poly[1]=-1.5;
+     216           0 :   coeff_poly[2]=0.0;
+     217           0 :   coeff_poly[3]=2.5;
+     218             : 
+     219           0 : }
+     220             : 
+     221             : }
+     222             : }
+     223             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.func-sort-c.html b/coverage/crystallization/Q4.cpp.func-sort-c.html new file mode 100644 index 0000000000..4c7f16bb52 --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe1886createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe1866createERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe186C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe186D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe188C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe188D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.func.html b/coverage/crystallization/Q4.cpp.func.html new file mode 100644 index 0000000000..e0efe54c80 --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe1866createERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe186C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q4RegisterMe186D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe1886createERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe188C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q4RegisterMe188D2Ev4168
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.gcov.html b/coverage/crystallization/Q4.cpp.gcov.html new file mode 100644 index 0000000000..7b864f8bed --- /dev/null +++ b/coverage/crystallization/Q4.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + 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-05-27 13:05: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 q_4 vector on the central atom and the q_4 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       12510 : PLUMED_REGISTER_ACTION(Q4,"Q4")
+     187             : typedef LocalSteinhardt<Q4> LOCAL_Q4;
+     188       12504 : PLUMED_REGISTER_ACTION(LOCAL_Q4,"LOCAL_Q4")
+     189             : 
+     190           5 : void Q4::registerKeywords( Keywords& keys ) {
+     191           5 :   Steinhardt::registerKeywords( keys );
+     192           5 : }
+     193             : 
+     194           3 : Q4::Q4(const ActionOptions& ao ):
+     195             :   Action(ao),
+     196           3 :   Steinhardt(ao)
+     197             : {
+     198           3 :   setAngularMomentum(4);
+     199             : 
+     200           3 :   normaliz.resize( 5 );
+     201           3 :   normaliz[0] = sqrt( ( 9.0*24.0 ) / (4.0*pi*24.0) );
+     202           3 :   normaliz[1] = -sqrt( ( 9.0*6.0 ) / (4.0*pi*120.0) );
+     203           3 :   normaliz[2] = sqrt( ( 9.0*2.0) / (4.0*pi*720.0) );
+     204           3 :   normaliz[3] = -sqrt( ( 9.0*1) / (4.0*pi*5040.0) );
+     205           3 :   normaliz[4] = sqrt( (9.0*1) / (4.0*pi*40320.0) );
+     206             : 
+     207           3 :   coeff_poly.resize( 5 );
+     208           3 :   coeff_poly[0]=0.375; coeff_poly[1]=0.0;
+     209           3 :   coeff_poly[2]=-3.75; coeff_poly[3]=0.0;
+     210           3 :   coeff_poly[4]=4.375;
+     211           3 : }
+     212             : 
+     213             : }
+     214             : }
+     215             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.func-sort-c.html b/coverage/crystallization/Q6.cpp.func-sort-c.html new file mode 100644 index 0000000000..372fa1469f --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe1886createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe1866createERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE17
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe186C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe186D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe188C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe188D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.func.html b/coverage/crystallization/Q6.cpp.func.html new file mode 100644 index 0000000000..192111ba16 --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe1866createERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe186C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_115Q6RegisterMe186D2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe1886createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe188C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_121LOCAL_Q6RegisterMe188D2Ev4168
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE17
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.gcov.html b/coverage/crystallization/Q6.cpp.gcov.html new file mode 100644 index 0000000000..f6b332c1f2 --- /dev/null +++ b/coverage/crystallization/Q6.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + 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-05-27 13:05: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 q_6 vector on the central atom and the q_6 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       12534 : PLUMED_REGISTER_ACTION(Q6,"Q6")
+     187             : typedef LocalSteinhardt<Q6> LOCAL_Q6;
+     188       12514 : PLUMED_REGISTER_ACTION(LOCAL_Q6,"LOCAL_Q6")
+     189             : 
+     190          17 : void Q6::registerKeywords( Keywords& keys ) {
+     191          17 :   Steinhardt::registerKeywords( keys );
+     192          17 : }
+     193             : 
+     194          15 : Q6::Q6(const ActionOptions& ao ):
+     195             :   Action(ao),
+     196          15 :   Steinhardt(ao)
+     197             : {
+     198          15 :   setAngularMomentum(6);
+     199             : 
+     200          15 :   normaliz.resize( 7 );
+     201          15 :   normaliz[0] = sqrt( ( 13.0*720.0 ) / (4.0*pi*720.0) );
+     202          15 :   normaliz[1] = -sqrt( ( 13.0*120.0 ) / (4.0*pi*5040) );
+     203          15 :   normaliz[2] = sqrt( ( 13.0*24) / (4.0*pi*40320) );
+     204          15 :   normaliz[3] = -sqrt( ( 13.0*6) / (4.0*pi*362880) );
+     205          15 :   normaliz[4] = sqrt( (13.0*2) / (4.0*pi*3628800) );
+     206          15 :   normaliz[5] = -sqrt( (13.0*1) / (4.0*pi*39916800) );
+     207          15 :   normaliz[6] = sqrt( (13.0*1) / (4.0*pi*479001600) );
+     208             : 
+     209          15 :   coeff_poly.resize( 7 );
+     210          15 :   coeff_poly[0]=-0.3125; coeff_poly[1]=0.0;
+     211          15 :   coeff_poly[2]=6.5625; coeff_poly[3]=0.0;
+     212          15 :   coeff_poly[4]=-19.6875; coeff_poly[5]=0.0;
+     213          15 :   coeff_poly[6]=14.4375;
+     214          15 : }
+     215             : 
+     216             : }
+     217             : }
+     218             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.func-sort-c.html b/coverage/crystallization/SMAC.cpp.func-sort-c.html new file mode 100644 index 0000000000..b43c4287a6 --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization4SMACC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe1396createERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMAC16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe139C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_117SMACRegisterMe139D2Ev4168
_ZNK4PLMD15crystallization4SMAC30calculateCoordinationPrefactorERKdRd4464
_ZNK4PLMD15crystallization4SMAC21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_1025856
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.func.html b/coverage/crystallization/SMAC.cpp.func.html new file mode 100644 index 0000000000..7e08d7416d --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe786createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.func.html b/coverage/crystallization/SimpleCubic.cpp.func.html new file mode 100644 index 0000000000..5b3973e53e --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe786createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_123SimpleCubicRegisterMe78D2Ev4168
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.gcov.html b/coverage/crystallization/SimpleCubic.cpp.gcov.html new file mode 100644 index 0000000000..c5e2a47b6e --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.gcov.html @@ -0,0 +1,192 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(SimpleCubic,"SIMPLECUBIC")
+      79             : 
+      80           3 : void SimpleCubic::registerKeywords( Keywords& keys ) {
+      81           3 :   CubicHarmonicBase::registerKeywords( keys );
+      82           3 : }
+      83             : 
+      84           1 : SimpleCubic::SimpleCubic(const ActionOptions&ao):
+      85             :   Action(ao),
+      86           1 :   CubicHarmonicBase(ao)
+      87             : {
+      88           1 :   checkRead();
+      89           1 : }
+      90             : 
+      91        4032 : double SimpleCubic::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+      92        4032 :   double x2 = distance[0]*distance[0];
+      93        4032 :   double x3 = distance[0]*x2;
+      94        4032 :   double x4 = distance[0]*x3;
+      95             : 
+      96        4032 :   double y2 = distance[1]*distance[1];
+      97        4032 :   double y3 = distance[1]*y2;
+      98        4032 :   double y4 = distance[1]*y3;
+      99             : 
+     100        4032 :   double z2 = distance[2]*distance[2];
+     101        4032 :   double z3 = distance[2]*z2;
+     102        4032 :   double z4 = distance[2]*z3;
+     103             : 
+     104        4032 :   double r4 = pow( d2, 2 );
+     105        4032 :   double tmp = ( x4 + y4 + z4 ) / r4;
+     106             : 
+     107        4032 :   double t1=(x2+y2+z2), t2=t1*t1, t3=(x4+y4+z4)/(t1*t2);
+     108        4032 :   myder[0] = 4*x3/t2-4*distance[0]*t3;
+     109        4032 :   myder[1] = 4*y3/t2-4*distance[1]*t3;
+     110        4032 :   myder[2] = 4*z3/t2-4*distance[2]*t3;
+     111        4032 :   return tmp;
+     112             : }
+     113             : 
+     114             : }
+     115             : }
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.func-sort-c.html b/coverage/crystallization/Steinhardt.cpp.func-sort-c.html new file mode 100644 index 0000000000..b3de8dab88 --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE24
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE74931
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15435674
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.func.html b/coverage/crystallization/Steinhardt.cpp.func.html new file mode 100644 index 0000000000..d14906d569 --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15435674
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE74931
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.gcov.html b/coverage/crystallization/Steinhardt.cpp.gcov.html new file mode 100644 index 0000000000..030920079b --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + 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-05-27 13:05: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          24 : void Steinhardt::registerKeywords( Keywords& keys ) {
+      30          24 :   VectorMultiColvar::registerKeywords( keys );
+      31          48 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      32          48 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      33          48 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      34          48 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      35          48 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      36             :            "The following provides information on the \\ref switchingfunction that are available. "
+      37             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      38          72 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      39          96 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN"); keys.use("VMEAN");
+      40         120 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("ALT_MIN");
+      41          48 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      42          24 : }
+      43             : 
+      44          18 : Steinhardt::Steinhardt( const ActionOptions& ao ):
+      45             :   Action(ao),
+      46             :   VectorMultiColvar(ao),
+      47          18 :   tmom(0)
+      48             : {
+      49             :   // Read in the switching function
+      50          36 :   std::string sw, errors; parse("SWITCH",sw);
+      51          18 :   if(sw.length()>0) {
+      52           6 :     switchingFunction.set(sw,errors);
+      53             :   } else {
+      54          12 :     double r_0=-1.0, d_0; int nn, mm;
+      55          24 :     parse("NN",nn); parse("MM",mm);
+      56          24 :     parse("R_0",r_0); parse("D_0",d_0);
+      57          12 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      58          12 :     switchingFunction.set(nn,mm,r_0,d_0);
+      59             :   }
+      60          18 :   log.printf("  Steinhardt parameter of central atom and those within %s\n",( switchingFunction.description() ).c_str() );
+      61          36 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      62             :   // Set the link cell cutoff
+      63          18 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      64          18 :   rcut = switchingFunction.get_dmax(); rcut2 = rcut*rcut;
+      65          18 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      66          18 : }
+      67             : 
+      68          18 : void Steinhardt::setAngularMomentum( const unsigned& ang ) {
+      69          18 :   tmom=ang; setVectorDimensionality( 2*(2*ang + 1) );
+      70          18 : }
+      71             : 
+      72       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.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html b/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html new file mode 100644 index 0000000000..54d7860b69 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.func.html b/coverage/crystallization/Tetrahedral.cpp.func.html new file mode 100644 index 0000000000..2353b1c28c --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe836createERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83C2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_123TetrahedralRegisterMe83D2Ev4168
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.gcov.html b/coverage/crystallization/Tetrahedral.cpp.gcov.html new file mode 100644 index 0000000000..f70c5649d6 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(Tetrahedral,"TETRAHEDRAL")
+      84             : 
+      85           3 : void Tetrahedral::registerKeywords( Keywords& keys ) {
+      86           3 :   CubicHarmonicBase::registerKeywords( keys );
+      87           3 : }
+      88             : 
+      89           1 : Tetrahedral::Tetrahedral(const ActionOptions&ao):
+      90             :   Action(ao),
+      91           1 :   CubicHarmonicBase(ao)
+      92             : {
+      93           1 :   checkRead();
+      94           1 : }
+      95             : 
+      96        4032 : double Tetrahedral::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+      97        4032 :   double sp1 = +distance[0]+distance[1]+distance[2];
+      98        4032 :   double sp2 = +distance[0]-distance[1]-distance[2];
+      99        4032 :   double sp3 = -distance[0]+distance[1]-distance[2];
+     100        4032 :   double sp4 = -distance[0]-distance[1]+distance[2];
+     101             : 
+     102             :   double sp1c = pow( sp1, 3 );
+     103             :   double sp2c = pow( sp2, 3 );
+     104             :   double sp3c = pow( sp3, 3 );
+     105             :   double sp4c = pow( sp4, 3 );
+     106             : 
+     107        4032 :   double d1 = distance.modulo();
+     108             :   double r3 = pow( d1, 3 );
+     109             :   double r5 = pow( d1, 5 );
+     110             : 
+     111        4032 :   double tmp = sp1c/r3 + sp2c/r3 + sp3c/r3 + sp4c/r3;
+     112             : 
+     113        4032 :   double t1=(3*sp1c)/r5; double tt1=((3*sp1*sp1)/r3);
+     114        4032 :   double t2=(3*sp2c)/r5; double tt2=((3*sp2*sp2)/r3);
+     115        4032 :   double t3=(3*sp3c)/r5; double tt3=((3*sp3*sp3)/r3);
+     116        4032 :   double t4=(3*sp4c)/r5; double tt4=((3*sp4*sp4)/r3);
+     117             : 
+     118        4032 :   myder[0] = (tt1-(distance[0]*t1))  + (tt2-(distance[0]*t2))  + (-tt3-(distance[0]*t3))  + (-tt4-(distance[0]*t4));
+     119        4032 :   myder[1] = (tt1-(distance[1]*t1))  + (-tt2-(distance[1]*t2))  + (tt3-(distance[1]*t3))  + (-tt4-(distance[1]*t4));
+     120        4032 :   myder[2] = (tt1-(distance[2]*t1))  + (-tt2-(distance[2]*t2))  + (-tt3-(distance[2]*t3))  + (tt4-(distance[2]*t4));
+     121             : 
+     122        4032 :   return tmp;
+     123             : }
+     124             : 
+     125             : }
+     126             : }
+     127             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.func-sort-c.html b/coverage/crystallization/VectorMean.cpp.func-sort-c.html new file mode 100644 index 0000000000..d699c11e21 --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4168
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev4168
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.func.html b/coverage/crystallization/VectorMean.cpp.func.html new file mode 100644 index 0000000000..86f2e5da42 --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10VectorMean14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD15crystallization10VectorMean16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization10VectorMean16value_descriptorB5cxx11Ev6
_ZN4PLMD15crystallization10VectorMean6finishERKSt6vectorIdSaIdEE1828
_ZN4PLMD15crystallization10VectorMean6resizeEv23
_ZN4PLMD15crystallization10VectorMeanC2ERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMe6createERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev4168
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.gcov.html b/coverage/crystallization/VectorMean.cpp.gcov.html new file mode 100644 index 0000000000..2c2b0ade84 --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_VESSEL(VectorMean,"VMEAN")
+      45             : 
+      46           6 : void VectorMean::registerKeywords( Keywords& keys ) {
+      47           6 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           6 : }
+      49             : 
+      50        4168 : void VectorMean::reserveKeyword( Keywords& keys ) {
+      51        8336 :   keys.reserve("vessel","VMEAN","calculate the norm of the mean vector.");
+      52        8336 :   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        4168 : }
+      55             : 
+      56           6 : VectorMean::VectorMean( const vesselbase::VesselOptions& da ) :
+      57             :   FunctionVessel(da),
+      58           6 :   nder(0)
+      59             : {
+      60           6 : }
+      61             : 
+      62           6 : std::string VectorMean::value_descriptor() {
+      63           6 :   return "the norm of the mean vector";
+      64             : }
+      65             : 
+      66          23 : void VectorMean::resize() {
+      67          23 :   unsigned ncomp=getAction()->getNumberOfQuantities() - 2;
+      68             : 
+      69          23 :   if( getAction()->derivativesAreRequired() ) {
+      70          16 :     nder=getAction()->getNumberOfDerivatives();
+      71          16 :     resizeBuffer( (1+nder)*(ncomp+1) ); getFinalValue()->resizeDerivatives( nder );
+      72             :   } else {
+      73           7 :     nder=0; resizeBuffer(ncomp+1);
+      74             :   }
+      75          23 : }
+      76             : 
+      77       14712 : void VectorMean::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      78       14712 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      79             : 
+      80       14712 :   double weight=myvals.get(0); plumed_dbg_assert( weight>=getTolerance() );
+      81       14712 :   buffer[bufstart] += weight;
+      82       61240 :   for(unsigned i=0; i<ncomp; ++i) buffer[bufstart + (1+i)*(1+nder)] += weight*myvals.get(2+i);
+      83       14712 :   if( !getAction()->derivativesAreRequired() ) return;
+      84             : 
+      85       14712 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, 1.0, bufstart, buffer );
+      86       61240 :   for(unsigned i=0; i<ncomp; ++i) {
+      87       46528 :     double colvar=myvals.get(2+i);
+      88       46528 :     myvals.chainRule( 2+i, 1+i, 1, 0, weight, bufstart, buffer );
+      89       46528 :     if( diffweight ) myvals.chainRule( 0, 1+i, 1, 0, colvar, bufstart, buffer );
+      90             :   }
+      91             :   return;
+      92             : }
+      93             : 
+      94        1828 : void VectorMean::finish( const std::vector<double>& buffer ) {
+      95        1828 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      96        1828 :   double sum=0, ww=buffer[bufstart];
+      97        7358 :   for(unsigned i=0; i<ncomp; ++i) {
+      98        5530 :     double tmp = buffer[bufstart+(nder+1)*(i+1)] / ww;
+      99        5530 :     sum+=tmp*tmp;
+     100             :   }
+     101        1828 :   setOutputValue( sqrt(sum) );
+     102        1828 :   if( !getAction()->derivativesAreRequired() ) return;
+     103             : 
+     104        1828 :   Value* fval=getFinalValue(); double tw = 1.0 / sqrt(sum);
+     105        7358 :   for(unsigned icomp=0; icomp<ncomp; ++icomp) {
+     106        5530 :     double tmp = buffer[bufstart + (icomp+1)*(1+nder)] / ww;
+     107        5530 :     unsigned bstart = bufstart + (1+icomp)*(nder+1) + 1;
+     108      460636 :     for(unsigned jder=0; jder<nder; ++jder) fval->addDerivative( jder, (tw*tmp/ww)*( buffer[bstart + jder] - tmp*buffer[bufstart + 1 + jder] ) );
+     109             :   }
+     110             : }
+     111             : 
+     112             : }
+     113             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html b/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html new file mode 100644 index 0000000000..85a24cf49c --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE38
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE100463
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.func.html b/coverage/crystallization/VectorMultiColvar.cpp.func.html new file mode 100644 index 0000000000..7c6a64e880 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE100463
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.gcov.html b/coverage/crystallization/VectorMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..ebc7ec3e53 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.gcov.html @@ -0,0 +1,192 @@ + + + + + + + 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-05-27 13:05: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          38 : void VectorMultiColvar::registerKeywords( Keywords& keys ) {
+      29          38 :   MultiColvarBase::registerKeywords( keys );
+      30          38 :   keys.setComponentsIntroduction("When the label of this action is used as the input for a second you are not referring to a scalar quantity as you are in "
+      31             :                                  "regular collective variables.  The label is used to reference the full set of vectors calculated by "
+      32             :                                  "the action.  This is usual when using \\ref multicolvarfunction. Generally when doing this the previously calculated "
+      33             :                                  "multicolvar will be referenced using the DATA keyword rather than ARG.\n\n"
+      34             :                                  "This Action can be used to calculate the following scalar quantities directly.  These quantities are calculated by "
+      35             :                                  "employing the keywords listed below. "
+      36             :                                  "These quantities can then be referenced elsewhere in the input file by using this Action's label "
+      37             :                                  "followed by a dot and the name of the quantity. All of them can be calculated multiple times "
+      38             :                                  "with different parameters.  In this case the quantities calculated can be referenced elsewhere in the "
+      39             :                                  "input by using the name of the quantity followed by a numerical identifier "
+      40             :                                  "e.g. <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 etc.  When doing this and, for clarity we have "
+      41             :                                  "made it so that the user can set the label for the components. As such by using the LABEL keyword in the description of the keyword "
+      42             :                                  "input you can customize the component name.  In addition, you can calculate all of these scalar functions for "
+      43             :                                  "one particular component of the calculated vector by making use of the COMPONENT keyword.  The first component is used to "
+      44             :                                  "refer to the norm of the vector.  The individual components can then be referenced using the numbers 2, 3, and so on.  So "
+      45             :                                  "as an example MEAN1={COMPONENT=1} calculates the average vector norm.  MEAN2={COMPONENT=2} by contrast calculates the mean "
+      46             :                                  "for all of the first components of the vectors.");
+      47          38 : }
+      48             : 
+      49          26 : VectorMultiColvar::VectorMultiColvar(const ActionOptions& ao):
+      50             :   Action(ao),
+      51             :   MultiColvarBase(ao),
+      52          26 :   store_director(true)
+      53             : {
+      54             :   setLowMemOption(true);
+      55          26 : }
+      56             : 
+      57          26 : void VectorMultiColvar::setVectorDimensionality( const unsigned& ncomp ) {
+      58          26 :   ncomponents = ncomp; resizeFunctions(); // This resize needs to be here to ensure buffers are set to correct size in base
+      59          26 : }
+      60             : 
+      61           0 : void VectorMultiColvar::doNotCalculateDirector() {
+      62           0 :   store_director=false;    // Need a sanity check in here so that you don't use the same instance of Q4 to calculate vectors and directors
+      63           0 : }
+      64             : 
+      65      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.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html b/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html new file mode 100644 index 0000000000..9dd65ad417 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1252604
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.func.html b/coverage/crystallization/VectorMultiColvar.h.func.html new file mode 100644 index 0000000000..b061fd6be1 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1252604
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.gcov.html b/coverage/crystallization/VectorMultiColvar.h.gcov.html new file mode 100644 index 0000000000..e466bcbcb7 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.gcov.html @@ -0,0 +1,161 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.func-sort-c.html b/coverage/crystallization/VectorSum.cpp.func-sort-c.html new file mode 100644 index 0000000000..96244f729e --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_119VectorSumRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev4168
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.func.html b/coverage/crystallization/VectorSum.cpp.func.html new file mode 100644 index 0000000000..cf63c10b7b --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMe6createERKNS_10vesselbase13VesselOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeC2Ev4168
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev4168
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD15crystallization9VectorSum16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD15crystallization9VectorSum16value_descriptorB5cxx11Ev0
_ZN4PLMD15crystallization9VectorSum6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization9VectorSum6resizeEv0
_ZN4PLMD15crystallization9VectorSumC2ERKNS_10vesselbase13VesselOptionsE0
_ZNK4PLMD15crystallization9VectorSum9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.gcov.html b/coverage/crystallization/VectorSum.cpp.gcov.html new file mode 100644 index 0000000000..314b6f56dd --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_VESSEL(VectorSum,"VSUM")
+      45             : 
+      46           0 : void VectorSum::registerKeywords( Keywords& keys ) {
+      47           0 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           0 : }
+      49             : 
+      50        4168 : void VectorSum::reserveKeyword( Keywords& keys ) {
+      51        8336 :   keys.reserve("vessel","VSUM","calculate the norm of the sum of vectors.");
+      52        8336 :   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        4168 : }
+      55             : 
+      56           0 : VectorSum::VectorSum( const vesselbase::VesselOptions& da ) :
+      57             :   FunctionVessel(da),
+      58           0 :   nder(0)
+      59             : {
+      60           0 : }
+      61             : 
+      62           0 : std::string VectorSum::value_descriptor() {
+      63           0 :   return "the norm of the mean vector";
+      64             : }
+      65             : 
+      66           0 : void VectorSum::resize() {
+      67           0 :   unsigned ncomp=getAction()->getNumberOfQuantities() - 2;
+      68             : 
+      69           0 :   if( getAction()->derivativesAreRequired() ) {
+      70           0 :     nder=getAction()->getNumberOfDerivatives();
+      71           0 :     resizeBuffer( (1+nder)*ncomp ); getFinalValue()->resizeDerivatives( nder );
+      72             :   } else {
+      73           0 :     nder=0; resizeBuffer(ncomp);
+      74             :   }
+      75           0 : }
+      76             : 
+      77           0 : void VectorSum::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      78           0 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      79             : 
+      80           0 :   double weight=myvals.get(0);
+      81             :   plumed_dbg_assert( weight>=getTolerance() );
+      82           0 :   for(unsigned i=0; i<ncomp; ++i) buffer[bufstart + i*(1+nder)] += weight*myvals.get(2+i);
+      83           0 :   if( !getAction()->derivativesAreRequired() ) return;
+      84             : 
+      85           0 :   for(unsigned i=0; i<ncomp; ++i) {
+      86           0 :     double colvar=myvals.get(2+i);
+      87           0 :     myvals.chainRule( 2+i, i, 1, 0, weight, bufstart, buffer );
+      88           0 :     if( diffweight ) myvals.chainRule( 0, i, 1, 0, colvar, bufstart, buffer );
+      89             :   }
+      90           0 :   return;
+      91             : }
+      92             : 
+      93           0 : void VectorSum::finish( const std::vector<double>& buffer ) {
+      94           0 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      95             : 
+      96             :   double sum=0;
+      97           0 :   for(unsigned i=0; i<ncomp; ++i) {
+      98           0 :     double tmp = buffer[bufstart+(nder+1)*i];
+      99           0 :     sum+=tmp*tmp;
+     100             :   }
+     101           0 :   double tw = 1.0 / sqrt(sum);
+     102           0 :   setOutputValue( sqrt(sum) );
+     103           0 :   if( !getAction()->derivativesAreRequired() ) return;
+     104             : 
+     105             :   Value* fval=getFinalValue();
+     106           0 :   for(unsigned icomp=0; icomp<ncomp; ++icomp) {
+     107           0 :     double tmp = buffer[bufstart + icomp*(1+nder)];
+     108           0 :     unsigned bstart = bufstart + icomp*(nder+1) + 1;
+     109           0 :     for(unsigned jder=0; jder<nder; ++jder) fval->addDerivative( jder, tw*tmp*buffer[bstart + jder] );
+     110             :   }
+     111             : }
+     112             : 
+     113             : }
+     114             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/index-sort-f.html b/coverage/crystallization/index-sort-f.html new file mode 100644 index 0000000000..98b27e1ec1 --- /dev/null +++ b/coverage/crystallization/index-sort-f.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1015121183.8 %
Date:2024-05-27 13:05: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
Fccubic.cpp +
100.0%
+
100.0 %29 / 2985.7 %6 / 7
Tetrahedral.cpp +
100.0%
+
100.0 %23 / 2385.7 %6 / 7
SMAC.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
Gradient.cpp +
71.8%71.8%
+
71.8 %51 / 7187.5 %7 / 8
BondOrientation.cpp +
91.2%91.2%
+
91.2 %52 / 5787.5 %7 / 8
Q6.cpp +
100.0%
+
100.0 %22 / 2288.9 %8 / 9
EnvironmentSimilarity.cpp +
94.2%94.2%
+
94.2 %226 / 24090.0 %9 / 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
GradientVessel.cpp +
84.2%84.2%
+
84.2 %80 / 95100.0 %10 / 10
VectorMean.cpp +
100.0%
+
100.0 %44 / 44100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/index-sort-l.html b/coverage/crystallization/index-sort-l.html new file mode 100644 index 0000000000..3e62d400f2 --- /dev/null +++ b/coverage/crystallization/index-sort-l.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1015121183.8 %
Date:2024-05-27 13:05: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
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
EnvironmentSimilarity.cpp +
94.2%94.2%
+
94.2 %226 / 24090.0 %9 / 10
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.16
+
+ + + diff --git a/coverage/crystallization/index.html b/coverage/crystallization/index.html new file mode 100644 index 0000000000..565baaf990 --- /dev/null +++ b/coverage/crystallization/index.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1015121183.8 %
Date:2024-05-27 13:05: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 +
94.2%94.2%
+
94.2 %226 / 24090.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.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html new file mode 100644 index 0000000000..aaa2807c7c --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe1696createERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html new file mode 100644 index 0000000000..2b813cf597 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe1696createERKNS_13ActionOptionsE7
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_145ClassicalMultiDimensionalScalingRegisterMe169D2Ev4168
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html new file mode 100644 index 0000000000..35010cd033 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + 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-05-27 13:05: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       12518 : PLUMED_REGISTER_ACTION(ClassicalMultiDimensionalScaling,"CLASSICAL_MDS")
+     170             : 
+     171           9 : void ClassicalMultiDimensionalScaling::registerKeywords( Keywords& keys ) {
+     172           9 :   DimensionalityReductionBase::registerKeywords( keys );
+     173           9 : }
+     174             : 
+     175           7 : ClassicalMultiDimensionalScaling::ClassicalMultiDimensionalScaling( const ActionOptions& ao):
+     176             :   Action(ao),
+     177           7 :   DimensionalityReductionBase(ao)
+     178             : {
+     179           7 :   if( dimredbase ) error("input to CLASSICAL_MDS should not be output from dimensionality reduction object");
+     180           7 : }
+     181             : 
+     182          12 : void ClassicalMultiDimensionalScaling::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+     183             :   // Retrieve the distances from the dimensionality reduction object
+     184          12 :   double half=(-0.5); Matrix<double> distances( half*targets );
+     185             : 
+     186             :   // Apply centering transtion
+     187             :   unsigned n=distances.nrows(); double sum;
+     188             :   // First HM
+     189        1564 :   for(unsigned i=0; i<n; ++i) {
+     190      389056 :     sum=0; for(unsigned j=0; j<n; ++j) sum+=distances(i,j);
+     191      389056 :     for(unsigned j=0; j<n; ++j) distances(i,j) -= sum/n;
+     192             :   }
+     193             :   // Now (HM)H
+     194        1564 :   for(unsigned i=0; i<n; ++i) {
+     195      389056 :     sum=0; for(unsigned j=0; j<n; ++j) sum+=distances(j,i);
+     196      389056 :     for(unsigned j=0; j<n; ++j) distances(j,i) -= sum/n;
+     197             :   }
+     198             : 
+     199             :   // Diagonalize matrix
+     200          12 :   std::vector<double> eigval(n); Matrix<double> eigvec(n,n);
+     201          12 :   diagMat( distances, eigval, eigvec );
+     202             : 
+     203             :   // Pass final projections to map object
+     204        1564 :   for(unsigned i=0; i<n; ++i) {
+     205        4654 :     for(unsigned j=0; j<projections.ncols(); ++j) projections(i,j)=std::sqrt(eigval[n-1-j])*eigvec(n-1-j,i);
+     206             :   }
+     207          12 : }
+     208             : 
+     209             : }
+     210             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html b/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..3a0c03da59 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.func.html b/coverage/dimred/DimensionalityReductionBase.cpp.func.html new file mode 100644 index 0000000000..df0fe1cac9 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html new file mode 100644 index 0000000000..7f4dd84b06 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475979.7 %
Date:2024-05-27 13:05: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          30 : void DimensionalityReductionBase::registerKeywords( Keywords& keys ) {
+      31          30 :   analysis::AnalysisBase::registerKeywords( keys );
+      32          60 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+      33          60 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      34          30 : }
+      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.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html b/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html new file mode 100644 index 0000000000..6637235d47 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.func.html b/coverage/dimred/DimensionalityReductionBase.h.func.html new file mode 100644 index 0000000000..0cdfcbe3fa --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.gcov.html b/coverage/dimred/DimensionalityReductionBase.h.gcov.html new file mode 100644 index 0000000000..5343b603a0 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html b/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html new file mode 100644 index 0000000000..9f09980d53 --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.func.html b/coverage/dimred/OutputPCAProjections.cpp.func.html new file mode 100644 index 0000000000..c1fade0b26 --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe586createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_131OutputPCAProjectionRegisterMe58D2Ev4168
_ZN4PLMD6dimred19OutputPCAProjection15performAnalysisEv2
_ZN4PLMD6dimred19OutputPCAProjection16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred19OutputPCAProjectionC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjectionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred19OutputPCAProjection11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.gcov.html b/coverage/dimred/OutputPCAProjections.cpp.gcov.html new file mode 100644 index 0000000000..a5ae530462 --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + LCOV - plumed test coverage - dimred/OutputPCAProjections.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - OutputPCAProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353697.2 %
Date:2024-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(OutputPCAProjection,"OUTPUT_PCA_PROJECTION")
+      59             : 
+      60           4 : void OutputPCAProjection::registerKeywords( Keywords& keys ) {
+      61           4 :   analysis::AnalysisBase::registerKeywords( keys );
+      62           8 :   keys.add("compulsory","FILE","the name of the file to output to");
+      63           8 :   keys.add("optional","FMT","the format to use in the output file");
+      64           8 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      65           4 : }
+      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.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func-sort-c.html b/coverage/dimred/PCA.cpp.func-sort-c.html new file mode 100644 index 0000000000..4425a30104 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func.html b/coverage/dimred/PCA.cpp.func.html new file mode 100644 index 0000000000..97e00c8b88 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe1006createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_116PCARegisterMe100D2Ev4168
_ZN4PLMD6dimred3PCA13getProjectionERKjRSt6vectorIdSaIdEERd0
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
_ZN4PLMD6dimred3PCA15performAnalysisEv3
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.gcov.html b/coverage/dimred/PCA.cpp.gcov.html new file mode 100644 index 0000000000..15a6398fc5 --- /dev/null +++ b/coverage/dimred/PCA.cpp.gcov.html @@ -0,0 +1,354 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(PCA,"PCA")
+     101             : 
+     102           5 : void PCA::registerKeywords( Keywords& keys ) {
+     103          15 :   DimensionalityReductionBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+     104          10 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+     105          10 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+     106           5 : }
+     107             : 
+     108           3 : PCA::PCA(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           3 :   DimensionalityReductionBase(ao)
+     111             : {
+     112             :   // Get the input PDB file from the underlying ReadAnalysisFrames object
+     113           3 :   analysis::ReadAnalysisFrames* myframes = dynamic_cast<analysis::ReadAnalysisFrames*>( my_input_data );
+     114           3 :   if( !myframes ) error("input to PCA should be ReadAnalysisFrames object");
+     115           6 :   parse("METRIC",mtype); std::vector<AtomNumber> atoms;
+     116           3 :   log.printf("  performing PCA analysis using %s metric \n", mtype.c_str() );
+     117           3 :   if( my_input_data->getNumberOfAtoms()>0 ) {
+     118           2 :     parseAtomList("ATOMS",atoms);
+     119           1 :     if( atoms.size()!=0 ) {
+     120           0 :       mypdb.setAtomNumbers( atoms );
+     121           0 :       for(unsigned i=0; i<atoms.size(); ++i) {
+     122             :         bool found=false;
+     123           0 :         for(unsigned j=0; j<my_input_data->getAtomIndexes().size(); ++j) {
+     124           0 :           if( my_input_data->getAtomIndexes()[j]==atoms[i] ) { found=true; break; }
+     125             :         }
+     126           0 :         if( !found ) {
+     127           0 :           std::string num; Tools::convert( atoms[i].serial(), num );
+     128           0 :           error("atom number " + num + " is not stored in any action that has been input");
+     129             :         }
+     130             :       }
+     131           0 :       mypdb.addBlockEnd( atoms.size() );
+     132           1 :     } else if( getNumberOfArguments()==0 ) {
+     133           1 :       mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+     134           1 :       mypdb.addBlockEnd( my_input_data->getAtomIndexes().size() );
+     135           1 :       if( mtype=="EUCLIDEAN" ) mtype="OPTIMAL";
+     136             :     }
+     137             :   }
+     138           3 :   if( my_input_data->getArgumentNames().size()>0 ) {
+     139           2 :     if( getNumberOfArguments()==0 && atoms.size()==0 ) {
+     140           2 :       std::vector<std::string> argnames( my_input_data->getArgumentNames() );
+     141           2 :       mypdb.setArgumentNames( argnames ); requestArguments( my_input_data->getArgumentList() );
+     142           2 :     } else {
+     143           0 :       std::vector<Value*> myargs( getArguments() );
+     144           0 :       std::vector<std::string> inargnames( my_input_data->getArgumentNames() );
+     145           0 :       std::vector<std::string> argnames( myargs.size() );
+     146           0 :       for(unsigned i=0; i<myargs.size(); ++i) {
+     147           0 :         argnames[i]=myargs[i]->getName();
+     148             :         bool found=false;
+     149           0 :         for(unsigned j=0; j<inargnames.size(); ++j) {
+     150           0 :           if( argnames[i]==inargnames[j] ) { found=true; break; }
+     151             :         }
+     152           0 :         if( !found ) error("input named " + my_input_data->getLabel() + " does not store/calculate quantity named " + argnames[i] );
+     153             :       }
+     154           0 :       mypdb.setArgumentNames( argnames ); requestArguments( myargs );
+     155           0 :     }
+     156             :   }
+     157           3 :   if( nlow==0 ) error("dimensionality of output not set");
+     158           3 :   checkRead();
+     159           3 : }
+     160             : 
+     161           3 : void PCA::performAnalysis() {
+     162             :   // Align everything to the first frame
+     163           3 :   my_input_data->getStoredData( 0, false ).transferDataToPDB( mypdb );
+     164           3 :   auto myconf0=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     165           3 :   MultiValue myval( 1, myconf0->getNumberOfReferenceArguments() + 3*myconf0->getNumberOfReferencePositions() + 9 );
+     166           3 :   ReferenceValuePack mypack( myconf0->getNumberOfReferenceArguments(), myconf0->getNumberOfReferencePositions(), myval );
+     167          25 :   for(unsigned i=0; i<myconf0->getNumberOfReferencePositions(); ++i) mypack.setAtomIndex( i, i );
+     168             :   // Setup some PCA storage
+     169           3 :   myconf0->setupPCAStorage ( mypack );
+     170           3 :   std::vector<double> displace( myconf0->getNumberOfReferencePositions() );
+     171           3 :   if( myconf0->getNumberOfReferencePositions()>0 ) {
+     172           1 :     ReferenceAtoms* at = dynamic_cast<ReferenceAtoms*>( myconf0.get() );
+     173           1 :     displace = at->getDisplace();
+     174             :   }
+     175             : 
+     176             :   // Create some arrays to store the average position
+     177           3 :   std::vector<double> sarg( myconf0->getNumberOfReferenceArguments(), 0 );
+     178           3 :   std::vector<Vector> spos( myconf0->getNumberOfReferencePositions() );
+     179          25 :   for(unsigned i=0; i<myconf0->getNumberOfReferencePositions(); ++i) spos[i].zero();
+     180             : 
+     181             :   // Calculate the average displacement from the first frame
+     182           3 :   double norm=getWeight(0); std::vector<double> args( getNumberOfArguments() );
+     183        1638 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+     184        1635 :     my_input_data->getStoredData( i, false ).transferDataToPDB( mypdb );
+     185        3815 :     for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     186        1635 :     myconf0->calc( mypdb.getPositions(), getPbc(), getArguments(), args, mypack, true );
+     187             :     // Accumulate average displacement of arguments (Here PBC could do fucked up things - really needs Berry Phase ) GAT
+     188        3815 :     for(unsigned j=0; j<myconf0->getNumberOfReferenceArguments(); ++j) sarg[j] += 0.5*getWeight(i)*mypack.getArgumentDerivative(j);
+     189             :     // Accumulate average displacement of position
+     190       13625 :     for(unsigned j=0; j<myconf0->getNumberOfReferencePositions(); ++j) spos[j] += getWeight(i)*mypack.getAtomsDisplacementVector()[j] / displace[j];
+     191        1635 :     norm += getWeight(i);
+     192             :   }
+     193             :   // Now normalise the displacements to get the average and add these to the first frame
+     194           3 :   double inorm = 1.0 / norm ;
+     195           7 :   for(unsigned j=0; j<myconf0->getNumberOfReferenceArguments(); ++j) sarg[j] = inorm*sarg[j] + myconf0->getReferenceArguments()[j];
+     196          25 :   for(unsigned j=0; j<myconf0->getNumberOfReferencePositions(); ++j) spos[j] = inorm*spos[j] + myconf0->getReferencePositions()[j];
+     197             :   // Now accumulate the covariance
+     198           3 :   unsigned narg=myconf0->getNumberOfReferenceArguments(), natoms=myconf0->getNumberOfReferencePositions();
+     199           3 :   Matrix<double> covar( narg+3*natoms, narg+3*natoms ); covar=0;
+     200        1641 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+     201        1638 :     my_input_data->getStoredData( i, false ).transferDataToPDB( mypdb );
+     202        3822 :     for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     203        1638 :     myconf0->calc( mypdb.getPositions(), getPbc(), getArguments(), args, mypack, true );
+     204        3822 :     for(unsigned jarg=0; jarg<narg; ++jarg) {
+     205             :       // Need sorting for PBC with GAT
+     206        2184 :       double jarg_d = 0.5*mypack.getArgumentDerivative(jarg) + myconf0->getReferenceArguments()[jarg] - sarg[jarg];
+     207        6552 :       for(unsigned karg=0; karg<narg; ++karg) {
+     208             :         // Need sorting for PBC with GAT
+     209        4368 :         double karg_d = 0.5*mypack.getArgumentDerivative(karg) + myconf0->getReferenceArguments()[karg] - sarg[karg];
+     210        4368 :         covar( jarg, karg ) += 0.25*getWeight(i)*jarg_d*karg_d; // mypack.getArgumentDerivative(jarg)*mypack.getArgumentDerivative(karg);
+     211             :       }
+     212             :     }
+     213       13650 :     for(unsigned jat=0; jat<natoms; ++jat) {
+     214       48048 :       for(unsigned jc=0; jc<3; ++jc) {
+     215       36036 :         double jdisplace = mypack.getAtomsDisplacementVector()[jat][jc] / displace[jat] + myconf0->getReferencePositions()[jat][jc] - spos[jat][jc];
+     216      828828 :         for(unsigned kat=0; kat<natoms; ++kat) {
+     217     3171168 :           for(unsigned kc=0; kc<3; ++kc) {
+     218     2378376 :             double kdisplace = mypack.getAtomsDisplacementVector()[kat][kc] /displace[kat] + myconf0->getReferencePositions()[kat][kc] - spos[kat][kc];
+     219     2378376 :             covar( narg+3*jat + jc, narg+3*kat + kc ) += getWeight(i)*jdisplace*kdisplace;
+     220             :           }
+     221             :         }
+     222             :       }
+     223             :     }
+     224             :   }
+     225             :   // Normalise
+     226          73 :   for(unsigned i=0; i<covar.nrows(); ++i) {
+     227        4434 :     for(unsigned j=0; j<covar.ncols(); ++j) covar(i,j) *= inorm;
+     228             :   }
+     229             : 
+     230             :   // Diagonalise the covariance
+     231           3 :   std::vector<double> eigval( narg+3*natoms );
+     232             :   Matrix<double> eigvec( narg+3*natoms, narg+3*natoms );
+     233           3 :   diagMat( covar, eigval, eigvec );
+     234             : 
+     235             :   // Output the reference configuration
+     236           3 :   mypdb.setAtomPositions( spos );
+     237           7 :   for(unsigned j=0; j<sarg.size(); ++j) mypdb.setArgumentValue( getArguments()[j]->getName(), sarg[j] );
+     238             :   // Reset the reference configuration
+     239           6 :   myref = metricRegister().create<ReferenceConfiguration>( mtype, mypdb );
+     240             : 
+     241             :   // Store and print the eigenvectors
+     242           3 :   std::vector<Vector> tmp_atoms( natoms );
+     243           9 :   for(unsigned dim=0; dim<nlow; ++dim) {
+     244           6 :     unsigned idim = covar.ncols() - 1 - dim;
+     245          14 :     for(unsigned i=0; i<narg; ++i) mypdb.setArgumentValue( getArguments()[i]->getName(), eigvec(idim,i) );
+     246          50 :     for(unsigned i=0; i<natoms; ++i) {
+     247         176 :       for(unsigned k=0; k<3; ++k) tmp_atoms[i][k]=eigvec(idim,narg+3*i+k);
+     248             :     }
+     249           6 :     mypdb.setAtomPositions( tmp_atoms );
+     250             :     // Create a direction object so that we can calculate other PCA components
+     251          12 :     directions.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")));
+     252           6 :     directions[dim].read( mypdb );
+     253             :   }
+     254           3 : }
+     255             : 
+     256           0 : void PCA::getProjection( const unsigned& idata, std::vector<double>& point, double& weight ) {
+     257           0 :   if( point.size()!=nlow ) point.resize( nlow );
+     258             :   // Retrieve the weight
+     259           0 :   weight = getWeight(idata);
+     260             :   // Retrieve the data point
+     261           0 :   getProjection( my_input_data->getStoredData( idata, false ), point );
+     262           0 : }
+     263             : 
+     264         546 : void PCA::getProjection( analysis::DataCollectionObject& myidata, std::vector<double>& point ) {
+     265         546 :   myidata.transferDataToPDB( mypdb ); std::vector<double> args( getArguments().size() );
+     266        1638 :   for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     267             :   // Create some storage space
+     268         546 :   MultiValue myval( 1, 3*mypdb.getPositions().size() + args.size() + 9);
+     269         546 :   ReferenceValuePack mypack( args.size(), mypdb.getPositions().size(), myval );
+     270         546 :   for(unsigned i=0; i<mypdb.getPositions().size(); ++i) mypack.setAtomIndex( i, i );
+     271         546 :   myref->setupPCAStorage( mypack );
+     272             :   // And calculate
+     273         546 :   myref->calculate( mypdb.getPositions(), getPbc(), getArguments(), mypack, true );
+     274        1638 :   for(unsigned i=0; i<nlow; ++i) point[i]=myref->projectDisplacementOnVector( directions[i], getArguments(), args, mypack );
+     275        1092 : }
+     276             : 
+     277             : }
+     278             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.h.func-sort-c.html b/coverage/dimred/PCA.h.func-sort-c.html new file mode 100644 index 0000000000..89d5093a3f --- /dev/null +++ b/coverage/dimred/PCA.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/PCA.h.func.html b/coverage/dimred/PCA.h.func.html new file mode 100644 index 0000000000..6d8493c422 --- /dev/null +++ b/coverage/dimred/PCA.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/PCA.h.gcov.html b/coverage/dimred/PCA.h.gcov.html new file mode 100644 index 0000000000..1aa86a6836 --- /dev/null +++ b/coverage/dimred/PCA.h.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html new file mode 100644 index 0000000000..7e0db80619 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69D2Ev4168
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html new file mode 100644 index 0000000000..684d109e44 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe696createERKNS_13ActionOptionsE2
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_136ProjectNonLandmarkPointsRegisterMe69D2Ev4168
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15getArgumentListEv0
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15performAnalysisEv2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred24ProjectNonLandmarkPoints11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html new file mode 100644 index 0000000000..87d84da530 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html @@ -0,0 +1,213 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ProjectNonLandmarkPoints,"PROJECT_ALL_ANALYSIS_DATA")
+      70             : 
+      71           4 : void ProjectNonLandmarkPoints::registerKeywords( Keywords& keys ) {
+      72           4 :   analysis::AnalysisBase::registerKeywords( keys );
+      73           8 :   keys.add("compulsory","PROJECTION","the projection that you wish to generate out-of-sample projections with");
+      74           8 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient optimization");
+      75           8 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      76           4 : }
+      77             : 
+      78           2 : ProjectNonLandmarkPoints::ProjectNonLandmarkPoints( const ActionOptions& ao ):
+      79             :   Action(ao),
+      80             :   analysis::AnalysisBase(ao),
+      81           2 :   mybase(NULL)
+      82             : {
+      83           2 :   std::string myproj; parse("PROJECTION",myproj);
+      84           2 :   mybase = plumed.getActionSet().selectWithLabel<DimensionalityReductionBase*>( myproj );
+      85           2 :   if( !mybase ) error("could not find projection of data named " + myproj );
+      86             :   // Add the dependency and set the dimensionality
+      87           2 :   addDependency( mybase ); nlow = mybase->nlow;
+      88             :   // Add fake components to the underlying ActionWithValue for the arguments
+      89             :   std::string num;
+      90           6 :   for(unsigned i=0; i<nlow; ++i) {
+      91          12 :     Tools::convert(i+1,num); addComponent( "coord-" + num ); componentIsNotPeriodic( "coord-" + num );
+      92             :   }
+      93             : 
+      94           2 :   log.printf("  generating out-of-sample projections using projection with label %s \n",myproj.c_str() );
+      95           4 :   parse("CGTOL",cgtol);
+      96           2 : }
+      97             : 
+      98           0 : std::vector<Value*> ProjectNonLandmarkPoints::getArgumentList() {
+      99             :   std::vector<Value*> arglist( analysis::AnalysisBase::getArgumentList() );
+     100           0 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+     101           0 :   return arglist;
+     102             : }
+     103             : 
+     104        1046 : void ProjectNonLandmarkPoints::generateProjection( const unsigned& idat, std::vector<double>& point ) {
+     105        1046 :   PCA* ispca = dynamic_cast<PCA*>( mybase );
+     106        1046 :   if( ispca ) {
+     107         546 :     ispca->getProjection( my_input_data->getStoredData(idat,false), point );
+     108             :   } else {
+     109             :     ConjugateGradient<ProjectNonLandmarkPoints> myminimiser( this );
+     110         500 :     unsigned closest=0; double mindist = std::sqrt( getDissimilarity( mybase->getDataPointIndexInBase(0), idat ) );
+     111         500 :     mybase->setTargetDistance( 0, mindist );
+     112      125000 :     for(unsigned i=1; i<mybase->getNumberOfDataPoints(); ++i) {
+     113      124500 :       double dist = std::sqrt( getDissimilarity( mybase->getDataPointIndexInBase(i), idat ) );
+     114      124500 :       mybase->setTargetDistance( i, dist );
+     115      124500 :       if( dist<mindist ) { mindist=dist; closest=i; }
+     116             :     }
+     117             :     // Put the initial guess near to the closest landmark  -- may wish to use grid here again Sandip??
+     118         500 :     Random random; random.setSeed(-1234);
+     119        1500 :     for(unsigned j=0; j<nlow; ++j) point[j]=mybase->projections(closest,j) + (random.RandU01() - 0.5)*0.01;
+     120         500 :     myminimiser.minimise( cgtol, point, &ProjectNonLandmarkPoints::calculateStress );
+     121             :   }
+     122        1046 : }
+     123             : 
+     124        1046 : analysis::DataCollectionObject& ProjectNonLandmarkPoints::getStoredData( const unsigned& idat, const bool& calcdist ) {
+     125        1046 :   std::vector<double> pp(nlow); generateProjection( idat, pp ); std::string num;
+     126             :   analysis::DataCollectionObject& myref=AnalysisBase::getStoredData(idat,calcdist);
+     127        3138 :   for(unsigned i=0; i<nlow; ++i) { Tools::convert(i+1,num); myref.setArgument( getLabel() + ".coord-" + num, pp[i] ); }
+     128        1046 :   return myref;
+     129             : }
+     130             : 
+     131       16744 : double ProjectNonLandmarkPoints::calculateStress( const std::vector<double>& pp, std::vector<double>& der ) {
+     132       16744 :   return mybase->calculateStress( pp, der );
+     133             : }
+     134             : 
+     135             : }
+     136             : }
+     137             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func-sort-c.html b/coverage/dimred/SMACOF.cpp.func-sort-c.html new file mode 100644 index 0000000000..022298548e --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func.html b/coverage/dimred/SMACOF.cpp.func.html new file mode 100644 index 0000000000..7744b673e7 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.gcov.html b/coverage/dimred/SMACOF.cpp.gcov.html new file mode 100644 index 0000000000..ee2c8c095c --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.gcov.html @@ -0,0 +1,169 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func-sort-c.html b/coverage/dimred/SketchMap.cpp.func-sort-c.html new file mode 100644 index 0000000000..65bfce8661 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe436createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func.html b/coverage/dimred/SketchMap.cpp.func.html new file mode 100644 index 0000000000..969c83de9e --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe436createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_121SketchMapRegisterMe43D2Ev4168
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.gcov.html b/coverage/dimred/SketchMap.cpp.gcov.html new file mode 100644 index 0000000000..9fe3eebed3 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.gcov.html @@ -0,0 +1,181 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(SketchMap,"SKETCH_MAP")
+      44             : 
+      45           2 : void SketchMap::registerKeywords( Keywords& keys ) {
+      46           2 :   ActionShortcut::registerKeywords( keys );
+      47           4 :   keys.add("compulsory","NLOW_DIM","the dimension of the low dimensional space in which the projections will be constructed");
+      48           4 :   keys.add("compulsory","MATRIX","the matrix of distances between points that you want to reproduce in your sketch-map projection");
+      49           4 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      50           4 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      51           4 :   keys.add("compulsory","ANNEAL_RATE","0.5","the rate at which to do the annealing");
+      52           4 :   keys.add("compulsory","ANNEAL_STEPS","10","the number of steps of annealing to do");
+      53           4 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      54             : // Smap pointwise input
+      55           4 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      56           4 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      57           4 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      58           4 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      59           2 : }
+      60             : 
+      61           0 : SketchMap::SketchMap( const ActionOptions& ao ) :
+      62             :   Action(ao),
+      63           0 :   ActionShortcut(ao)
+      64             : {
+      65             :   // Input for MDS
+      66           0 :   std::string mds_line = getShortcutLabel() + "_mds: CLASSICAL_MDS";
+      67           0 :   std::string nlow; parse("NLOW_DIM",nlow); mds_line += " NLOW_DIM=" + nlow;
+      68           0 :   std::string mat; parse("MATRIX",mat); mds_line += " USE_OUTPUT_DATA_FROM=" + mat;
+      69           0 :   readInputLine( mds_line );
+      70             :   // Create generic input for all conjgrad cycles
+      71           0 :   std::string cgtol; parse("CGTOL",cgtol); std::string ncyc; parse("NCYCLES",ncyc); std::string buf; parse("BUFFER",buf);
+      72           0 :   std::string cg_grid; parse("CGRID_SIZE",cg_grid); std::string fg_grid; parse("FGRID_SIZE",fg_grid);
+      73           0 :   std::string cg_step_input = " CGTOL=" + cgtol; unsigned nlow_dim; Tools::convert( nlow, nlow_dim );
+      74           0 :   std::string pw_step_input = cg_step_input + " NCYCLES=" + ncyc + " BUFFER=" + buf;
+      75           0 :   pw_step_input += " CGRID_SIZE=" + cg_grid; for(unsigned i=1; i<nlow_dim; ++i) pw_step_input += "," + cg_grid;
+      76           0 :   pw_step_input += " FGRID_SIZE=" + fg_grid; for(unsigned i=1; i<nlow_dim; ++i) pw_step_input += "," + fg_grid;
+      77             :   // Input for iterative distance matching
+      78           0 :   std::string imds_line_cg = getShortcutLabel() + "_smap1_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_mds";
+      79           0 :   std::string hd_func; parse("HIGH_DIM_FUNCTION",hd_func); imds_line_cg += " HIGH_DIM_FUNCTION={" + hd_func + "}";
+      80           0 :   std::string ld_func; parse("LOW_DIM_FUNCTION",ld_func); imds_line_cg += " LOW_DIM_FUNCTION={" + ld_func + "}";
+      81           0 :   imds_line_cg += cg_step_input + " MIXPARAM=1.0"; readInputLine( imds_line_cg );
+      82           0 :   std::string imds_line_pw = getShortcutLabel() + "_smap1_pw: SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap1_cg";
+      83           0 :   imds_line_pw += pw_step_input + " MIXPARAM=1.0"; readInputLine( imds_line_pw );
+      84             :   // Now sketch-map
+      85           0 :   unsigned asteps; parse("ANNEAL_STEPS",asteps); std::string psmap = getShortcutLabel() + "_smap1_pw";
+      86           0 :   if( asteps>1 ) {
+      87           0 :     double smear; parse("ANNEAL_RATE", smear); double old_mix = 1.0; double new_mix = old_mix*smear;
+      88           0 :     for(unsigned i=0; i<asteps; ++i) {
+      89           0 :       std::string omix; Tools::convert( old_mix, omix ); std::string nmix; Tools::convert( new_mix, nmix );
+      90           0 :       imds_line_cg = getShortcutLabel() + "_smap" + nmix + "_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap" + omix + "_pw";
+      91           0 :       imds_line_cg += cg_step_input + " MIXPARAM=" + nmix; readInputLine( imds_line_cg );
+      92           0 :       imds_line_pw = getShortcutLabel() + "_smap" + nmix + "_pw: SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap" + omix + "_cg";
+      93           0 :       imds_line_pw += pw_step_input + " MIXPARAM=" + nmix; readInputLine( imds_line_pw );
+      94           0 :       old_mix = new_mix; new_mix = old_mix*smear; psmap = getShortcutLabel() + "_smap" + nmix + "_pw";
+      95             :     }
+      96             :   }
+      97             :   // Final sketch-map with no mixing of distance matching
+      98           0 :   imds_line_cg = getShortcutLabel() + "_smap_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + psmap + cg_step_input;
+      99           0 :   readInputLine( imds_line_cg );
+     100           0 :   imds_line_pw = getShortcutLabel() + ": SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap_cg" + pw_step_input;
+     101           0 :   readInputLine( imds_line_pw );
+     102           0 : }
+     103             : 
+     104             : }
+     105             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.func-sort-c.html b/coverage/dimred/SketchMapBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..0301f05301 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.func.html b/coverage/dimred/SketchMapBase.cpp.func.html new file mode 100644 index 0000000000..5fec3c9b34 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.gcov.html b/coverage/dimred/SketchMapBase.cpp.gcov.html new file mode 100644 index 0000000000..589ec91b33 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.gcov.html @@ -0,0 +1,242 @@ + + + + + + + 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-05-27 13:05: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          14 : void SketchMapBase::registerKeywords( Keywords& keys ) {
+      28          14 :   DimensionalityReductionBase::registerKeywords( keys );
+      29          14 :   keys.remove("NLOW_DIM");
+      30          28 :   keys.add("compulsory","HIGH_DIM_FUNCTION","as in input action","the parameters of the switching function in the high dimensional space");
+      31          28 :   keys.add("compulsory","LOW_DIM_FUNCTION","as in input action","the parameters of the switching function in the low dimensional space");
+      32          28 :   keys.add("compulsory","MIXPARAM","0.0","the amount of the pure distances to mix into the stress function");
+      33          14 : }
+      34             : 
+      35           6 : SketchMapBase::SketchMapBase( const ActionOptions& ao ):
+      36             :   Action(ao),
+      37             :   DimensionalityReductionBase(ao),
+      38           6 :   smapbase(NULL),
+      39           6 :   normw(0.0)
+      40             : {
+      41             :   // Check if we have data from a input sketch-map object - we can reuse switching functions wahoo!!
+      42           6 :   if( dimredbase ) smapbase = dynamic_cast<SketchMapBase*>( dimredbase );
+      43             : 
+      44             :   // Read in the switching functions
+      45             :   std::string linput,hinput, errors;
+      46          12 :   parse("HIGH_DIM_FUNCTION",hinput);
+      47           6 :   if( hinput=="as in input action" ) {
+      48           1 :     if( !smapbase ) error("high dimensional switching function has not been set - use HIGH_DIM_FUNCTION");
+      49           1 :     reuse_hd=true;
+      50           1 :     log.printf("  reusing high dimensional filter function defined in previous sketch-map action\n");
+      51             :   } else {
+      52           5 :     reuse_hd=false;
+      53           5 :     highdf.set(hinput,errors);
+      54           5 :     if(errors.length()>0) error(errors);
+      55          10 :     log.printf("  filter function for dissimilarities in high dimensional space has cutoff %s \n",highdf.description().c_str() );
+      56             :   }
+      57             : 
+      58          12 :   parse("LOW_DIM_FUNCTION",linput);
+      59           6 :   if( linput=="as in input action" ) {
+      60           1 :     if( !smapbase ) error("low dimensional switching function has not been set - use LOW_DIM_FUNCTION");
+      61           1 :     reuse_ld=true;
+      62           1 :     log.printf("  reusing low dimensional filter function defined in previous sketch-map action\n");
+      63             :   } else {
+      64           5 :     reuse_ld=false;
+      65           5 :     lowdf.set(linput,errors);
+      66           5 :     if(errors.length()>0) error(errors);
+      67          10 :     log.printf("  filter function for distances in low dimensionality space has cutoff %s \n",lowdf.description().c_str() );
+      68             :   }
+      69             : 
+      70             :   // Read the mixing parameter
+      71           6 :   parse("MIXPARAM",mixparam);
+      72           6 :   if( mixparam<0 || mixparam>1 ) error("mixing parameter must be between 0 and 1");
+      73           6 :   log.printf("  mixing %f of pure distances with %f of filtered distances \n",mixparam,1.-mixparam);
+      74           6 : }
+      75             : 
+      76           7 : void SketchMapBase::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+      77           7 :   if( dtargets.size()!=targets.nrows() ) {
+      78             :     // These hold data so that we can do stress calculations
+      79           6 :     dtargets.resize( targets.nrows() ); ftargets.resize( targets.nrows() ); pweights.resize( targets.nrows() );
+      80             :     // Matrices for storing input data
+      81             :     transformed.resize( targets.nrows(), targets.ncols() );
+      82             :     distances.resize( targets.nrows(), targets.ncols() );
+      83             :   }
+      84             : 
+      85             :   // Stores the weights in an array for faster access, as well as the normalization
+      86           7 :   normw=0;
+      87        1141 :   for(unsigned i=0; i<targets.nrows() ; ++i) { pweights[i] = getWeight(i); normw+=pweights[i]; }
+      88           7 :   normw*=normw;
+      89             : 
+      90             :   // Transform the high dimensional distances
+      91             :   double df; distances=0.; transformed=0.;
+      92        1134 :   for(unsigned i=1; i<distances.ncols(); ++i) {
+      93      172838 :     for(unsigned j=0; j<i; ++j) {
+      94      171711 :       distances(i,j)=distances(j,i)=std::sqrt( targets(i,j) );
+      95      171711 :       transformed(i,j)=transformed(j,i)=transformHighDimensionalDistance( distances(i,j), df );
+      96             :     }
+      97             :   }
+      98             :   // And minimse
+      99           7 :   minimise( projections );
+     100           7 : }
+     101             : 
+     102       41344 : double SketchMapBase::calculateStress( const std::vector<double>& p, std::vector<double>& d ) {
+     103             :   // Zero derivative and stress accumulators
+     104      124032 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     105       41344 :   double stress=0; std::vector<double> dtmp( p.size() );
+     106             :   // Now accumulate total stress on system
+     107     6687344 :   for(unsigned i=0; i<ftargets.size(); ++i) {
+     108     6646000 :     if( dtargets[i]<epsilon ) continue ;
+     109             : 
+     110             :     // Calculate distance in low dimensional space
+     111     6615785 :     double dd=0;
+     112    19847355 :     for(unsigned j=0; j<p.size(); ++j) { dtmp[j]=p[j]-projections(i,j); dd+=dtmp[j]*dtmp[j]; }
+     113     6615785 :     dd = std::sqrt(dd);
+     114             : 
+     115             :     // Now do transformations and calculate differences
+     116     6615785 :     double df, fd = transformLowDimensionalDistance( dd, df );
+     117     6615785 :     double ddiff = dd - dtargets[i];
+     118     6615785 :     double fdiff = fd - ftargets[i];
+     119             : 
+     120             :     // Calculate derivatives
+     121     6615785 :     double pref = 2.*getWeight(i) / dd ;
+     122    19847355 :     for(unsigned j=0; j<p.size(); ++j) d[j] += pref*( (1-mixparam)*fdiff*df + mixparam*ddiff )*dtmp[j];
+     123             : 
+     124             :     // Accumulate the total stress
+     125     6615785 :     stress += getWeight(i)*( (1-mixparam)*fdiff*fdiff + mixparam*ddiff*ddiff );
+     126             :   }
+     127       41344 :   return stress;
+     128             : }
+     129             : 
+     130        1913 : double SketchMapBase::calculateFullStress( const std::vector<double>& p, std::vector<double>& d ) {
+     131             :   // Zero derivative and stress accumulators
+     132      393213 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     133        1913 :   double stress=0; std::vector<double> dtmp( nlow );
+     134             : 
+     135      195650 :   for(unsigned i=1; i<distances.nrows(); ++i) {
+     136      193737 :     double iweight = pweights[i];
+     137    14802162 :     for(unsigned j=0; j<i; ++j) {
+     138    14608425 :       double jweight =  pweights[j];
+     139             :       // Calculate distance in low dimensional space
+     140    14608425 :       double dd=0;
+     141    43825275 :       for(unsigned k=0; k<nlow; ++k) { dtmp[k]=p[nlow*i+k] - p[nlow*j+k]; dd+=dtmp[k]*dtmp[k]; }
+     142    14608425 :       dd = std::sqrt(dd);
+     143             : 
+     144             :       // Now do transformations and calculate differences
+     145    14608425 :       double df, fd = transformLowDimensionalDistance( dd, df );
+     146    14608425 :       double ddiff = dd - distances(i,j);
+     147    14608425 :       double fdiff = fd - transformed(i,j);;
+     148             : 
+     149             :       // Calculate derivatives
+     150    14608425 :       double pref = 2.*iweight*jweight*( (1-mixparam)*fdiff*df + mixparam*ddiff ) / dd;
+     151    43825275 :       for(unsigned k=0; k<nlow; ++k) {
+     152    29216850 :         double dterm=pref*dtmp[k]; d[nlow*i+k]+=dterm; d[nlow*j+k]-=dterm;
+     153             :       }
+     154             : 
+     155             :       // Accumulate the total stress
+     156    14608425 :       stress += iweight*jweight*( (1-mixparam)*fdiff*fdiff + mixparam*ddiff*ddiff );
+     157             :     }
+     158             :   }
+     159      393213 :   stress /= normw; for (unsigned k=0; k < d.size(); ++k) d[k] /= normw;
+     160        1913 :   return stress;
+     161             : }
+     162             : 
+     163             : }
+     164             : }
+     165             : 
+     166             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.func-sort-c.html b/coverage/dimred/SketchMapBase.h.func-sort-c.html new file mode 100644 index 0000000000..54347451b8 --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.func.html b/coverage/dimred/SketchMapBase.h.func.html new file mode 100644 index 0000000000..852637499d --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.gcov.html b/coverage/dimred/SketchMapBase.h.gcov.html new file mode 100644 index 0000000000..7ac94b09d2 --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.gcov.html @@ -0,0 +1,169 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html b/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html new file mode 100644 index 0000000000..470982b532 --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe476createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.func.html b/coverage/dimred/SketchMapConjGrad.cpp.func.html new file mode 100644 index 0000000000..b7a4258a8f --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe476createERKNS_13ActionOptionsE3
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_129SketchMapConjGradRegisterMe47D2Ev4168
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.gcov.html b/coverage/dimred/SketchMapConjGrad.cpp.gcov.html new file mode 100644 index 0000000000..ced90d827a --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.gcov.html @@ -0,0 +1,146 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(SketchMapConjGrad,"SKETCHMAP_CONJGRAD")
+      48             : 
+      49           5 : void SketchMapConjGrad::registerKeywords( Keywords& keys ) {
+      50           5 :   SketchMapBase::registerKeywords( keys );
+      51          10 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      52           5 : }
+      53             : 
+      54           3 : SketchMapConjGrad::SketchMapConjGrad( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           3 :   SketchMapBase(ao)
+      57             : {
+      58           3 :   parse("CGTOL",cgtol);
+      59           3 :   log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+      60           3 : }
+      61             : 
+      62           4 : void SketchMapConjGrad::minimise( Matrix<double>& projections ) {
+      63             :   ConjugateGradient<SketchMapConjGrad> mycgminimise( this );
+      64           4 :   std::vector<double> myproj( projections.getVector() );
+      65           4 :   mycgminimise.minimise( cgtol, myproj, &SketchMapConjGrad::calculateFullStress );
+      66           4 :   projections.setFromVector( myproj );
+      67           4 : }
+      68             : 
+      69             : }
+      70             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html b/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html new file mode 100644 index 0000000000..db6c68fa0b --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.func.html b/coverage/dimred/SketchMapPointwise.cpp.func.html new file mode 100644 index 0000000000..5130941d94 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe506createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_130SketchMapPointwiseRegisterMe50D2Ev4168
_ZN4PLMD6dimred18SketchMapPointwise16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred18SketchMapPointwise8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred18SketchMapPointwiseC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.gcov.html b/coverage/dimred/SketchMapPointwise.cpp.gcov.html new file mode 100644 index 0000000000..3d11d8d2c8 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(SketchMapPointwise,"SKETCHMAP_POINTWISE")
+      51             : 
+      52           3 : void SketchMapPointwise::registerKeywords( Keywords& keys ) {
+      53           3 :   SketchMapBase::registerKeywords( keys );
+      54           6 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      55           6 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      56           6 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      57           6 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      58           6 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      59           3 : }
+      60             : 
+      61           1 : SketchMapPointwise::SketchMapPointwise( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63             :   SketchMapBase(ao),
+      64           2 :   npoints(nlow),
+      65           1 :   nfgrid(nlow)
+      66             : {
+      67           3 :   parseVector("CGRID_SIZE",npoints); parse("BUFFER",gbuf);
+      68           1 :   if( npoints.size()!=nlow ) error("vector giving number of grid point in each direction has wrong size");
+      69           2 :   parse("NCYCLES",ncycles); parse("CGTOL",cgtol);
+      70             : 
+      71           2 :   parseVector("FGRID_SIZE",nfgrid);
+      72           1 :   if( nfgrid[0]!=0 && nlow!=2 ) error("interpolation only works in two dimensions");
+      73             : 
+      74           1 :   log.printf("  doing %u cycles of global optimization sweeps\n",ncycles);
+      75           1 :   log.printf("  using coarse grid of points that is %u",npoints[0]);
+      76           1 :   log.printf(" and that is %f larger than the difference between the position of the minimum and maximum projection \n",gbuf);
+      77           2 :   for(unsigned j=1; j<npoints.size(); ++j) log.printf(" by %u",npoints[j]);
+      78           1 :   if( nfgrid[0]>0 ) {
+      79           1 :     log.printf("  interpolating stress onto grid of points that is %u",nfgrid[0]);
+      80           2 :     for(unsigned j=1; j<nfgrid.size(); ++j) log.printf(" by %u",nfgrid[j]);
+      81           1 :     log.printf("\n");
+      82             :   }
+      83           1 :   log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+      84           1 : }
+      85             : 
+      86           1 : void SketchMapPointwise::minimise( Matrix<double>& projections ) {
+      87           1 :   std::vector<double> gmin( nlow ), gmax( nlow ), mypoint( nlow );
+      88             : 
+      89             :   // Find the extent of the grid
+      90           3 :   for(unsigned j=0; j<nlow; ++j) gmin[j]=gmax[j]=projections(0,j);
+      91         100 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      92         297 :     for(unsigned j=0; j<nlow; ++j) {
+      93         198 :       if( projections(i,j) < gmin[j] ) gmin[j] = projections(i,j);
+      94         198 :       if( projections(i,j) > gmax[j] ) gmax[j] = projections(i,j);
+      95             :     }
+      96             :   }
+      97           3 :   for(unsigned j=0; j<nlow; ++j) {
+      98           2 :     double gbuffer = 0.5*gbuf*( gmax[j]-gmin[j] ) - 0.5*( gmax[j]- gmin[j] );
+      99           2 :     gmin[j]-=gbuffer; gmax[j]+=gbuffer;
+     100             :   }
+     101             : 
+     102             :   // And do the search
+     103             :   ConjugateGradient<SketchMapPointwise> mycgminimise( this );
+     104           1 :   gridtools::GridSearch<SketchMapPointwise> mygridsearch( gmin, gmax, npoints, nfgrid, this );
+     105             :   // Run multiple loops over all projections
+     106           3 :   for(unsigned i=0; i<ncycles; ++i) {
+     107         202 :     for(unsigned j=0; j<getNumberOfDataPoints(); ++j) {
+     108             :       // Setup target distances and target functions for calculate stress
+     109       20200 :       for(unsigned k=0; k<getNumberOfDataPoints(); ++k) setTargetDistance( k, distances(j,k)  );
+     110             : 
+     111             :       // Find current projection of jth point
+     112         600 :       for(unsigned k=0; k<mypoint.size(); ++k) mypoint[k]=projections(j,k);
+     113             :       // Minimise using grid search
+     114         200 :       bool moved=mygridsearch.minimise( mypoint, &SketchMapPointwise::calculateStress );
+     115         200 :       if( moved ) {
+     116             :         // Reassign the new projection
+     117          66 :         for(unsigned k=0; k<mypoint.size(); ++k) projections(j,k)=mypoint[k];
+     118             :         // Minimise output using conjugate gradient
+     119          22 :         mycgminimise.minimise( cgtol, projections.getVector(), &SketchMapPointwise::calculateFullStress );
+     120             :       }
+     121             :     }
+     122             :   }
+     123           1 : }
+     124             : 
+     125             : }
+     126             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.func-sort-c.html b/coverage/dimred/SketchMapRead.cpp.func-sort-c.html new file mode 100644 index 0000000000..8e3d4853d6 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe666createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZZN4PLMD6dimred13SketchMapReadC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_1
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66D2Ev4168
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.func.html b/coverage/dimred/SketchMapRead.cpp.func.html new file mode 100644 index 0000000000..7b8e5d9279 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe666createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_125SketchMapReadRegisterMe66D2Ev4168
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
_ZZN4PLMD6dimred13SketchMapReadC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.gcov.html b/coverage/dimred/SketchMapRead.cpp.gcov.html new file mode 100644 index 0000000000..73bcb766ad --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + LCOV - plumed test coverage - dimred/SketchMapRead.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapRead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768292.7 %
Date:2024-05-27 13:05: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 "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       12506 : PLUMED_REGISTER_ACTION(SketchMapRead,"SKETCHMAP_READ")
+      67             : 
+      68           3 : void SketchMapRead::registerKeywords( Keywords& keys ) {
+      69           3 :   SketchMapBase::registerKeywords( keys ); keys.remove("USE_OUTPUT_DATA_FROM");
+      70           6 :   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           6 :   keys.add("compulsory","REFERENCE","the file containing the sketch-map projection");
+      74           6 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      75           6 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      76           3 :   useCustomisableComponents(keys);
+      77           3 : }
+      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=this->fopen(ifilename.c_str(),"r");
+      99           1 :   if(!fp) error("could not open reference file " + ifilename );
+     100             : // call fclose when fp goes out of scope
+     101           1 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+     102             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     103             : 
+     104             : 
+     105             :   // Read in the embedding
+     106             :   bool do_read=true; double val, ww, wnorm=0, prop; unsigned nfram=0;
+     107          85 :   while (do_read) {
+     108          85 :     PDB inpdb;
+     109             :     // Read the pdb file
+     110         170 :     do_read=inpdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     111             :     // Break if we are done
+     112          85 :     if( !do_read ) break ;
+     113             :     // Check for required properties
+     114         252 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     115         168 :       if( !inpdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+     116         168 :       it->second.push_back(prop);
+     117             :     }
+     118             :     // And read the frame ( create a measure )
+     119          84 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, inpdb ) );
+     120         168 :     if( !inpdb.getArgumentValue( "WEIGHT", ww ) ) error("could not find weights in input pdb");
+     121          84 :     weights.push_back( ww ); wnorm += ww; nfram++;
+     122             :     // And create a data collection object
+     123          84 :     analysis::DataCollectionObject new_data; new_data.setAtomNumbersAndArgumentNames( getLabel(), inpdb.getAtomNumbers(), inpdb.getArgumentNames() );
+     124          84 :     new_data.setAtomPositions( inpdb.getPositions() );
+     125         504 :     for(unsigned i=0; i<inpdb.getArgumentNames().size(); ++i) {
+     126         420 :       std::string aname = inpdb.getArgumentNames()[i];
+     127         420 :       if( !inpdb.getArgumentValue( aname, val ) ) error("failed to find argument named " + aname);
+     128         420 :       new_data.setArgument( aname, val );
+     129             :     }
+     130          84 :     data.push_back( new_data );
+     131          85 :   }
+     132             :   // Finish the setup of the object by getting the arguments and atoms that are required
+     133             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     134          85 :   for(unsigned i=0; i<myframes.size(); ++i) { weights[i] /= wnorm; myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     135           1 :   requestAtoms( atoms ); std::vector<Value*> req_args; std::vector<std::string> fargs;
+     136           6 :   for(unsigned i=0; i<args.size(); ++i) {
+     137             :     bool found=false;
+     138          12 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     139           9 :       if( args[i]==it->first ) { found=true; break; }
+     140             :     }
+     141           5 :     if( !found ) { fargs.push_back( args[i] ); }
+     142             :   }
+     143           1 :   interpretArgumentList( fargs, req_args ); mypdb.setArgumentNames( fargs ); requestArguments( req_args );
+     144             : 
+     145           1 :   if(nfram==0 ) error("no reference configurations were specified");
+     146           1 :   log.printf(" found %u configurations in file %s\n",nfram,ifilename.c_str() );
+     147           4 : }
+     148             : 
+     149           1 : void SketchMapRead::minimise( Matrix<double>& projections ) {
+     150             :   unsigned j=0;
+     151           3 :   for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     152         170 :     for(unsigned i=0; i<myframes.size(); ++i) projections(i,j) = it->second[i];
+     153           2 :     j++;
+     154             :   }
+     155           1 : }
+     156             : 
+     157        7056 : analysis::DataCollectionObject & SketchMapRead::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     158        7056 :   return data[idata];
+     159             : }
+     160             : 
+     161         173 : unsigned SketchMapRead::getNumberOfDataPoints() const {
+     162         173 :   return myframes.size();
+     163             : }
+     164             : 
+     165           0 : unsigned SketchMapRead::getDataPointIndexInBase( const unsigned& idata ) const {
+     166           0 :   error("cannot use read in sketch-map to out of sample project data");
+     167             :   return idata;
+     168             : }
+     169             : 
+     170           0 : std::vector<Value*> SketchMapRead::getArgumentList() {
+     171           0 :   std::vector<Value*> arglist( ActionWithArguments::getArguments() );
+     172           0 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+     173           0 :   return arglist;
+     174             : }
+     175             : 
+     176             : // Highly unsatisfactory solution to problem GAT
+     177        3486 : double SketchMapRead::getDissimilarity( const unsigned& i, const unsigned& j ) {
+     178        3486 :   plumed_assert( i<myframes.size() && j<myframes.size() );
+     179        3486 :   if( i!=j ) {
+     180             :     double dd;
+     181        3486 :     getStoredData( i, true ).transferDataToPDB( mypdb );
+     182        3486 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     183        3486 :     getStoredData( j, true ).transferDataToPDB( mypdb );
+     184        3486 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     185        3486 :     dd=distance( getPbc(), ActionWithArguments::getArguments(), myref1.get(), myref2.get(), true );
+     186             :     return dd;
+     187        3486 :   }
+     188             :   return 0.0;
+     189             : }
+     190             : 
+     191         168 : double SketchMapRead::getWeight( const unsigned& idata ) {
+     192         168 :   plumed_assert( idata<weights.size() );
+     193         168 :   return weights[idata];
+     194             : }
+     195             : 
+     196             : }
+     197             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html b/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html new file mode 100644 index 0000000000..4b8eda700b --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.func.html b/coverage/dimred/SketchMapSmacof.cpp.func.html new file mode 100644 index 0000000000..2a6283a194 --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe496createERKNS_13ActionOptionsE1
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_127SketchMapSmacofRegisterMe49D2Ev4168
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred15SketchMapSmacof8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred15SketchMapSmacofC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacofC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.gcov.html b/coverage/dimred/SketchMapSmacof.cpp.gcov.html new file mode 100644 index 0000000000..c8f6e26202 --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(SketchMapSmacof,"SKETCHMAP_SMACOF")
+      50             : 
+      51           3 : void SketchMapSmacof::registerKeywords( Keywords& keys ) {
+      52           3 :   SketchMapBase::registerKeywords( keys );
+      53           6 :   keys.add("compulsory","SMACOF_TOL","1E-4","the tolerance for each SMACOF cycle");
+      54           6 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           6 :   keys.add("compulsory","SMAP_TOL","1E-4","the tolerance for sketch-map");
+      56           6 :   keys.add("compulsory","SMAP_MAXCYC","100","maximum number of optimization cycles for iterative sketch-map algorithm");
+      57           6 :   keys.add("compulsory","REGULARISE_PARAM","0.001","this is used to ensure that we don't divide by zero when updating weights");
+      58           3 : }
+      59             : 
+      60           1 : SketchMapSmacof::SketchMapSmacof( const ActionOptions& ao ):
+      61             :   Action(ao),
+      62           1 :   SketchMapBase(ao)
+      63             : {
+      64           1 :   parse("REGULARISE_PARAM",regulariser);
+      65           2 :   parse("SMACOF_MAXCYC",max_smap); parse("SMAP_MAXCYC",maxiter);
+      66           2 :   parse("SMACOF_TOL",smap_tol); parse("SMAP_TOL",iter_tol);
+      67           1 : }
+      68             : 
+      69           1 : void SketchMapSmacof::minimise( Matrix<double>& projections ) {
+      70             :   Matrix<double> weights( distances.nrows(), distances.ncols() ); weights=0.;
+      71           1 :   double filt = recalculateWeights( projections, weights );
+      72             : 
+      73           1 :   for(unsigned i=0; i<maxiter; ++i) {
+      74           1 :     SMACOF::run( weights, distances, smap_tol, max_smap, projections );
+      75             :     // Recalculate weights matrix and sigma
+      76           1 :     double newsig = recalculateWeights( projections, weights );
+      77             :     // Test whether or not the algorithm has converged
+      78           1 :     if( std::fabs( newsig - filt )<iter_tol ) break;
+      79             :     // Make initial sigma into new sigma so that the value of new sigma is used every time so that the error can be reduced
+      80             :     filt=newsig;
+      81             :   }
+      82           1 : }
+      83             : 
+      84           2 : double SketchMapSmacof::recalculateWeights( const Matrix<double>& projections, Matrix<double>& weights ) {
+      85             :   double filt=0, totalWeight=0.;; double dr;
+      86        1000 :   for(unsigned i=1; i<weights.nrows(); ++i) {
+      87      250498 :     for(unsigned j=0; j<i; ++j) {
+      88      249500 :       double ninj=getWeight(i)*getWeight(j); totalWeight += ninj;
+      89             : 
+      90             :       double tempd=0;
+      91      748500 :       for(unsigned k=0; k<projections.ncols(); ++k) {
+      92      499000 :         double tmp = projections(i,k) - projections(j,k);
+      93      499000 :         tempd += tmp*tmp;
+      94             :       }
+      95      249500 :       double dij=std::sqrt(tempd);
+      96             : 
+      97      249500 :       double fij = transformLowDimensionalDistance( dij, dr );
+      98      249500 :       double filter=transformed(i,j)-fij;
+      99      249500 :       double diff=distances(i,j) - dij;
+     100             : 
+     101      249500 :       if( std::fabs(diff)<regulariser ) weights(i,j)=weights(j,i)=0.0;
+     102      249403 :       else weights(i,j)=weights(j,i) = ninj*( (1-mixparam)*( filter*dr )/diff + mixparam );
+     103      249500 :       filt += ninj*( (1-mixparam)*filter*filter + mixparam*diff*diff );
+     104             :     }
+     105             :   }
+     106           2 :   return filt / totalWeight;
+     107             : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html b/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html new file mode 100644 index 0000000000..45faae42d2 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.func.html b/coverage/dimred/SmacoffMDS.cpp.func.html new file mode 100644 index 0000000000..3bc9e66386 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe486createERKNS_13ActionOptionsE0
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48C2Ev4168
_ZN4PLMD6dimred12_GLOBAL__N_121SmacofMDSRegisterMe48D2Ev4168
_ZN4PLMD6dimred9SmacofMDS16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred9SmacofMDS20calculateProjectionsERKNS_6MatrixIdEERS3_0
_ZN4PLMD6dimred9SmacofMDSC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.gcov.html b/coverage/dimred/SmacoffMDS.cpp.gcov.html new file mode 100644 index 0000000000..ecc38b8ba9 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(SmacofMDS,"SMACOF_MDS")
+      49             : 
+      50           2 : void SmacofMDS::registerKeywords( Keywords& keys ) {
+      51           2 :   DimensionalityReductionBase::registerKeywords( keys );
+      52           2 :   keys.remove("NLOW_DIM");
+      53           4 :   keys.add("compulsory","SMACOF_TOL","1E-4","tolerance for the SMACOF optimization algorithm");
+      54           4 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           2 : }
+      56             : 
+      57           0 : SmacofMDS::SmacofMDS( const ActionOptions& ao):
+      58             :   Action(ao),
+      59           0 :   DimensionalityReductionBase(ao)
+      60             : {
+      61           0 :   if( !dimredbase ) error("SMACOF must be initialized using output from dimensionality reduction object");
+      62             : 
+      63           0 :   parse("SMACOF_TOL",tol); parse("SMACOF_MAXCYC",maxloops);
+      64           0 :   log.printf("  running smacof to convergence at %f or for a maximum of %u steps \n",tol,maxloops);
+      65           0 : }
+      66             : 
+      67           0 : void SmacofMDS::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+      68             :   // Take the square root of all the distances and the weights
+      69             :   Matrix<double> weights( targets.nrows(), targets.ncols() );
+      70             :   Matrix<double> distances( targets.nrows(), targets.ncols() );
+      71           0 :   for(unsigned i=1; i<distances.ncols(); ++i) {
+      72           0 :     for(unsigned j=0; j<i; ++j) {
+      73           0 :       distances(i,j)=distances(j,i)=std::sqrt( targets(i,j) );
+      74           0 :       weights(i,j)=weights(j,i)=getWeight(i)*getWeight(j);
+      75             :     }
+      76             :   }
+      77             :   // And run SMACOF
+      78           0 :   SMACOF::run( weights, targets, tol, maxloops, projections );
+      79           0 : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index-sort-f.html b/coverage/dimred/index-sort-f.html new file mode 100644 index 0000000000..fa73fd9ca6 --- /dev/null +++ b/coverage/dimred/index-sort-f.html @@ -0,0 +1,243 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:55665684.8 %
Date:2024-05-27 13:05:14Functions:7910873.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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
PCA.cpp +
80.8%80.8%
+
80.8 %97 / 12077.8 %7 / 9
SketchMapRead.cpp +
92.7%92.7%
+
92.7 %76 / 8278.6 %11 / 14
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
SketchMapConjGrad.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
SketchMapPointwise.cpp +
100.0%
+
100.0 %47 / 4785.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.16
+
+ + + diff --git a/coverage/dimred/index-sort-l.html b/coverage/dimred/index-sort-l.html new file mode 100644 index 0000000000..c184c6d3a9 --- /dev/null +++ b/coverage/dimred/index-sort-l.html @@ -0,0 +1,243 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:55665684.8 %
Date:2024-05-27 13:05:14Functions:7910873.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 / 8278.6 %11 / 14
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.16
+
+ + + diff --git a/coverage/dimred/index.html b/coverage/dimred/index.html new file mode 100644 index 0000000000..e16378fd12 --- /dev/null +++ b/coverage/dimred/index.html @@ -0,0 +1,243 @@ + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:55665684.8 %
Date:2024-05-27 13:05:14Functions:7910873.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 / 8278.6 %11 / 14
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.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func-sort-c.html b/coverage/drr/DRR.cpp.func-sort-c.html new file mode 100644 index 0000000000..b7936f0aea --- /dev/null +++ b/coverage/drr/DRR.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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:32835293.2 %
Date:2024-05-27 13:05: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
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__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
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func.html b/coverage/drr/DRR.cpp.func.html new file mode 100644 index 0000000000..58665ab853 --- /dev/null +++ b/coverage/drr/DRR.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + 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:32835293.2 %
Date:2024-05-27 13:05: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
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb36
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.gcov.html b/coverage/drr/DRR.cpp.gcov.html new file mode 100644 index 0000000000..fe9c85ba5b --- /dev/null +++ b/coverage/drr/DRR.cpp.gcov.html @@ -0,0 +1,631 @@ + + + + + + + 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:32835293.2 %
Date:2024-05-27 13:05: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);
+     164         914 :     samples[baseaddr] += nsamples;
+     165         914 :     auto it_fa = begin(forces) + baseaddr * ndims;
+     166         914 :     std::transform(begin(f), end(f), it_fa, it_fa, std::plus<double>());
+     167         914 :     return true;
+     168             :   } else {
+     169             :     return false;
+     170             :   }
+     171             : }
+     172             : 
+     173           4 : vector<DRRAxis> DRRForceGrid::merge(const vector<DRRAxis> &dA,
+     174             :                                     const vector<DRRAxis> &dB) {
+     175           4 :   vector<DRRAxis> dR(dA.size());
+     176           4 :   std::transform(begin(dA), end(dA), begin(dB), begin(dR), DRRAxis::merge);
+     177           4 :   return dR;
+     178             : }
+     179             : 
+     180             : vector<double>
+     181        1600 : DRRForceGrid::getAccumulatedForces(const vector<double> &pos) const {
+     182        1600 :   vector<double> result(ndims, 0);
+     183        1600 :   if (!isInBoundary(pos))
+     184             :     return result;
+     185         800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     186         800 :   std::copy(begin(forces) + force_addr, begin(forces) + force_addr + ndims,
+     187             :             begin(result));
+     188         800 :   return result;
+     189             : }
+     190             : 
+     191       67612 : unsigned long int DRRForceGrid::getCount(const vector<double> &pos,
+     192             :     bool SkipCheck) const {
+     193       67612 :   if (!SkipCheck) {
+     194        1600 :     if (!isInBoundary(pos)) {
+     195             :       return 0;
+     196             :     }
+     197             :   }
+     198       66812 :   return samples[sampleAddress(pos)];
+     199             : }
+     200             : 
+     201      195576 : vector<double> DRRForceGrid::getGradient(const vector<double> &pos,
+     202             :     bool SkipCheck) const {
+     203      195576 :   vector<double> result(ndims, 0);
+     204      195576 :   if (!SkipCheck) {
+     205      162000 :     if (!isInBoundary(pos)) {
+     206             :       return result;
+     207             :     }
+     208             :   }
+     209      195576 :   const size_t baseaddr = sampleAddress(pos);
+     210             :   const unsigned long int &count = samples[baseaddr];
+     211      195576 :   if (count == 0)
+     212             :     return result;
+     213      195411 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     214      195411 :   std::transform(it_fa, it_fa + ndims, begin(result),
+     215      389802 :   [&count](double fa) { return (-1.0) * fa / count; });
+     216      195411 :   return result;
+     217             : }
+     218             : 
+     219       64800 : double DRRForceGrid::getDivergence(const vector<double> &pos) const {
+     220             :   double div = 0.0;
+     221       64800 :   vector<double> grad_deriv(ndims, 0.0);
+     222       64800 :   if (!isInBoundary(pos)) {
+     223             :     return div;
+     224             :   }
+     225       64800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     226       64800 :   vector<double> grad = getGradient(pos);
+     227      194400 :   for (size_t i = 0; i < ndims; ++i) {
+     228      129600 :     const double binWidth = dimensions[i].binWidth;
+     229      129600 :     vector<double> first = pos;
+     230      129600 :     first[i] = dimensions[i].min + binWidth * 0.5;
+     231      129600 :     vector<double> last = pos;
+     232      129600 :     last[i] = dimensions[i].max - binWidth * 0.5;
+     233      129600 :     const size_t force_addr_first = sampleAddress(first) * ndims;
+     234      129600 :     const size_t force_addr_last = sampleAddress(last) * ndims;
+     235      129600 :     if (force_addr == force_addr_first) {
+     236         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     237         720 :         vector<double> next = pos;
+     238         720 :         next[i] += binWidth;
+     239         720 :         const vector<double> grad_next = getGradient(next);
+     240         720 :         const vector<double> grad_prev = getGradient(last);
+     241         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     242             :       } else {
+     243           0 :         vector<double> next = pos;
+     244           0 :         next[i] += binWidth;
+     245           0 :         vector<double> next_2 = next;
+     246           0 :         next_2[i] += binWidth;
+     247           0 :         const vector<double> grad_next = getGradient(next);
+     248           0 :         const vector<double> grad_next_2 = getGradient(next_2);
+     249           0 :         grad_deriv[i] =
+     250           0 :           (grad_next_2[i] * -1.0 + grad_next[i] * 4.0 - grad[i] * 3.0) /
+     251           0 :           (2.0 * binWidth);
+     252             :       }
+     253      128880 :     } else if (force_addr == force_addr_last) {
+     254         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     255         720 :         vector<double> prev = pos;
+     256         720 :         prev[i] -= binWidth;
+     257         720 :         const vector<double> grad_next = getGradient(first);
+     258         720 :         const vector<double> grad_prev = getGradient(prev);
+     259         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     260             :       } else {
+     261           0 :         vector<double> prev = pos;
+     262           0 :         prev[i] -= binWidth;
+     263           0 :         vector<double> prev_2 = prev;
+     264           0 :         prev_2[i] -= binWidth;
+     265           0 :         const vector<double> grad_prev = getGradient(prev);
+     266           0 :         const vector<double> grad_prev_2 = getGradient(prev_2);
+     267           0 :         grad_deriv[i] =
+     268           0 :           (grad[i] * 3.0 - grad_prev[i] * 4.0 + grad_prev_2[i] * 1.0) /
+     269           0 :           (2.0 * binWidth);
+     270             :       }
+     271             :     } else {
+     272      128160 :       vector<double> prev = pos;
+     273      128160 :       prev[i] -= binWidth;
+     274      128160 :       vector<double> next = pos;
+     275      128160 :       next[i] += binWidth;
+     276      128160 :       const vector<double> grad_next = getGradient(next);
+     277      128160 :       const vector<double> grad_prev = getGradient(prev);
+     278      128160 :       grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     279             :     }
+     280             :   }
+     281             :   div = std::accumulate(begin(grad_deriv), end(grad_deriv), 0.0);
+     282             :   return div;
+     283             : }
+     284             : 
+     285             : vector<double>
+     286      195576 : DRRForceGrid::getCountsLogDerivative(const vector<double> &pos) const {
+     287      195576 :   const size_t addr = sampleAddress(pos);
+     288      195576 :   const unsigned long int count_this = samples[addr];
+     289      195576 :   vector<double> result(ndims, 0);
+     290      585588 :   for (size_t i = 0; i < ndims; ++i) {
+     291      390012 :     const double binWidth = dimensions[i].binWidth;
+     292             :     const size_t addr_first =
+     293      390012 :       addr - shifts[i] * index1D(dimensions[i], pos[i]) + 0;
+     294      390012 :     const size_t addr_last = addr_first + shifts[i] * (dimensions[i].nbins - 1);
+     295      390012 :     if (addr == addr_first) {
+     296        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     297        2178 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     298             :         const unsigned long int &count_prev = samples[addr_last];
+     299        2178 :         if (count_next != 0 && count_prev != 0)
+     300        2160 :           result[i] =
+     301        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     302             :       } else {
+     303          32 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     304          32 :         const unsigned long int &count_next2 = samples[addr + shifts[i] * 2];
+     305          32 :         if (count_next != 0 && count_this != 0 && count_next2 != 0)
+     306           6 :           result[i] =
+     307           6 :             (std::log(count_next2) * (-1.0) + std::log(count_next) * 4.0 -
+     308           6 :              std::log(count_this) * 3.0) /
+     309           6 :             (2.0 * binWidth);
+     310             :       }
+     311      387802 :     } else if (addr == addr_last) {
+     312        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     313        2178 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     314             :         const unsigned long int &count_next = samples[addr_first];
+     315        2178 :         if (count_next != 0 && count_prev != 0)
+     316        2160 :           result[i] =
+     317        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     318             :       } else {
+     319          32 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     320          32 :         const unsigned long int &count_prev2 = samples[addr - shifts[i] * 2];
+     321          32 :         if (count_prev != 0 && count_this != 0 && count_prev2 != 0)
+     322           6 :           result[i] = (std::log(count_this) * 3.0 - std::log(count_prev) * 4.0 +
+     323           6 :                        std::log(count_prev2)) /
+     324           6 :                       (2.0 * binWidth);
+     325             :       }
+     326             :     } else {
+     327      385592 :       const unsigned long int &count_prev = samples[addr - shifts[i]];
+     328      385592 :       const unsigned long int &count_next = samples[addr + shifts[i]];
+     329      385592 :       if (count_next != 0 && count_prev != 0)
+     330      385432 :         result[i] =
+     331      385432 :           (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     332             :     }
+     333             :   }
+     334      195576 :   return result;
+     335             : }
+     336             : 
+     337          26 : void DRRForceGrid::write1DPMF(string filename) const {
+     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 :   const string countname = filename + suffix + ".count";
+     356          36 :   const 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 :   const 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:: writeZCountZGrad(const string &filename, bool addition) const {
+     513          18 :   const string countname = filename + ".zcount";
+     514          18 :   const string gradname = filename + ".zgrad";
+     515          18 :   vector<double> pos(ndims, 0);
+     516             :   FILE *pCount;
+     517             :   FILE *pGrad;
+     518          18 :   if (addition) {
+     519           4 :     pCount = fopen(countname.c_str(), "a");
+     520           4 :     pGrad = fopen(gradname.c_str(), "a");
+     521             :   } else {
+     522          14 :     pCount = fopen(countname.c_str(), "w");
+     523          14 :     pGrad = fopen(gradname.c_str(), "w");
+     524             :   }
+     525          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     526          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     527       33024 :   for (size_t i = 0; i < sampleSize; ++i) {
+     528       98448 :     for (size_t j = 0; j < ndims; ++j) {
+     529       65442 :       pos[j] = table[j][i];
+     530       65442 :       fprintf(pCount, " %.9f", table[j][i]);
+     531       65442 :       fprintf(pGrad, " %.9f", table[j][i]);
+     532             :     }
+     533       33006 :     const size_t baseaddr = sampleAddress(pos);
+     534             :     const auto& current_sample = samples[baseaddr];
+     535       33006 :     fprintf(pCount, " %lu\n", current_sample);
+     536       33006 :     if (current_sample == 0) {
+     537         195 :       for (size_t j = 0; j < ndims; ++j) {
+     538             :         fprintf(pGrad, " %.9f", 0.0);
+     539             :       }
+     540             :     } else {
+     541       98253 :       for (size_t j = 0; j < ndims; ++j) {
+     542       65332 :         const double grad = -1.0 * forces[baseaddr * ndims + j] / current_sample;
+     543       65332 :         fprintf(pGrad, " %.9f", grad / outputunit);
+     544             :       }
+     545             :     }
+     546             :     fprintf(pGrad, "\n");
+     547             :   }
+     548          18 :   fclose(pCount);
+     549          18 :   fclose(pGrad);
+     550          18 : }
+     551             : 
+     552             : }
+     553             : }
+     554             : 
+     555             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.func-sort-c.html b/coverage/drr/DRR.h.func-sort-c.html new file mode 100644 index 0000000000..b9ffecde7e --- /dev/null +++ b/coverage/drr/DRR.h.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/drr/DRR.h.func.html b/coverage/drr/DRR.h.func.html new file mode 100644 index 0000000000..f59f336b44 --- /dev/null +++ b/coverage/drr/DRR.h.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/drr/DRR.h.gcov.html b/coverage/drr/DRR.h.gcov.html new file mode 100644 index 0000000000..4c77231b50 --- /dev/null +++ b/coverage/drr/DRR.h.gcov.html @@ -0,0 +1,434 @@ + + + + + + + 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-05-27 13:05: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         228 :   virtual ~DRRForceGrid() {}
+     206             : 
+     207             : protected:
+     208             :   /// The output suffix appended before .grad(.czar.grad) and
+     209             :   /// .count(.czar.count)
+     210             :   string suffix;
+     211             :   /// Number of dimensions
+     212             :   size_t ndims;
+     213             :   /// Store each axes
+     214             :   vector<DRRAxis> dimensions;
+     215             :   /// Size of samples
+     216             :   size_t sampleSize;
+     217             :   /// The header lines of .grad and .count files
+     218             :   string headers;
+     219             :   /// A table stores the middle points of all dimensions.
+     220             :   /// For output in .grad and .count files
+     221             :   vector<vector<double>> table;
+     222             :   /// Store the average force of each bins
+     223             :   vector<double> forces;
+     224             :   /// Store counts of each bins
+     225             :   vector<unsigned long int> samples;
+     226             :   /// Only for 1D pmf output
+     227             :   vector<double> endpoints;
+     228             :   /// For faster indexing
+     229             :   /// shifts[0] = 1, shifts[n+1] = shifts[n] * dimensions[n].nbins
+     230             :   vector<size_t> shifts;
+     231             :   /// For set different output units
+     232             :   double outputunit;
+     233             : 
+     234             :   /// Miscellaneous helper functions
+     235             :   static size_t index1D(const DRRAxis &c, double x);
+     236             :   void fillTable(const vector<vector<double>> &in);
+     237             : 
+     238             :   /// Boost serialization functions
+     239             :   friend class boost::serialization::access;
+     240             :   template <class Archive>
+     241          38 :   void save(Archive &ar, const unsigned int version) const {
+     242             :     // Don't save all members.
+     243          38 :     ar << suffix;
+     244          38 :     ar << dimensions;
+     245          38 :     ar << forces;
+     246          38 :     ar << samples;
+     247          38 :   }
+     248          16 :   template <class Archive> void load(Archive &ar, const unsigned int version) {
+     249          16 :     ar >> suffix;
+     250          16 :     ar >> dimensions;
+     251          16 :     ar >> forces;
+     252          16 :     ar >> samples;
+     253             :     // Restore other members.
+     254          16 :     ndims = dimensions.size();
+     255          16 :     sampleSize = samples.size();
+     256          16 :     std::stringstream ss;
+     257          16 :     ss << "# " << ndims << '\n';
+     258          16 :     vector<vector<double>> mp(ndims);
+     259          16 :     shifts.resize(ndims, 0);
+     260          16 :     shifts[0] = 1;
+     261          38 :     for (size_t i = 0; i < ndims; ++i) {
+     262          22 :       mp[i] = dimensions[i].getMiddlePoints();
+     263          22 :       if (i > 0) {
+     264           6 :         shifts[i] = shifts[i - 1] * dimensions[i - 1].nbins;
+     265             :       }
+     266             :       ss.precision(std::numeric_limits<double>::max_digits10);
+     267          44 :       ss << std::fixed << "# " << dimensions[i].min << ' '
+     268          44 :          << dimensions[i].binWidth << ' ' << dimensions[i].nbins;
+     269          22 :       if (dimensions[i].isPeriodic())
+     270          24 :         ss << " 1" << '\n';
+     271             :       else
+     272          20 :         ss << " 0" << '\n';
+     273             :     }
+     274          16 :     fillTable(mp);
+     275          16 :     headers = ss.str();
+     276          16 :     outputunit = 1.0;
+     277             :     // For 1D pmf
+     278          16 :     if (ndims == 1) {
+     279          10 :       endpoints.resize(dimensions[0].nbins + 1, 0);
+     280          10 :       double ep = dimensions[0].min;
+     281          10 :       double stride = dimensions[0].binWidth;
+     282        1020 :       for (auto it = begin(endpoints); it != end(endpoints); ++it) {
+     283        1010 :         (*it) = ep;
+     284        1010 :         ep += stride;
+     285             :       }
+     286             :     }
+     287          16 :   }
+     288             :   template <typename Archive>
+     289             :   void serialize(Archive &ar, const unsigned int version) {
+     290             :     boost::serialization::split_member(ar, *this, version);
+     291             :   }
+     292             : };
+     293             : 
+     294             : class ABF : public DRRForceGrid {
+     295             : public:
+     296          16 :   ABF() {}
+     297           2 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     298             :       double fullSamples = 500.0, double maxFactor = 1.0,
+     299             :       bool initializeTable = true)
+     300           2 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     301           2 :       mFullSamples(fullSamples), mMaxFactors(p_dimensions.size(), maxFactor) {}
+     302          11 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     303             :       double fullSamples, const vector<double>& maxFactors,
+     304             :       bool initializeTable = true)
+     305          11 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     306          11 :       mFullSamples(fullSamples), mMaxFactors(maxFactors) {}
+     307             :   // Provide a setter for ABF parametres (fullsamples, maxfactor)
+     308             :   void setParameters(double fullSamples, const vector<double>& maxFactors) {
+     309           1 :     mFullSamples = fullSamples;
+     310           1 :     mMaxFactors = maxFactors;
+     311           1 :   }
+     312             :   // Store the "instantaneous" spring force of a point and get ABF bias forces.
+     313             :   bool store_getbias(const vector<double> &pos,
+     314             :                      const vector<double> &f,
+     315             :                      vector<double> &fbias);
+     316             :   static ABF mergewindow(const ABF &aWA, const ABF &aWB);
+     317          38 :   ~ABF() {}
+     318             : 
+     319             : private:
+     320             :   // Parametres for calculate bias force
+     321             :   double mFullSamples;
+     322             :   vector<double> mMaxFactors;
+     323             :   // Boost serialization
+     324             :   friend class boost::serialization::access;
+     325             :   template <typename Archive>
+     326             :   void serialize(Archive &ar, const unsigned int version) {
+     327          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     328             :   }
+     329             : };
+     330             : 
+     331          28 : class CZAR : public DRRForceGrid {
+     332             : public:
+     333          16 :   CZAR() : kbt(0) {}
+     334             :   CZAR(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     335             :        double p_kbt, bool initializeTable = true)
+     336          13 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable), kbt(p_kbt) {}
+     337             :   vector<double> getGradient(const vector<double> &pos,
+     338             :                              bool SkipCheck = false) const;
+     339             :   double getkbt() const { return kbt; }
+     340             :   void setkbt(double p_kbt) { kbt = p_kbt; }
+     341             :   static CZAR mergewindow(const CZAR &cWA, const CZAR &cWB);
+     342             :   void writeZCountZGrad(const string &filename, bool addition = false) const;
+     343          23 :   ~CZAR() {}
+     344             : 
+     345             : private:
+     346             :   double kbt;
+     347             :   friend class boost::serialization::access;
+     348             :   template <typename Archive>
+     349          27 :   void serialize(Archive &ar, const unsigned int version) {
+     350          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     351          27 :     ar &kbt;
+     352          27 :   }
+     353             : };
+     354             : }
+     355             : }
+     356             : 
+     357             : #endif
+     358             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html new file mode 100644 index 0000000000..9a144b0261 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_140DynamicReferenceRestrainingRegisterMe2456createERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe245C2Ev4168
_ZN4PLMD3drr12_GLOBAL__N_140DynamicReferenceRestrainingRegisterMe245D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func.html b/coverage/drr/DynamicReferenceRestraining.cpp.func.html new file mode 100644 index 0000000000..15ccad11ed --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev4168
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev4168
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE4168
_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.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.gcov.html b/coverage/drr/drrtool.cpp.gcov.html new file mode 100644 index 0000000000..024660fdda --- /dev/null +++ b/coverage/drr/drrtool.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + 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-05-27 13:05: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       12513 : PLUMED_REGISTER_CLTOOL(drrtool, "drr_tool")
+      90             : 
+      91        4168 : void drrtool::registerKeywords(Keywords &keys) {
+      92        4168 :   CLTool::registerKeywords(keys);
+      93        8336 :   keys.add("optional", "--extract", "Extract drrstate file(s)");
+      94        8336 :   keys.add("optional", "--merge", "Merge eABF windows");
+      95        8336 :   keys.add("optional", "--merge_output", "The output filename of the merged result");
+      96        8336 :   keys.add("optional", "--divergence", "Calculate divergence of gradient field (experimental)");
+      97        8336 :   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        8336 :   keys.addFlag("-v", false, "Verbose output");
+      99        4168 : }
+     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.resize(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.writeZCountZGrad(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.resize(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.writeZCountZGrad(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.resize(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.16
+
+ + + diff --git a/coverage/drr/index-sort-f.html b/coverage/drr/index-sort-f.html new file mode 100644 index 0000000000..7c29ff7cbd --- /dev/null +++ b/coverage/drr/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1194126694.3 %
Date:2024-05-27 13:05: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.2%93.2%
+
93.2 %328 / 35296.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.16
+
+ + + diff --git a/coverage/drr/index-sort-l.html b/coverage/drr/index-sort-l.html new file mode 100644 index 0000000000..3f36829566 --- /dev/null +++ b/coverage/drr/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1194126694.3 %
Date:2024-05-27 13:05: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.2%93.2%
+
93.2 %328 / 35296.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.16
+
+ + + diff --git a/coverage/drr/index.html b/coverage/drr/index.html new file mode 100644 index 0000000000..cd83cfa350 --- /dev/null +++ b/coverage/drr/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1194126694.3 %
Date:2024-05-27 13:05:14Functions:929794.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.cpp +
93.2%93.2%
+
93.2 %328 / 35296.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.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func-sort-c.html b/coverage/eds/EDS.cpp.func-sort-c.html new file mode 100644 index 0000000000..0e87212b54 --- /dev/null +++ b/coverage/eds/EDS.cpp.func-sort-c.html @@ -0,0 +1,164 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280C2Ev4168
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func.html b/coverage/eds/EDS.cpp.func.html new file mode 100644 index 0000000000..90f6310804 --- /dev/null +++ b/coverage/eds/EDS.cpp.func.html @@ -0,0 +1,164 @@ + + + + + + + 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-05-27 13:05:14Functions:202387.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe2806createERKNS_13ActionOptionsE8
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280C2Ev4168
_ZN4PLMD3eds12_GLOBAL__N_116EDSRegisterMe280D2Ev4168
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDS17calc_lm_step_sizeEv1
_ZN4PLMD3eds3EDS17turnOnDerivativesEv0
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS18calc_ssd_step_sizeEv6
_ZN4PLMD3eds3EDS20calc_covar_step_sizeEv1
_ZN4PLMD3eds3EDS20update_pseudo_virialEv2
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDSD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.gcov.html b/coverage/eds/EDS.cpp.gcov.html new file mode 100644 index 0000000000..bcb31c52e8 --- /dev/null +++ b/coverage/eds/EDS.cpp.gcov.html @@ -0,0 +1,1256 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(EDS, "EDS")
+     281             : 
+     282          10 : void EDS::registerKeywords(Keywords &keys)
+     283             : {
+     284          10 :   Bias::registerKeywords(keys);
+     285          10 :   keys.use("ARG");
+     286          20 :   keys.add("optional", "CENTER", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. This is for fixed centers");
+     287          20 :   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          20 :   keys.add("optional", "PERIOD", "Steps over which to adjust bias for adaptive or ramping");
+     291          20 :   keys.add("compulsory", "RANGE", "25.0", "The (starting) maximum increase in coupling constant per PERIOD (in \\f$k_B T\\f$/[BIAS_SCALE unit]) for each CV biased");
+     292          20 :   keys.add("compulsory", "SEED", "0", "Seed for random order of changing bias");
+     293          20 :   keys.add("compulsory", "INIT", "0", "Starting value for coupling constant");
+     294          20 :   keys.add("compulsory", "FIXED", "0", "Fixed target values for coupling constant. Non-adaptive.");
+     295          20 :   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          20 :   keys.add("optional", "TEMP", "The system temperature. If not provided will be taken from MD code (if available)");
+     298          20 :   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          20 :   keys.add("optional", "VIRIAL", "Add an update penalty for having non-zero virial contributions. Only makes sense with multiple correlated CVs.");
+     302          20 :   keys.add("optional", "LOGWEIGHTS", "Add weights to use for computing statistics. For example, if biasing with metadynamics.");
+     303          20 :   keys.addFlag("LM", false, "Use Levenberg-Marquadt algorithm along with simultaneous keyword. Otherwise use gradient descent.");
+     304          20 :   keys.add("compulsory", "LM_MIXING", "1", "Initial mixing parameter when using Levenberg-Marquadt minimization.");
+     305          20 :   keys.add("optional", "RESTART_FMT", "the format that should be used to output real numbers in EDS restarts");
+     306          20 :   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          20 :   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          20 :   keys.addFlag("RAMP", false, "Slowly increase bias constant to a fixed value");
+     314          20 :   keys.addFlag("COVAR", false, "Utilize the covariance matrix when updating the bias. Default Off, but may be enabled due to other options");
+     315          20 :   keys.addFlag("FREEZE", false, "Fix bias at current level (only used for restarting).");
+     316          20 :   keys.addFlag("MEAN", false, "Instead of using final bias level from restart, use average. Can only be used in conjunction with FREEZE");
+     317             : 
+     318          10 :   keys.use("RESTART");
+     319             : 
+     320          20 :   keys.addOutputComponent("force2", "default", "squared value of force from the bias");
+     321          20 :   keys.addOutputComponent("pressure", "default", "If using virial keyword, this is the current sum of virial terms. It is in units of pressure (energy / vol^3)");
+     322          20 :   keys.addOutputComponent("_coupling", "default", "For each named CV biased, there will be a corresponding output CV_coupling storing the current linear bias prefactor.");
+     323          10 : }
+     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          16 :   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.16
+
+ + + diff --git a/coverage/eds/index-sort-f.html b/coverage/eds/index-sort-f.html new file mode 100644 index 0000000000..75aca355e0 --- /dev/null +++ b/coverage/eds/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45248892.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/eds/index-sort-l.html b/coverage/eds/index-sort-l.html new file mode 100644 index 0000000000..2a0258ef83 --- /dev/null +++ b/coverage/eds/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45248892.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/eds/index.html b/coverage/eds/index.html new file mode 100644 index 0000000000..2aebe21a5d --- /dev/null +++ b/coverage/eds/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45248892.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/emerald.png b/coverage/emerald.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad4f4068b935643d2486f323005fb294a9bd7e GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^Jb!lvI6;R0X`wF(yt=9xVZRt1vCRixIA4P dLn>}1Cji+@42)0J?}79&c)I$ztaD0e0sy@GAL0N2 literal 0 HcmV?d00001 diff --git a/coverage/fisst/FISST.cpp.func-sort-c.html b/coverage/fisst/FISST.cpp.func-sort-c.html new file mode 100644 index 0000000000..dd35104a37 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167C2Ev4168
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.func.html b/coverage/fisst/FISST.cpp.func.html new file mode 100644 index 0000000000..5c8f9927da --- /dev/null +++ b/coverage/fisst/FISST.cpp.func.html @@ -0,0 +1,160 @@ + + + + + + + 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-05-27 13:05:14Functions:182281.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe1676createERKNS_13ActionOptionsE2
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167C2Ev4168
_ZN4PLMD5fisst12_GLOBAL__N_118FISSTRegisterMe167D2Ev4168
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISSTD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.gcov.html b/coverage/fisst/FISST.cpp.gcov.html new file mode 100644 index 0000000000..7465917ac0 --- /dev/null +++ b/coverage/fisst/FISST.cpp.gcov.html @@ -0,0 +1,738 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(FISST,"FISST")
+     168             : 
+     169           4 : void FISST::registerKeywords(Keywords& keys) {
+     170           4 :   Bias::registerKeywords(keys);
+     171           4 :   keys.use("ARG");
+     172           8 :   keys.add("compulsory","PERIOD","Steps corresponding to the learning rate");
+     173           8 :   keys.add("optional","RESET_PERIOD","Reset the learning statistics every time this number of steps comes around.");
+     174           8 :   keys.add("compulsory","NINTERPOLATE","Number of grid points on which to do interpolation.");
+     175           8 :   keys.add("compulsory","MIN_FORCE","Minimum force (per CV) to use for sampling. Units: [Energy]/[CV]  (can be negative).");
+     176           8 :   keys.add("compulsory","MAX_FORCE","Maximum force (per CV) to use for sampling.");
+     177           8 :   keys.add("compulsory","CENTER","0","The CV value at which the applied bias energy will be zero");
+     178           8 :   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           8 :   keys.add("optional","INITIAL_WEIGHT_DIST","Starting distribution for the force weights (options: UNIFORM, EXP, GAUSS).");
+     181           8 :   keys.add("optional","INITIAL_WEIGHT_RATE","Rate of decay for exponential and gaussian distributions. W(F)~exp(-r |F|^d).");
+     182             : 
+     183           8 :   keys.add("optional","RESTART_FMT","the format that should be used to output real numbers in FISST restarts.");
+     184           8 :   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           8 :   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           8 :   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           8 :   keys.add("optional","OBSERVABLE_FREQ","How often to write out observable weights (default=period).");
+     194           8 :   keys.addFlag("FREEZE",false,"Fix bias weights at current level (only used for restarting).");
+     195           4 :   keys.use("RESTART");
+     196           8 :   keys.addOutputComponent("force2","default","squared value of force from the bias.");
+     197           8 :   keys.addOutputComponent("_fbar","default", "For each named CV biased, there will be a corresponding output CV_fbar storing the current linear bias prefactor.");
+     198           4 : }
+     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.16
+
+ + + diff --git a/coverage/fisst/index-sort-f.html b/coverage/fisst/index-sort-f.html new file mode 100644 index 0000000000..c97fbbe135 --- /dev/null +++ b/coverage/fisst/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/fisst/index-sort-l.html b/coverage/fisst/index-sort-l.html new file mode 100644 index 0000000000..636945f34c --- /dev/null +++ b/coverage/fisst/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/fisst/index.html b/coverage/fisst/index.html new file mode 100644 index 0000000000..f569ba695f --- /dev/null +++ b/coverage/fisst/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html new file mode 100644 index 0000000000..88d21d38e5 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func.html b/coverage/fisst/legendre_rule_fast.cpp.func.html new file mode 100644 index 0000000000..d75596f1f7 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.gcov.html b/coverage/fisst/legendre_rule_fast.cpp.gcov.html new file mode 100644 index 0000000000..e9b76a04f3 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.gcov.html @@ -0,0 +1,641 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func-sort-c.html b/coverage/function/Combine.cpp.func-sort-c.html new file mode 100644 index 0000000000..b30b39815e --- /dev/null +++ b/coverage/function/Combine.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe906createERKNS_13ActionOptionsE137
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE137
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE139
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90D2Ev4168
_ZN4PLMD8function7Combine9calculateEv7887
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func.html b/coverage/function/Combine.cpp.func.html new file mode 100644 index 0000000000..315138e576 --- /dev/null +++ b/coverage/function/Combine.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe906createERKNS_13ActionOptionsE137
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CombineRegisterMe90D2Ev4168
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE139
_ZN4PLMD8function7Combine9calculateEv7887
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE137
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.gcov.html b/coverage/function/Combine.cpp.gcov.html new file mode 100644 index 0000000000..0e38f1709e --- /dev/null +++ b/coverage/function/Combine.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-05-27 13:05: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       12775 : PLUMED_REGISTER_ACTION(Combine,"COMBINE")
+      91             : 
+      92         139 : void Combine::registerKeywords(Keywords& keys) {
+      93         139 :   Function::registerKeywords(keys);
+      94         278 :   keys.use("ARG"); keys.use("PERIODIC");
+      95         278 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients of the arguments in your function");
+      96         278 :   keys.add("compulsory","PARAMETERS","0.0","the parameters of the arguments in your function");
+      97         278 :   keys.add("compulsory","POWERS","1.0","the powers to which you are raising each of the arguments in your function");
+      98         278 :   keys.addFlag("NORMALIZE",false,"normalize all the coefficients so that in total they are equal to one");
+      99         139 : }
+     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.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func-sort-c.html b/coverage/function/Custom.cpp.func-sort-c.html new file mode 100644 index 0000000000..dc24b2e155 --- /dev/null +++ b/coverage/function/Custom.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe1796createERKNS_13ActionOptionsE47
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe2116createERKNS_13ActionOptionsE387
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE434
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE438
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179D2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe211C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe211D2Ev4168
_ZN4PLMD8function6Custom9calculateEv39154
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func.html b/coverage/function/Custom.cpp.func.html new file mode 100644 index 0000000000..c191cd687f --- /dev/null +++ b/coverage/function/Custom.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe1796createERKNS_13ActionOptionsE47
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe179D2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe2116createERKNS_13ActionOptionsE387
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe211C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119CustomRegisterMe211D2Ev4168
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE438
_ZN4PLMD8function6Custom9calculateEv39154
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE434
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.gcov.html b/coverage/function/Custom.cpp.gcov.html new file mode 100644 index 0000000000..1a09dc5b80 --- /dev/null +++ b/coverage/function/Custom.cpp.gcov.html @@ -0,0 +1,376 @@ + + + + + + + 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-05-27 13:05: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       12598 : PLUMED_REGISTER_ACTION(Custom,"CUSTOM")
+     180             : 
+     181             : //+PLUMEDOC FUNCTION MATHEVAL
+     182             : /*
+     183             : An alias to the CUSTOM function that can also be used to calaculate combinations of variables using a custom expression.
+     184             : 
+     185             : Documentation for this action is identical to that for \ref CUSTOM
+     186             : 
+     187             : This alias is kept in order to maintain compatibility with previous PLUMED versions.
+     188             : However, notice that as of PLUMED 2.5 the libmatheval library is not linked anymore,
+     189             : and the \ref MATHEVAL function is implemented using the Lepton library.
+     190             : 
+     191             : \par Examples
+     192             : 
+     193             : Just replace \ref CUSTOM with \ref MATHEVAL.
+     194             : 
+     195             : \plumedfile
+     196             : d: DISTANCE ATOMS=10,15
+     197             : m: MATHEVAL ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+     198             : # check the function you are applying:
+     199             : PRINT ARG=d,m FILE=checkme
+     200             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     201             : \endplumedfile
+     202             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     203             : 
+     204             : */
+     205             : //+ENDPLUMEDOC
+     206             : 
+     207             : class Matheval :
+     208             :   public Custom {
+     209             : };
+     210             : 
+     211       13278 : PLUMED_REGISTER_ACTION(Custom,"MATHEVAL")
+     212             : 
+     213         438 : void Custom::registerKeywords(Keywords& keys) {
+     214         438 :   Function::registerKeywords(keys);
+     215         876 :   keys.use("ARG"); keys.use("PERIODIC");
+     216         876 :   keys.add("compulsory","FUNC","the function you wish to evaluate");
+     217         876 :   keys.add("optional","VAR","the names to give each of the arguments in the function.  If you have up to three arguments in your function you can use x, y and z to refer to them.  Otherwise you must use this flag to give your variables names.");
+     218         438 : }
+     219             : 
+     220         434 : Custom::Custom(const ActionOptions&ao):
+     221             :   Action(ao),
+     222             :   Function(ao),
+     223         434 :   expression_deriv(getNumberOfArguments()),
+     224         434 :   values(getNumberOfArguments()),
+     225         434 :   names(getNumberOfArguments()),
+     226         434 :   lepton_ref(getNumberOfArguments(),nullptr),
+     227        1302 :   lepton_ref_deriv(getNumberOfArguments()*getNumberOfArguments(),nullptr)
+     228             : {
+     229         868 :   parseVector("VAR",var);
+     230         434 :   if(var.size()==0) {
+     231         421 :     var.resize(getNumberOfArguments());
+     232         421 :     if(getNumberOfArguments()>3)
+     233           0 :       error("Using more than 3 arguments you should explicitly write their names with VAR");
+     234         421 :     if(var.size()>0) var[0]="x";
+     235         421 :     if(var.size()>1) var[1]="y";
+     236         421 :     if(var.size()>2) var[2]="z";
+     237             :   }
+     238         434 :   if(var.size()!=getNumberOfArguments())
+     239           0 :     error("Size of VAR array should be the same as number of arguments");
+     240         434 :   parse("FUNC",func);
+     241         434 :   addValueWithDerivatives();
+     242         434 :   checkRead();
+     243             : 
+     244         434 :   log.printf("  with function : %s\n",func.c_str());
+     245         434 :   log.printf("  with variables :");
+     246         968 :   for(unsigned i=0; i<var.size(); i++) log.printf(" %s",var[i].c_str());
+     247         434 :   log.printf("\n");
+     248             : 
+     249         434 :   lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants());
+     250         434 :   log<<"  function as parsed by lepton: "<<pe<<"\n";
+     251         434 :   expression=pe.createCompiledExpression();
+     252         942 :   for(auto &p: expression.getVariables()) {
+     253         508 :     if(std::find(var.begin(),var.end(),p)==var.end()) {
+     254           0 :       error("variable " + p + " is not defined");
+     255             :     }
+     256             :   }
+     257         434 :   log<<"  derivatives as computed by lepton:\n";
+     258         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     259        1068 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(lepton::Constants());
+     260         534 :     log<<"    "<<pe<<"\n";
+     261         534 :     expression_deriv[i]=pe.createCompiledExpression();
+     262             :   }
+     263             : 
+     264         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     265             :     try {
+     266         534 :       lepton_ref[i]=&expression.getVariableReference(var[i]);
+     267          26 :     } catch(const PLMD::lepton::Exception& exc) {
+     268             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     269             : // e.g. func=0*x
+     270          26 :     }
+     271             :   }
+     272         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     273        1526 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     274             :       try {
+     275         992 :         lepton_ref_deriv[i*getNumberOfArguments()+j]=&expression_deriv[i].getVariableReference(var[j]);
+     276         513 :       } catch(const PLMD::lepton::Exception& exc) {
+     277             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     278             : // e.g. func=0*x
+     279         513 :       }
+     280             :     }
+     281             :   }
+     282         434 : }
+     283             : 
+     284       39154 : void Custom::calculate() {
+     285       78949 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     286       39795 :     if(lepton_ref[i]) *lepton_ref[i]=getArgument(i);
+     287             :   }
+     288       39154 :   setValue(expression.evaluate());
+     289       78949 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     290       82348 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     291       42553 :       if(lepton_ref_deriv[i*getNumberOfArguments()+j]) *lepton_ref_deriv[i*getNumberOfArguments()+j]=getArgument(j);
+     292             :     }
+     293       39795 :     setDerivative(i,expression_deriv[i].evaluate());
+     294             :   }
+     295       39154 : }
+     296             : 
+     297             : }
+     298             : }
+     299             : 
+     300             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func-sort-c.html b/coverage/function/Ensemble.cpp.func-sort-c.html new file mode 100644 index 0000000000..4927a69cc1 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe716createERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func.html b/coverage/function/Ensemble.cpp.func.html new file mode 100644 index 0000000000..c12f1f801a --- /dev/null +++ b/coverage/function/Ensemble.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe716createERKNS_13ActionOptionsE27
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_120EnsembleRegisterMe71D2Ev4168
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.gcov.html b/coverage/function/Ensemble.cpp.gcov.html new file mode 100644 index 0000000000..d800f7f25e --- /dev/null +++ b/coverage/function/Ensemble.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + 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-05-27 13:05: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       12558 : PLUMED_REGISTER_ACTION(Ensemble,"ENSEMBLE")
+      72             : 
+      73          29 : void Ensemble::registerKeywords(Keywords& keys) {
+      74          29 :   Function::registerKeywords(keys);
+      75          29 :   keys.use("ARG");
+      76          58 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+      77          58 :   keys.addFlag("CENTRAL",false,"calculate a central moment instead of a standard moment");
+      78          58 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are reweighting");
+      79          58 :   keys.add("optional","MOMENT","the moment you want to calculate in alternative to the mean or the variance");
+      80          58 :   keys.add("optional","POWER","the power of the mean (and moment)");
+      81          29 :   ActionWithValue::useCustomisableComponents(keys);
+      82          29 : }
+      83             : 
+      84          27 : Ensemble::Ensemble(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   Function(ao),
+      87          27 :   do_reweight(false),
+      88          27 :   do_moments(false),
+      89          27 :   do_central(false),
+      90          27 :   do_powers(false),
+      91          27 :   kbt(-1.0),
+      92          27 :   moment(0),
+      93          27 :   power(0)
+      94             : {
+      95          27 :   parseFlag("REWEIGHT", do_reweight);
+      96          27 :   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.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func-sort-c.html b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html new file mode 100644 index 0000000000..1f0e26cb7a --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe1266createERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe126C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_128FuncPathGeneralRegisterMe126D2Ev4168
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func.html b/coverage/function/FuncPathGeneral.cpp.func.html new file mode 100644 index 0000000000..49a5d1ee92 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe2186createERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.func.html b/coverage/function/FuncPathMSD.cpp.func.html new file mode 100644 index 0000000000..da8cacae5d --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe2186createERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_124FuncPathMSDRegisterMe218D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.gcov.html b/coverage/function/FuncPathMSD.cpp.gcov.html new file mode 100644 index 0000000000..38e958c1df --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.gcov.html @@ -0,0 +1,444 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(FuncPathMSD,"FUNCPATHMSD")
+     219             : 
+     220           4 : void FuncPathMSD::registerKeywords(Keywords& keys) {
+     221           4 :   Function::registerKeywords(keys);
+     222           4 :   keys.use("ARG");
+     223           8 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+     224           8 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+     225           8 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+     226           4 :   componentsAreNotOptional(keys);
+     227           8 :   keys.addOutputComponent("s","default","the position on the path");
+     228           8 :   keys.addOutputComponent("z","default","the distance from the path");
+     229           4 : }
+     230           2 : FuncPathMSD::FuncPathMSD(const ActionOptions&ao):
+     231             :   Action(ao),
+     232             :   Function(ao),
+     233           2 :   neigh_size(-1),
+     234           2 :   neigh_stride(-1.)
+     235             : {
+     236             : 
+     237           2 :   parse("LAMBDA",lambda);
+     238           2 :   parse("NEIGH_SIZE",neigh_size);
+     239           2 :   parse("NEIGH_STRIDE",neigh_stride);
+     240           2 :   checkRead();
+     241           2 :   log.printf("  lambda is %f\n",lambda);
+     242             :   // list the action involved and check the type
+     243           2 :   std::string myname=getPntrToArgument(0)->getPntrToAction()->getName();
+     244           2 :   if(myname!="RMSD"&&myname!="CONTACTMAP"&&myname!="DISTANCE"&&myname!="PIV") error("One or more of your arguments is not of RMSD/CONTACTMAP/DISTANCE/PIV type!!!");
+     245           6 :   for(unsigned i=1; i<getNumberOfArguments(); i++) {
+     246             :     // for each value get the name and the label of the corresponding action
+     247           4 :     if( getPntrToArgument(i)->getPntrToAction()->getName()!=myname ) error("mismatch between the types of arguments");
+     248             :   }
+     249           2 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     250             :   // do some neighbor printout
+     251           2 :   if(neigh_stride>0. || neigh_size>0) {
+     252           1 :     if(neigh_size>static_cast<int>(getNumberOfArguments())) {
+     253           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n",neigh_size,getNumberOfArguments());
+     254           0 :       neigh_size=getNumberOfArguments();
+     255             :     }
+     256           1 :     log.printf("  Neighbor list enabled: \n");
+     257           1 :     log.printf("                size   :  %d elements\n",neigh_size);
+     258           1 :     log.printf("                stride :  %f time \n",neigh_stride);
+     259             :   } else {
+     260           1 :     log.printf("  Neighbor list NOT enabled \n");
+     261             :   }
+     262             : 
+     263           4 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     264           4 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     265             : 
+     266             :   // now backup the arguments
+     267           8 :   for(unsigned i=0; i<getNumberOfArguments(); i++)allArguments.push_back(getPntrToArgument(i));
+     268             :   double i=1.;
+     269           8 :   for(const auto & it : allArguments) {
+     270           6 :     indexmap[it]=i; i+=1.;
+     271             :   }
+     272             : 
+     273           2 : }
+     274             : // calculator
+     275        1092 : void FuncPathMSD::calculate() {
+     276             : // log.printf("NOW CALCULATE! \n");
+     277             :   double s_path=0.;
+     278             :   double partition=0.;
+     279        1092 :   if(neighpair.empty()) { // at first step, resize it
+     280           0 :     neighpair.resize(allArguments.size());
+     281           0 :     for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     282             :   }
+     283             : 
+     284        1092 :   Value* val_s_path=getPntrToComponent("s");
+     285        2184 :   Value* val_z_path=getPntrToComponent("z");
+     286             : 
+     287        3959 :   for(auto & it : neighpair) {
+     288        2867 :     it.second=std::exp(-lambda*(it.first->get()));
+     289        2867 :     s_path+=(indexmap[it.first])*it.second;
+     290        2867 :     partition+=it.second;
+     291             :   }
+     292        1092 :   s_path/=partition;
+     293             :   val_s_path->set(s_path);
+     294        1092 :   val_z_path->set(-(1./lambda)*std::log(partition));
+     295             :   int n=0;
+     296        3959 :   for(const auto & it : neighpair) {
+     297        2867 :     double expval=it.second;
+     298        2867 :     double tmp=lambda*expval*(s_path-(indexmap[it.first]))/partition;
+     299             :     setDerivative(val_s_path,n,tmp);
+     300        2867 :     setDerivative(val_z_path,n,expval/partition);
+     301        2867 :     n++;
+     302             :   }
+     303             : 
+     304             : //  log.printf("CALCULATION DONE! \n");
+     305        1092 : }
+     306             : ///
+     307             : /// this function updates the needed argument list
+     308             : ///
+     309        1092 : void FuncPathMSD::prepare() {
+     310             : 
+     311             :   // neighbor list: rank and activate the chain for the next step
+     312             : 
+     313             :   // neighbor list: if neigh_size<0 never sort and keep the full vector
+     314             :   // neighbor list: if neigh_size>0
+     315             :   //                if the size is full -> sort the vector and decide the dependencies for next step
+     316             :   //                if the size is not full -> check if next step will need the full dependency otherwise keep this dependencies
+     317             : 
+     318             :   // here just resize the neighpair. The real resizing of reinit will be done by the prepare stage that will modify the  list of arguments
+     319        1092 :   if (neigh_size>0) {
+     320         546 :     if(neighpair.size()==allArguments.size()) { // I just did the complete round: need to sort, shorten and give it a go
+     321             :       // sort the values
+     322         137 :       std::sort(neighpair.begin(),neighpair.end(),pairordering());
+     323             :       // resize the effective list
+     324         137 :       neighpair.resize(neigh_size);
+     325         137 :       log.printf("  NEIGH LIST NOW INCLUDE INDEXES: ");
+     326         411 :       for(int i=0; i<neigh_size; ++i) {log.printf(" %f ",indexmap[neighpair[i].first]);} log.printf(" \n");
+     327             :     } else {
+     328         409 :       if( int(getStep())%int(neigh_stride/getTimeStep())==0 ) {
+     329         137 :         log.printf(" Time %f : recalculating full neighlist \n",getStep()*getTimeStep());
+     330         137 :         neighpair.resize(allArguments.size());
+     331         548 :         for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     332             :       }
+     333             :     }
+     334             :   } else {
+     335         546 :     if( int(getStep())==0) {
+     336           1 :       neighpair.resize(allArguments.size());
+     337           4 :       for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     338             :     }
+     339             :   }
+     340             :   std::vector<Value*> argstocall;
+     341             : //log.printf("PREPARING \n");
+     342             :   argstocall.clear();
+     343        1092 :   if(!neighpair.empty()) {
+     344        3959 :     for(const auto & it : neighpair) {
+     345        2867 :       argstocall.push_back( it.first );
+     346             :       //     log.printf("CALLING %p %f ",(*it).first ,indexmap[(*it).first] );
+     347             :     }
+     348             :   } else {
+     349           0 :     for(unsigned i=0; i<allArguments.size(); i++) {
+     350           0 :       argstocall.push_back(allArguments[i]);
+     351             :     }
+     352             :   }
+     353             : // now the list of argument changes
+     354        1092 :   requestArguments(argstocall);
+     355             : //now resize the derivatives as well
+     356             : //for each value in this action
+     357        3276 :   for(int i=0; i< getNumberOfComponents(); i++) {
+     358             :     //resize the derivative to the number   the
+     359        2184 :     getPntrToComponent(i)->clearDerivatives();
+     360        2184 :     getPntrToComponent(i)->resizeDerivatives(getNumberOfArguments());
+     361             :   }
+     362             : //log.printf("PREPARING DONE! \n");
+     363        1092 : }
+     364             : 
+     365             : }
+     366             : }
+     367             : 
+     368             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func-sort-c.html b/coverage/function/FuncSumHills.cpp.func-sort-c.html new file mode 100644 index 0000000000..85430b47e9 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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:29532889.9 %
Date:2024-05-27 13:05: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_8KeywordsE11
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199D2Ev4168
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func.html b/coverage/function/FuncSumHills.cpp.func.html new file mode 100644 index 0000000000..0f8754d61f --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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:29532889.9 %
Date:2024-05-27 13:05: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_8KeywordsE11
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe1996createERKNS_13ActionOptionsE9
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_125FuncSumHillsRegisterMe199D2Ev4168
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.gcov.html b/coverage/function/FuncSumHills.cpp.gcov.html new file mode 100644 index 0000000000..7563f36f0b --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.gcov.html @@ -0,0 +1,714 @@ + + + + + + + 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:29532889.9 %
Date:2024-05-27 13:05: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       12522 : PLUMED_REGISTER_ACTION(FuncSumHills,"FUNCSUMHILLS")
+     200             : 
+     201          11 : void FuncSumHills::registerKeywords(Keywords& keys) {
+     202          11 :   Function::registerKeywords(keys);
+     203          11 :   keys.use("ARG");
+     204          22 :   keys.add("optional","HILLSFILES"," source file for hills creation(may be the same as HILLS)"); // this can be a vector!
+     205          22 :   keys.add("optional","HISTOFILES"," source file for histogram creation(may be the same as HILLS)"); // also this can be a vector!
+     206          22 :   keys.add("optional","HISTOSIGMA"," sigmas for binning when the histogram correction is needed    ");
+     207          22 :   keys.add("optional","PROJ"," only with sumhills: the projection on the CVs");
+     208          22 :   keys.add("optional","KT"," only with sumhills: the kt factor when projection on CVs");
+     209          22 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     210          22 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     211          22 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     212          22 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     213          22 :   keys.add("optional","INTERVAL","set one dimensional INTERVAL");
+     214          22 :   keys.add("optional","OUTHILLS"," output file for hills ");
+     215          22 :   keys.add("optional","OUTHISTO"," output file for histogram ");
+     216          22 :   keys.add("optional","INITSTRIDE"," stride if you want an initial dump ");
+     217          22 :   keys.add("optional","STRIDE"," stride when you do it on the fly ");
+     218          22 :   keys.addFlag("ISCLTOOL",false,"use via plumed command line: calculate at read phase and then go");
+     219          22 :   keys.addFlag("PARALLELREAD",false,"read parallel HILLS file");
+     220          22 :   keys.addFlag("NEGBIAS",false,"dump  negative bias ( -bias )   instead of the free energy: needed in well tempered with flexible hills ");
+     221          22 :   keys.addFlag("NOHISTORY",false,"to be used with INITSTRIDE:  it splits the bias/histogram in pieces without previous history  ");
+     222          22 :   keys.addFlag("MINTOZERO",false,"translate the resulting bias/histogram to have the minimum to zero  ");
+     223          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     224          11 : }
+     225             : 
+     226           9 : FuncSumHills::FuncSumHills(const ActionOptions&ao):
+     227             :   Action(ao),
+     228             :   Function(ao),
+     229           9 :   initstride(-1),
+     230           9 :   iscltool(false),
+     231           9 :   integratehills(false),
+     232           9 :   integratehisto(false),
+     233           9 :   parallelread(false),
+     234           9 :   negativebias(false),
+     235           9 :   nohistory(false),
+     236           9 :   minTOzero(false),
+     237           9 :   doInt(false),
+     238           9 :   lowI_(-1.),
+     239           9 :   uppI_(-1.),
+     240           9 :   beta(-1.),
+     241           9 :   fmt("%14.9f")
+     242             : {
+     243             : 
+     244             :   // format
+     245           9 :   parse("FMT",fmt);
+     246           9 :   log<<"  Output format is "<<fmt<<"\n";
+     247             :   // here read
+     248             :   // Grid Stuff
+     249             :   std::vector<std::string> gmin;
+     250          18 :   parseVector("GRID_MIN",gmin);
+     251           9 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     252           9 :   plumed_massert(gmin.size()==getNumberOfArguments() || gmin.size()==0,"need GRID_MIN argument for this") ;
+     253             :   std::vector<std::string> gmax;
+     254          18 :   parseVector("GRID_MAX",gmax);
+     255           9 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     256           9 :   plumed_massert(gmax.size()==getNumberOfArguments() || gmax.size()==0,"need GRID_MAX argument for this") ;
+     257             :   std::vector<unsigned> gbin;
+     258             :   std::vector<double>   gspacing;
+     259          18 :   parseVector("GRID_BIN",gbin);
+     260           9 :   plumed_massert(gbin.size()==getNumberOfArguments() || gbin.size()==0,"need GRID_BIN argument for this") ;
+     261           9 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     262          18 :   parseVector("GRID_SPACING",gspacing);
+     263           9 :   plumed_massert(gspacing.size()==getNumberOfArguments() || gspacing.size()==0,"need GRID_SPACING argument for this") ;
+     264           9 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     265           9 :   if(gspacing.size()!=0 && gbin.size()==0) {
+     266           1 :     log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     267           8 :   } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     268           0 :     log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     269           0 :     log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     270             :   }
+     271          10 :   if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     272           1 :       if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     273             :       double a,b;
+     274           1 :       Tools::convert(gmin[i],a);
+     275           1 :       Tools::convert(gmax[i],b);
+     276           1 :       unsigned n=std::ceil((b-a)/gspacing[i]);
+     277           1 :       if(gbin[i]<n) gbin[i]=n;
+     278             :     }
+     279             : 
+     280             :   // Inteval keyword
+     281           9 :   std::vector<double> tmpI(2);
+     282          18 :   parseVector("INTERVAL",tmpI);
+     283           9 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     284           9 :   else if(tmpI.size()==2) {
+     285           0 :     lowI_=tmpI.at(0);
+     286           0 :     uppI_=tmpI.at(1);
+     287           0 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     288           0 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     289           0 :     doInt=true;
+     290             :   }
+     291           9 :   if(doInt) {
+     292           0 :     log << "  Upper and Lower limits boundaries for the bias are activated at " << lowI_ << " - " << uppI_<<"\n";
+     293           0 :     log << "  Using the same values as boundaries for the grid if not other value was defined (default: 200 bins)\n";
+     294           0 :     std::ostringstream strsmin, strsmax;
+     295           0 :     strsmin << lowI_;
+     296           0 :     strsmax << uppI_;
+     297           0 :     if(gmin.size()==0) gmin.push_back(strsmin.str());
+     298           0 :     if(gmax.size()==0) gmax.push_back(strsmax.str());
+     299           0 :     if(gbin.size()==0) gbin.push_back(200);
+     300           0 :   }
+     301             : 
+     302             : 
+     303             :   // hills file:
+     304          18 :   parseVector("HILLSFILES",hillsFiles);
+     305           9 :   if(hillsFiles.size()==0) {
+     306           1 :     integratehills=false; // default behaviour
+     307             :   } else {
+     308           8 :     integratehills=true;
+     309          17 :     for(unsigned i=0; i<hillsFiles.size(); i++) log<<"  hillsfile  : "<<hillsFiles[i]<<"\n";
+     310             :   }
+     311             :   // histo file:
+     312          18 :   parseVector("HISTOFILES",histoFiles);
+     313           9 :   if(histoFiles.size()==0) {
+     314           8 :     integratehisto=false;
+     315             :   } else {
+     316           1 :     integratehisto=true;
+     317           2 :     for(unsigned i=0; i<histoFiles.size(); i++) log<<"  histofile  : "<<histoFiles[i]<<"\n";
+     318             :   }
+     319             :   std::vector<double> histoSigma;
+     320           9 :   if(integratehisto) {
+     321           1 :     parseVector("HISTOSIGMA",histoSigma);
+     322           3 :     for(unsigned i=0; i<histoSigma.size(); i++) log<<"  histosigma  : "<<histoSigma[i]<<"\n";
+     323             :   }
+     324             : 
+     325             :   // needs a projection?
+     326             :   proj.clear();
+     327           9 :   parseVector("PROJ",proj);
+     328           9 :   if(integratehills) {
+     329           8 :     plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
+     330             :   }
+     331           9 :   if(integratehisto) {
+     332           1 :     plumed_massert(proj.size()<=getNumberOfArguments()," The number of projection must be less or equal to the full list of arguments ");
+     333             :   }
+     334           9 :   if(integratehisto&&proj.size()==0) {
+     335           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) proj.push_back(getPntrToArgument(i)->getName());
+     336             :   }
+     337             : 
+     338             :   // add some automatic hills width: not in case stride is defined
+     339             :   // since when you start from zero the automatic size will be zero!
+     340           9 :   if(gmin.size()==0 || gmax.size()==0) {
+     341           5 :     log<<"   \n";
+     342           5 :     log<<"  No boundaries defined: need to do a prescreening of hills \n";
+     343             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     344           5 :     if(integratehills) {
+     345          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++)tmphillsvalues.push_back( getPntrToArgument(i) );
+     346             :     }
+     347           5 :     if(integratehisto) {
+     348           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     349           2 :         std::string ss = getPntrToArgument(i)->getName();
+     350           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     351           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     352             :         }
+     353             :       }
+     354             :     }
+     355             : 
+     356           5 :     if(integratehills) {
+     357           4 :       FilesHandler hillsHandler(hillsFiles,parallelread,*this, log);
+     358             :       std::vector<double> vmin,vmax;
+     359             :       std::vector<unsigned> vbin;
+     360           4 :       hillsHandler.getMinMaxBin(tmphillsvalues,comm,vmin,vmax,vbin);
+     361           4 :       log<<"  found boundaries from hillsfile: \n";
+     362           4 :       gmin.resize(vmin.size());
+     363           4 :       gmax.resize(vmax.size());
+     364           4 :       if(gbin.size()==0) {
+     365           3 :         gbin=vbin;
+     366             :       } else {
+     367           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     368             :       }
+     369          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     370           8 :         Tools::convert(vmin[i],gmin[i]);
+     371           8 :         Tools::convert(vmax[i],gmax[i]);
+     372           8 :         log<<"  variable "<< getPntrToArgument(i)->getName()<<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     373             :       }
+     374             :     }
+     375             :     // if at this stage bins are not there then do it with histo
+     376           5 :     if(gmin.size()==0) {
+     377           1 :       FilesHandler histoHandler(histoFiles,parallelread,*this, log);
+     378             :       std::vector<double> vmin,vmax;
+     379             :       std::vector<unsigned> vbin;
+     380           1 :       histoHandler.getMinMaxBin(tmphistovalues,comm,vmin,vmax,vbin,histoSigma);
+     381           1 :       log<<"  found boundaries from histofile: \n";
+     382           1 :       gmin.resize(vmin.size());
+     383           1 :       gmax.resize(vmax.size());
+     384           1 :       if(gbin.size()==0) {
+     385           0 :         gbin=vbin;
+     386             :       } else {
+     387           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     388             :       }
+     389           3 :       for(unsigned i=0; i<proj.size(); i++) {
+     390           2 :         Tools::convert(vmin[i],gmin[i]);
+     391           2 :         Tools::convert(vmax[i],gmax[i]);
+     392           2 :         log<<"  variable "<< proj[i] <<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     393             :       }
+     394             :     }
+     395           5 :     log<<"  done!\n";
+     396           5 :     log<<"   \n";
+     397             :   }
+     398             : 
+     399             : 
+     400           9 :   if( proj.size() != 0 || integratehisto==true  ) {
+     401           3 :     parse("KT",beta);
+     402           7 :     for(unsigned i=0; i<proj.size(); i++) log<<"  projection "<<i<<" : "<<proj[i]<<"\n";
+     403             :     // this should be only for projection or free energy from histograms
+     404           3 :     plumed_massert(beta>0.,"if you make a projection or a histogram correction then you need KT flag!");
+     405           3 :     beta=1./beta;
+     406           3 :     log<<"  beta is "<<beta<<"\n";
+     407             :   }
+     408             :   // is a cltool: then you start and then die
+     409           9 :   parseFlag("ISCLTOOL",iscltool);
+     410             :   //
+     411           9 :   parseFlag("NEGBIAS",negativebias);
+     412             :   //
+     413           9 :   parseFlag("PARALLELREAD",parallelread);
+     414             :   // stride
+     415           9 :   parse("INITSTRIDE",initstride);
+     416             :   // output suffix or names
+     417           9 :   if(initstride<0) {
+     418           8 :     log<<"  Doing only one integration: no stride \n";
+     419             :     outhills="fes.dat"; outhisto="histo.dat";
+     420             :   }
+     421             :   else {
+     422             :     outhills="fes_"; outhisto="histo_";
+     423           1 :     log<<"  Doing integration slices every "<<initstride<<" kernels\n";
+     424           1 :     parseFlag("NOHISTORY",nohistory);
+     425           1 :     if(nohistory)log<<"  nohistory: each stride block has no memory of the previous block\n";
+     426             :   }
+     427           9 :   parseFlag("MINTOZERO",minTOzero);
+     428           9 :   if(minTOzero)log<<"  mintozero: bias/histogram will be translated to have the minimum value equal to zero\n";
+     429             :   //what might it be this?
+     430             :   // here start
+     431             :   // want something right now?? do it and return
+     432             :   // your argument is a set of cvs
+     433             :   // then you need: a hills / a colvar-like file (to do a histogram)
+     434             :   // create a bias representation for this
+     435           9 :   if(iscltool) {
+     436             : 
+     437             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     438           9 :     if(integratehills) {
+     439          23 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     440             :         // allocate a new value from the old one: no deriv here
+     441             :         // if we are summing hills then all the arguments are needed
+     442          15 :         tmphillsvalues.push_back( getPntrToArgument(i) );
+     443             :       }
+     444             :     }
+     445           9 :     if(integratehisto) {
+     446           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     447           2 :         std::string ss = getPntrToArgument(i)->getName();
+     448           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     449           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     450             :         }
+     451             :       }
+     452             :     }
+     453             : 
+     454             :     // check if the files exists
+     455           9 :     if(integratehills) {
+     456           8 :       checkFilesAreExisting(hillsFiles);
+     457          16 :       biasrep=Tools::make_unique<BiasRepresentation>(tmphillsvalues,comm, gmin, gmax, gbin, doInt, lowI_, uppI_);
+     458           8 :       if(negativebias) {
+     459           1 :         biasrep->setRescaledToBias(true);
+     460           1 :         log<<"  required the -bias instead of the free energy \n";
+     461           1 :         if(initstride<0) {outhills="negativebias.dat";}
+     462             :         else {outhills="negativebias_";}
+     463             :       }
+     464             :     }
+     465             : 
+     466           9 :     parse("OUTHILLS",outhills);
+     467           9 :     parse("OUTHISTO",outhisto);
+     468           9 :     if(integratehills)log<<"  output file for fes/bias  is :  "<<outhills<<"\n";
+     469           9 :     if(integratehisto)log<<"  output file for histogram is :  "<<outhisto<<"\n";
+     470           9 :     checkRead();
+     471             : 
+     472           9 :     log<<"\n";
+     473           9 :     log<<"  Now calculating...\n";
+     474           9 :     log<<"\n";
+     475             : 
+     476             :     // here it defines the column to be histogrammed, tmpvalues should be only
+     477             :     // the list of the collective variable one want to consider
+     478           9 :     if(integratehisto) {
+     479           1 :       checkFilesAreExisting(histoFiles);
+     480           2 :       historep=Tools::make_unique<BiasRepresentation>(tmphistovalues,comm,gmin,gmax,gbin,histoSigma);
+     481             :     }
+     482             : 
+     483             :     // decide how to source hills ( serial/parallel )
+     484             :     // here below the input control
+     485             :     // say how many hills and it will read them from the
+     486             :     // bunch of files provided, will update the representation
+     487             :     // of hills (i.e. a list of hills and the associated grid)
+     488             : 
+     489             :     // decide how to source colvars ( serial parallel )
+     490           9 :     std::unique_ptr<FilesHandler> hillsHandler;
+     491           9 :     std::unique_ptr<FilesHandler> histoHandler;
+     492             : 
+     493          17 :     if(integratehills)  hillsHandler=Tools::make_unique<FilesHandler>(hillsFiles,parallelread,*this, log);
+     494          10 :     if(integratehisto)  histoHandler=Tools::make_unique<FilesHandler>(histoFiles,parallelread,*this, log);
+     495             : 
+     496             : // Stopwatch is logged when it goes out of scope
+     497           9 :     Stopwatch sw(log);
+     498             : 
+     499             : // Stopwatch is stopped when swh goes out of scope
+     500           9 :     auto swh=sw.startStop("0 Summing hills");
+     501             : 
+     502             :     // read a number of hills and put in the bias representation
+     503             :     int nfiles=0;
+     504           9 :     bool ibias=integratehills; bool ihisto=integratehisto;
+     505             :     while(true) {
+     506          10 :       if(  integratehills  && ibias  ) {
+     507           9 :         if(nohistory) {biasrep->clear(); log<<"  clearing history before reading a new block\n";};
+     508           9 :         log<<"  reading hills: \n";
+     509           9 :         ibias=hillsHandler->readBunch(biasrep.get(),initstride) ; log<<"\n";
+     510             :       }
+     511             : 
+     512          10 :       if(  integratehisto  && ihisto ) {
+     513           1 :         if(nohistory) {historep->clear(); log<<"  clearing history before reading a new block\n";};
+     514           1 :         log<<"  reading histogram: \n";
+     515           1 :         ihisto=histoHandler->readBunch(historep.get(),initstride) ;  log<<"\n";
+     516             :       }
+     517             : 
+     518             :       // dump: need to project?
+     519          10 :       if(proj.size()!=0) {
+     520             : 
+     521           4 :         if(integratehills) {
+     522             : 
+     523           3 :           log<<"  Bias: Projecting on subgrid... \n";
+     524           3 :           BiasWeight Bw(beta);
+     525           3 :           Grid biasGrid=*(biasrep->getGridPtr());
+     526           3 :           Grid smallGrid=biasGrid.project(proj,&Bw);
+     527           3 :           OFile gridfile; gridfile.link(*this);
+     528           3 :           std::ostringstream ostr; ostr<<nfiles;
+     529             :           std::string myout;
+     530           7 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     531           3 :           log<<"  Bias: Writing subgrid on file "<<myout<<" \n";
+     532           3 :           gridfile.open(myout);
+     533           3 :           if(minTOzero) smallGrid.setMinToZero();
+     534             :           smallGrid.setOutputFmt(fmt);
+     535           3 :           smallGrid.writeToFile(gridfile);
+     536           3 :           gridfile.close();
+     537           3 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     538           3 :         }
+     539             :         // this should be removed
+     540           4 :         if(integratehisto) {
+     541             : 
+     542           1 :           log<<"  Histo: Projecting on subgrid... \n";
+     543           1 :           Grid histoGrid=*(historep->getGridPtr());
+     544             : 
+     545           1 :           OFile gridfile; gridfile.link(*this);
+     546           1 :           std::ostringstream ostr; ostr<<nfiles;
+     547             :           std::string myout;
+     548           1 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     549           1 :           log<<"  Histo: Writing subgrid on file "<<myout<<" \n";
+     550           1 :           gridfile.open(myout);
+     551             : 
+     552           1 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     553           1 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     554           1 :           if(minTOzero) histoGrid.setMinToZero();
+     555             :           histoGrid.setOutputFmt(fmt);
+     556           1 :           histoGrid.writeToFile(gridfile);
+     557             : 
+     558           1 :           if(!ihisto)integratehisto=false;// once you get to the final bunch just give up
+     559           1 :         }
+     560             : 
+     561             :       } else {
+     562             : 
+     563           6 :         if(integratehills) {
+     564             : 
+     565           6 :           Grid biasGrid=*(biasrep->getGridPtr());
+     566           6 :           biasGrid.scaleAllValuesAndDerivatives(-1.);
+     567             : 
+     568           6 :           OFile gridfile; gridfile.link(*this);
+     569           6 :           std::ostringstream ostr; ostr<<nfiles;
+     570             :           std::string myout;
+     571           6 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     572           6 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     573           6 :           gridfile.open(myout);
+     574             : 
+     575           6 :           if(minTOzero) biasGrid.setMinToZero();
+     576             :           biasGrid.setOutputFmt(fmt);
+     577           6 :           biasGrid.writeToFile(gridfile);
+     578             :           // rescale back prior to accumulate
+     579           6 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     580           6 :         }
+     581           6 :         if(integratehisto) {
+     582             : 
+     583           0 :           Grid histoGrid=*(historep->getGridPtr());
+     584             :           // do this if you want a free energy from a grid, otherwise do not
+     585           0 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     586           0 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     587             : 
+     588           0 :           OFile gridfile; gridfile.link(*this);
+     589           0 :           std::ostringstream ostr; ostr<<nfiles;
+     590             :           std::string myout;
+     591           0 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     592           0 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     593           0 :           gridfile.open(myout);
+     594             : 
+     595             :           // also this is useful only for free energy
+     596           0 :           if(minTOzero) histoGrid.setMinToZero();
+     597             :           histoGrid.setOutputFmt(fmt);
+     598           0 :           histoGrid.writeToFile(gridfile);
+     599             : 
+     600           0 :           if(!ihisto)integratehisto=false; // once you get to the final bunch just give up
+     601           0 :         }
+     602             :       }
+     603          10 :       if ( !ibias && !ihisto) break; //when both are over then just quit
+     604             : 
+     605           1 :       nfiles++;
+     606           1 :     }
+     607             : 
+     608             :     return;
+     609           9 :   }
+     610             :   // just an initialization but you need to do something on the fly?: need to connect with a metad run and its grid representation
+     611             :   // your argument is a metad run
+     612             :   // if the grid does not exist crash and say that you need some data
+     613             :   // otherwise just link with it
+     614             : 
+     615           9 : }
+     616             : 
+     617           0 : void FuncSumHills::calculate() {
+     618             :   // this should be connected only with a grid representation to metadynamics
+     619             :   // at regular time just dump it
+     620           0 :   plumed_merror("You should have never got here: this stuff is not yet implemented!");
+     621             : }
+     622             : 
+     623           9 : bool FuncSumHills::checkFilesAreExisting(const std::vector<std::string> & hills ) {
+     624           9 :   plumed_massert(hills.size()!=0,"the number of  files provided should be at least one" );
+     625           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.16
+
+ + + diff --git a/coverage/function/Function.cpp.func-sort-c.html b/coverage/function/Function.cpp.func-sort-c.html new file mode 100644 index 0000000000..35aa7a1115 --- /dev/null +++ b/coverage/function/Function.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8Function23addValueWithDerivativesEv571
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE669
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE699
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3173
_ZN4PLMD8function8Function5applyEv225077
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.func.html b/coverage/function/Function.cpp.func.html new file mode 100644 index 0000000000..0fd498fdb5 --- /dev/null +++ b/coverage/function/Function.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE699
_ZN4PLMD8function8Function23addValueWithDerivativesEv571
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3173
_ZN4PLMD8function8Function5applyEv225077
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE669
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.gcov.html b/coverage/function/Function.cpp.gcov.html new file mode 100644 index 0000000000..85cde8d4a8 --- /dev/null +++ b/coverage/function/Function.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-05-27 13:05: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         699 : void Function::registerKeywords(Keywords& keys) {
+      30         699 :   Action::registerKeywords(keys);
+      31         699 :   ActionWithValue::registerKeywords(keys);
+      32         699 :   ActionWithArguments::registerKeywords(keys);
+      33        1398 :   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         699 : }
+      35             : 
+      36         669 : Function::Function(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39         669 :   ActionWithArguments(ao)
+      40             : {
+      41         669 : }
+      42             : 
+      43         571 : void Function::addValueWithDerivatives() {
+      44         571 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      45         571 :   ActionWithValue::addValueWithDerivatives();
+      46         571 :   getPntrToValue()->resizeDerivatives(getNumberOfArguments());
+      47             : 
+      48        1142 :   if( keywords.exists("PERIODIC") ) {
+      49             :     std::vector<std::string> period;
+      50        1136 :     parseVector("PERIODIC",period);
+      51        1133 :     if(period.size()==1 && period[0]=="NO") {
+      52         565 :       setNotPeriodic();
+      53           3 :     } else if(period.size()==2) {
+      54           3 :       setPeriodic(period[0],period[1]);
+      55           0 :     } else error("missing PERIODIC keyword");
+      56         568 :   }
+      57         571 : }
+      58             : 
+      59        3173 : void Function::addComponentWithDerivatives( const std::string& name ) {
+      60        3173 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      61        3173 :   ActionWithValue::addComponentWithDerivatives(name);
+      62        3173 :   getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments());
+      63        3173 : }
+      64             : 
+      65      225077 : void Function::apply()
+      66             : {
+      67      225077 :   const unsigned noa=getNumberOfArguments();
+      68      225077 :   const unsigned ncp=getNumberOfComponents();
+      69      225077 :   const unsigned cgs=comm.Get_size();
+      70             : 
+      71      225077 :   std::vector<double> f(noa,0.0);
+      72             : 
+      73             :   unsigned stride=1;
+      74             :   unsigned rank=0;
+      75      225077 :   if(ncp>4*cgs) {
+      76           6 :     stride=comm.Get_size();
+      77           6 :     rank=comm.Get_rank();
+      78             :   }
+      79             : 
+      80      225077 :   unsigned at_least_one_forced=0;
+      81      225077 :   #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      225077 :   if(noa>0&&ncp>4*cgs) { comm.Sum(&f[0],noa); comm.Sum(at_least_one_forced); }
+      97             : 
+      98      290939 :   if(at_least_one_forced>0) for(unsigned i=0; i<noa; ++i) getPntrToArgument(i)->addForce(f[i]);
+      99      225077 : }
+     100             : 
+     101             : }
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func-sort-c.html b/coverage/function/Function.h.func-sort-c.html new file mode 100644 index 0000000000..e5ceea4b19 --- /dev/null +++ b/coverage/function/Function.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionD2Ev669
_ZN4PLMD8function8Function13setDerivativeEid52179
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3471295
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func.html b/coverage/function/Function.h.func.html new file mode 100644 index 0000000000..d079a19772 --- /dev/null +++ b/coverage/function/Function.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function13setDerivativeEid52179
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3471295
_ZN4PLMD8function8FunctionD2Ev669
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.gcov.html b/coverage/function/Function.h.gcov.html new file mode 100644 index 0000000000..34ab6d6c08 --- /dev/null +++ b/coverage/function/Function.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + 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-05-27 13:05: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         669 :   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       55089 :   v->addDerivative(i,d);
+      57           0 : }
+      58             : 
+      59             : inline
+      60       52179 : void Function::setDerivative(int i,double d) {
+      61       52179 :   setDerivative(getPntrToValue(),i,d);
+      62       52179 : }
+      63             : 
+      64             : inline
+      65     3471295 : unsigned Function::getNumberOfDerivatives() {
+      66     3471295 :   return getNumberOfArguments();
+      67             : }
+      68             : 
+      69             : }
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func-sort-c.html b/coverage/function/LocalEnsemble.cpp.func-sort-c.html new file mode 100644 index 0000000000..100e5eaf88 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe886createERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func.html b/coverage/function/LocalEnsemble.cpp.func.html new file mode 100644 index 0000000000..119307a357 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe886createERKNS_13ActionOptionsE2
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_125LocalEnsembleRegisterMe88D2Ev4168
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.gcov.html b/coverage/function/LocalEnsemble.cpp.gcov.html new file mode 100644 index 0000000000..e11b5afee6 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(LocalEnsemble,"LOCALENSEMBLE")
+      89             : 
+      90           4 : void LocalEnsemble::registerKeywords(Keywords& keys) {
+      91           4 :   Function::registerKeywords(keys);
+      92           4 :   keys.use("ARG");
+      93           8 :   keys.add("compulsory","NUM","the number of local replicas");
+      94           4 :   useCustomisableComponents(keys);
+      95           4 : }
+      96             : 
+      97           2 : LocalEnsemble::LocalEnsemble(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   Function(ao),
+     100           2 :   ens_dim(0)
+     101             : {
+     102           2 :   parse("NUM",ens_dim);
+     103           2 :   if(ens_dim==0) error("NUM should be greater or equal to 1");
+     104             : 
+     105             :   std::vector<Value*> arg;
+     106             :   int oldsize=-1;
+     107           8 :   for(unsigned i=1; i<=ens_dim; ++i ) {
+     108             :     std::vector<Value*> larg;
+     109          12 :     if(!parseArgumentList("ARG",i,larg)) break;
+     110          18 :     for(unsigned j=0; j<larg.size(); j++) arg.push_back(larg[j]);
+     111           6 :     if(oldsize!=-1&&oldsize!=static_cast<int>(larg.size())) error("In LOCALENSEMBLE you should have the same number of arguments for each ARG keyword");
+     112           6 :     oldsize = larg.size();
+     113           6 :     if(!larg.empty()) {
+     114           6 :       log.printf("  with arguments %u: ", i);
+     115          18 :       for(unsigned j=0; j<larg.size(); j++) log.printf(" %s",larg[j]->getName().c_str());
+     116           6 :       log.printf("\n");
+     117             :     }
+     118             :   }
+     119           2 :   requestArguments(arg);
+     120           2 :   narg = arg.size()/ens_dim;
+     121             : 
+     122             :   // these are the averages
+     123           6 :   for(unsigned i=0; i<narg; i++) {
+     124           4 :     std::string s=getPntrToArgument(i)->getName();
+     125           4 :     addComponentWithDerivatives(s);
+     126           4 :     getPntrToComponent(i)->setNotPeriodic();
+     127             :   }
+     128             : 
+     129           2 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     130           2 : }
+     131             : 
+     132          40 : void LocalEnsemble::calculate()
+     133             : {
+     134          40 :   const double fact = 1.0/static_cast<double>(ens_dim);
+     135          40 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     136             :   for(unsigned i=0; i<narg; ++i) {
+     137             :     double mean = 0.;
+     138             :     Value* v=getPntrToComponent(i);
+     139             :     for(unsigned j=0; j<ens_dim; ++j) {
+     140             :       const unsigned index = j*narg+i;
+     141             :       setDerivative(v, index, fact);
+     142             :       mean += fact*getArgument(index);
+     143             :     }
+     144             :     v->set(mean);
+     145             :   }
+     146          40 : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+     151             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func-sort-c.html b/coverage/function/Piecewise.cpp.func-sort-c.html new file mode 100644 index 0000000000..4af39776f9 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe796createERKNS_13ActionOptionsE3
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function9Piecewise9calculateEv10
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func.html b/coverage/function/Piecewise.cpp.func.html new file mode 100644 index 0000000000..025d8d6e3c --- /dev/null +++ b/coverage/function/Piecewise.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe796createERKNS_13ActionOptionsE3
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_121PiecewiseRegisterMe79D2Ev4168
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function9Piecewise9calculateEv10
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.gcov.html b/coverage/function/Piecewise.cpp.gcov.html new file mode 100644 index 0000000000..63a0626f0a --- /dev/null +++ b/coverage/function/Piecewise.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + 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-05-27 13:05: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       12509 : PLUMED_REGISTER_ACTION(Piecewise,"PIECEWISE")
+      80             : 
+      81           5 : void Piecewise::registerKeywords(Keywords& keys) {
+      82           5 :   Function::registerKeywords(keys);
+      83           5 :   keys.use("ARG");
+      84          10 :   keys.add("numbered","POINT","This keyword is used to specify the various points in the function above.");
+      85          10 :   keys.reset_style("POINT","compulsory");
+      86           5 :   componentsAreNotOptional(keys);
+      87          10 :   keys.addOutputComponent("_pfunc","default","one or multiple instances of this quantity can be referenced elsewhere "
+      88             :                           "in the input file.  These quantities will be named with the arguments of the "
+      89             :                           "function followed by the character string _pfunc.  These quantities tell the "
+      90             :                           "user the values of the piece wise functions of each of the arguments.");
+      91           5 : }
+      92             : 
+      93           3 : Piecewise::Piecewise(const ActionOptions&ao):
+      94             :   Action(ao),
+      95           3 :   Function(ao)
+      96             : {
+      97           9 :   for(int i=0;; i++) {
+      98             :     std::vector<double> pp;
+      99          24 :     if(!parseNumberedVector("POINT",i,pp) ) break;
+     100           9 :     if(pp.size()!=2) error("points should be in x,y format");
+     101           9 :     points.push_back(std::pair<double,double>(pp[0],pp[1]));
+     102           9 :     if(i>0 && points[i].first<=points[i-1].first) error("points abscissas should be monotonously increasing");
+     103           9 :   }
+     104             : 
+     105           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++)
+     106           4 :     if(getPntrToArgument(i)->isPeriodic())
+     107           1 :       error("Cannot use PIECEWISE on periodic arguments");
+     108             : 
+     109           2 :   if(getNumberOfArguments()==1) {
+     110           1 :     addValueWithDerivatives();
+     111           1 :     setNotPeriodic();
+     112             :   } else {
+     113           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     114           3 :       addComponentWithDerivatives( getPntrToArgument(i)->getName()+"_pfunc" );
+     115           2 :       getPntrToComponent(i)->setNotPeriodic();
+     116             :     }
+     117             :   }
+     118           2 :   checkRead();
+     119             : 
+     120           2 :   log.printf("  on points:");
+     121           8 :   for(unsigned i=0; i<points.size(); i++) log.printf("   (%f,%f)",points[i].first,points[i].second);
+     122           2 :   log.printf("\n");
+     123           4 : }
+     124             : 
+     125          10 : void Piecewise::calculate() {
+     126          25 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     127             :     double val=getArgument(i);
+     128             :     unsigned p=0;
+     129          37 :     for(; p<points.size(); p++) {
+     130          33 :       if(val<points[p].first) break;
+     131             :     }
+     132             :     double f,d;
+     133          15 :     if(p==0) {
+     134           5 :       f=points[0].second;
+     135             :       d=0.0;
+     136          10 :     } else if(p==points.size()) {
+     137           4 :       f=points[points.size()-1].second;
+     138             :       d=0.0;
+     139             :     } else {
+     140           6 :       double m=(points[p].second-points[p-1].second) / (points[p].first-points[p-1].first);
+     141           6 :       f=m*(val-points[p-1].first)+points[p-1].second;
+     142             :       d=m;
+     143             :     }
+     144          15 :     if(getNumberOfArguments()==1) {
+     145           5 :       setValue(f);
+     146           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.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func-sort-c.html b/coverage/function/Sort.cpp.func-sort-c.html new file mode 100644 index 0000000000..63601b0f5c --- /dev/null +++ b/coverage/function/Sort.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE14
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func.html b/coverage/function/Sort.cpp.func.html new file mode 100644 index 0000000000..648745d6b6 --- /dev/null +++ b/coverage/function/Sort.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe646createERKNS_13ActionOptionsE12
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_116SortRegisterMe64D2Ev4168
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function4Sort9calculateEv11
_ZN4PLMD8function4SortC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function4SortC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.gcov.html b/coverage/function/Sort.cpp.gcov.html new file mode 100644 index 0000000000..49e4529eb4 --- /dev/null +++ b/coverage/function/Sort.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + 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-05-27 13:05: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       12527 : PLUMED_REGISTER_ACTION(Sort,"SORT")
+      65             : 
+      66          14 : void Sort::registerKeywords(Keywords& keys) {
+      67          14 :   Function::registerKeywords(keys);
+      68          14 :   keys.use("ARG");
+      69          14 :   useCustomisableComponents(keys);
+      70          14 : }
+      71             : 
+      72          12 : Sort::Sort(const ActionOptions&ao):
+      73             :   Action(ao),
+      74          12 :   Function(ao)
+      75             : {
+      76          35 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      77             :     std::string s;
+      78          24 :     Tools::convert(i+1,s);
+      79          24 :     if(getPntrToArgument(i)->isPeriodic())
+      80           3 :       error("Cannot sort periodic values (check argument "+s+")");
+      81          23 :     addComponentWithDerivatives(s);
+      82          23 :     getPntrToComponent(i)->setNotPeriodic();
+      83             :   }
+      84          11 :   checkRead();
+      85             : 
+      86          13 : }
+      87             : 
+      88          11 : void Sort::calculate() {
+      89          11 :   std::vector<std::pair<double,int> > vals(getNumberOfArguments());
+      90          54 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      91          43 :     vals[i].first=getArgument(i);
+      92             : // In this manner I remember from which argument the component depends:
+      93          43 :     vals[i].second=i;
+      94             :   }
+      95             : // STL sort sorts based on first element (value) then second (index)
+      96          11 :   std::sort(vals.begin(),vals.end());
+      97          54 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      98          43 :     Value* v=getPntrToComponent(i);
+      99          43 :     v->set(vals[i].first);
+     100          43 :     setDerivative(v,vals[i].second,1.0);
+     101             :   }
+     102          11 : }
+     103             : 
+     104             : }
+     105             : }
+     106             : 
+     107             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func-sort-c.html b/coverage/function/Stats.cpp.func-sort-c.html new file mode 100644 index 0000000000..a364262f0c --- /dev/null +++ b/coverage/function/Stats.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe706createERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func.html b/coverage/function/Stats.cpp.func.html new file mode 100644 index 0000000000..f8aad4241a --- /dev/null +++ b/coverage/function/Stats.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe706createERKNS_13ActionOptionsE31
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_117StatsRegisterMe70D2Ev4168
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.gcov.html b/coverage/function/Stats.cpp.gcov.html new file mode 100644 index 0000000000..a3f1fc5784 --- /dev/null +++ b/coverage/function/Stats.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + 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-05-27 13:05: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       12566 : PLUMED_REGISTER_ACTION(Stats,"STATS")
+      71             : 
+      72          33 : void Stats::registerKeywords(Keywords& keys) {
+      73          33 :   Function::registerKeywords(keys);
+      74          33 :   keys.use("ARG");
+      75          66 :   keys.add("optional","PARARG","the input for this action is the scalar output from one or more other actions without derivatives.");
+      76          66 :   keys.add("optional","PARAMETERS","the parameters of the arguments in your function");
+      77          66 :   keys.addFlag("SQDEVSUM",false,"calculates only SQDEVSUM");
+      78          66 :   keys.addFlag("SQDEV",false,"calculates and store the SQDEV as components");
+      79          66 :   keys.addFlag("UPPERDISTS",false,"calculates and store the SQDEV as components");
+      80          66 :   keys.addOutputComponent("sqdevsum","default","the sum of the squared deviations between arguments and parameters");
+      81          66 :   keys.addOutputComponent("corr","default","the correlation between arguments and parameters");
+      82          66 :   keys.addOutputComponent("slope","default","the slope of a linear fit between arguments and parameters");
+      83          66 :   keys.addOutputComponent("intercept","default","the intercept of a linear fit between arguments and parameters");
+      84          66 :   keys.addOutputComponent("sqd","SQDEV","the squared deviations between arguments and parameters");
+      85          33 : }
+      86             : 
+      87          31 : Stats::Stats(const ActionOptions&ao):
+      88             :   Action(ao),
+      89             :   Function(ao),
+      90          31 :   sqdonly(false),
+      91          31 :   components(false),
+      92          31 :   upperd(false)
+      93             : {
+      94          62 :   parseVector("PARAMETERS",parameters);
+      95          31 :   if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments())&&!parameters.empty())
+      96           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+      97             : 
+      98             :   std::vector<Value*> arg2;
+      99          62 :   parseArgumentList("PARARG",arg2);
+     100             : 
+     101          31 :   if(!arg2.empty()) {
+     102          14 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     103          14 :     if(arg2.size()!=getNumberOfArguments()) error("Size of PARARG array should be the same as number for arguments in ARG");
+     104        5912 :     for(unsigned i=0; i<arg2.size(); i++) {
+     105        5898 :       parameters.push_back(arg2[i]->get());
+     106        5898 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     107             :     }
+     108             :   }
+     109             : 
+     110          31 :   if(parameters.size()!=getNumberOfArguments())
+     111           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     112             : 
+     113          31 :   if(getNumberOfArguments()<2) error("STATS need at least two arguments to be used");
+     114             : 
+     115          31 :   parseFlag("SQDEVSUM",sqdonly);
+     116          31 :   parseFlag("SQDEV",components);
+     117          31 :   parseFlag("UPPERDISTS",upperd);
+     118             : 
+     119          31 :   if(sqdonly&&components) error("You cannot used SQDEVSUM and SQDEV at the sametime");
+     120             : 
+     121          31 :   if(components) sqdonly = true;
+     122             : 
+     123          31 :   if(!arg2.empty()) log.printf("  using %zu parameters from inactive actions:", arg2.size());
+     124          17 :   else              log.printf("  using %zu parameters:", arg2.size());
+     125        6000 :   for(unsigned i=0; i<parameters.size(); i++) log.printf(" %f",parameters[i]);
+     126          31 :   log.printf("\n");
+     127             : 
+     128          31 :   if(sqdonly) {
+     129          17 :     if(components) {
+     130          60 :       for(unsigned i=0; i<parameters.size(); i++) {
+     131          48 :         std::string num; Tools::convert(i,num);
+     132          48 :         addComponentWithDerivatives("sqd-"+num);
+     133          96 :         componentIsNotPeriodic("sqd-"+num);
+     134             :       }
+     135             :     } else {
+     136           5 :       addComponentWithDerivatives("sqdevsum");
+     137          10 :       componentIsNotPeriodic("sqdevsum");
+     138             :     }
+     139             :   } else {
+     140          14 :     addComponentWithDerivatives("sqdevsum");
+     141          14 :     componentIsNotPeriodic("sqdevsum");
+     142          14 :     addComponentWithDerivatives("corr");
+     143          14 :     componentIsNotPeriodic("corr");
+     144          14 :     addComponentWithDerivatives("slope");
+     145          14 :     componentIsNotPeriodic("slope");
+     146          14 :     addComponentWithDerivatives("intercept");
+     147          28 :     componentIsNotPeriodic("intercept");
+     148             :   }
+     149             : 
+     150          31 :   checkRead();
+     151          31 : }
+     152             : 
+     153         122 : void Stats::calculate()
+     154             : {
+     155         122 :   if(sqdonly) {
+     156             : 
+     157             :     double nsqd = 0.;
+     158             :     Value* val;
+     159         106 :     if(!components) val=getPntrToComponent("sqdevsum");
+     160         174 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     161         121 :       double dev = getArgument(i)-parameters[i];
+     162         121 :       if(upperd&&dev<0) dev=0.;
+     163         121 :       if(components) {
+     164           0 :         val=getPntrToComponent(i);
+     165           0 :         val->set(dev*dev);
+     166             :       } else {
+     167         121 :         nsqd += dev*dev;
+     168             :       }
+     169         121 :       setDerivative(val,i,2.*dev);
+     170             :     }
+     171          53 :     if(!components) val->set(nsqd);
+     172             : 
+     173             :   } else {
+     174             : 
+     175             :     double scx=0., scx2=0., scy=0., scy2=0., scxy=0.;
+     176             : 
+     177        6230 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     178             :       const double tmpx=getArgument(i);
+     179        6161 :       const double tmpy=parameters[i];
+     180        6161 :       scx  += tmpx;
+     181        6161 :       scx2 += tmpx*tmpx;
+     182        6161 :       scy  += tmpy;
+     183        6161 :       scy2 += tmpy*tmpy;
+     184        6161 :       scxy += tmpx*tmpy;
+     185             :     }
+     186             : 
+     187          69 :     const double ns = parameters.size();
+     188             : 
+     189          69 :     const double num = ns*scxy - scx*scy;
+     190          69 :     const double idev2x = 1./(ns*scx2-scx*scx);
+     191          69 :     const double idevx = std::sqrt(idev2x);
+     192          69 :     const double idevy = 1./std::sqrt(ns*scy2-scy*scy);
+     193             : 
+     194             :     /* sd */
+     195          69 :     const double nsqd = scx2 + scy2 - 2.*scxy;
+     196             :     /* correlation */
+     197          69 :     const double correlation = num * idevx * idevy;
+     198             :     /* slope and intercept */
+     199          69 :     const double slope = num * idev2x;
+     200          69 :     const double inter = (scy - slope * scx)/ns;
+     201             : 
+     202          69 :     Value* valuea=getPntrToComponent("sqdevsum");
+     203          69 :     Value* valueb=getPntrToComponent("corr");
+     204          69 :     Value* valuec=getPntrToComponent("slope");
+     205         138 :     Value* valued=getPntrToComponent("intercept");
+     206             : 
+     207             :     valuea->set(nsqd);
+     208             :     valueb->set(correlation);
+     209             :     valuec->set(slope);
+     210             :     valued->set(inter);
+     211             : 
+     212             :     /* derivatives */
+     213        6230 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     214        6161 :       const double common_d1 = (ns*parameters[i]-scy)*idevx;
+     215        6161 :       const double common_d2 = num*(ns*getArgument(i)-scx)*idev2x*idevx;
+     216        6161 :       const double common_d3 = common_d1 - common_d2;
+     217             : 
+     218             :       /* sqdevsum */
+     219        6161 :       const double sq_der = 2.*(getArgument(i)-parameters[i]);
+     220             :       /* correlation */
+     221        6161 :       const double co_der = common_d3*idevy;
+     222             :       /* slope */
+     223        6161 :       const double sl_der = (common_d1-2.*common_d2)*idevx;
+     224             :       /* intercept */
+     225        6161 :       const double int_der = -(slope+ scx*sl_der)/ns;
+     226             : 
+     227             :       setDerivative(valuea,i,sq_der);
+     228             :       setDerivative(valueb,i,co_der);
+     229             :       setDerivative(valuec,i,sl_der);
+     230             :       setDerivative(valued,i,int_der);
+     231             :     }
+     232             : 
+     233             :   }
+     234         122 : }
+     235             : 
+     236             : }
+     237             : }
+     238             : 
+     239             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.func-sort-c.html b/coverage/function/Target.cpp.func-sort-c.html new file mode 100644 index 0000000000..414564ece4 --- /dev/null +++ b/coverage/function/Target.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.func.html b/coverage/function/Target.cpp.func.html new file mode 100644 index 0000000000..73cbd8f3ab --- /dev/null +++ b/coverage/function/Target.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe1086createERKNS_13ActionOptionsE0
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108C2Ev4168
_ZN4PLMD8function12_GLOBAL__N_119TargetRegisterMe108D2Ev4168
_ZN4PLMD8function6Target16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function6Target9calculateEv0
_ZN4PLMD8function6TargetC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function6TargetC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.gcov.html b/coverage/function/Target.cpp.gcov.html new file mode 100644 index 0000000000..72bf4e25a3 --- /dev/null +++ b/coverage/function/Target.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(Target,"TARGET")
+     109             : 
+     110           2 : void Target::registerKeywords(Keywords& keys) {
+     111           2 :   Function::registerKeywords(keys);
+     112           4 :   keys.add("compulsory","TYPE","EUCLIDEAN","the manner in which the distance should be calculated");
+     113           4 :   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           2 : }
+     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.16
+
+ + + diff --git a/coverage/function/index-sort-f.html b/coverage/function/index-sort-f.html new file mode 100644 index 0000000000..efd1887b13 --- /dev/null +++ b/coverage/function/index-sort-f.html @@ -0,0 +1,213 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:909105885.9 %
Date:2024-05-27 13:05: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
Ensemble.cpp +
63.1%63.1%
+
63.1 %82 / 13085.7 %6 / 7
Combine.cpp +
93.6%93.6%
+
93.6 %44 / 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
LocalEnsemble.cpp +
100.0%
+
100.0 %32 / 3285.7 %6 / 7
Piecewise.cpp +
100.0%
+
100.0 %47 / 4785.7 %6 / 7
FuncSumHills.cpp +
89.9%89.9%
+
89.9 %295 / 32886.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.16
+
+ + + diff --git a/coverage/function/index-sort-l.html b/coverage/function/index-sort-l.html new file mode 100644 index 0000000000..e1d5267397 --- /dev/null +++ b/coverage/function/index-sort-l.html @@ -0,0 +1,213 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:909105885.9 %
Date:2024-05-27 13:05: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 +
89.9%89.9%
+
89.9 %295 / 32886.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.16
+
+ + + diff --git a/coverage/function/index.html b/coverage/function/index.html new file mode 100644 index 0000000000..a992414a4c --- /dev/null +++ b/coverage/function/index.html @@ -0,0 +1,213 @@ + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:909105885.9 %
Date:2024-05-27 13:05: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 +
89.9%89.9%
+
89.9 %295 / 32886.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.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func-sort-c.html b/coverage/funnel/FPS.cpp.func-sort-c.html new file mode 100644 index 0000000000..a4594f7cb6 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:9610096.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe1186createERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe118C2Ev4168
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe118D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func.html b/coverage/funnel/FPS.cpp.func.html new file mode 100644 index 0000000000..06dfc28e1c --- /dev/null +++ b/coverage/funnel/FPS.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:9610096.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe1186createERKNS_13ActionOptionsE5
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe118C2Ev4168
_ZN4PLMD6funnel12_GLOBAL__N_122FUNNEL_PSRegisterMe118D2Ev4168
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.gcov.html b/coverage/funnel/FPS.cpp.gcov.html new file mode 100644 index 0000000000..d71c7c259c --- /dev/null +++ b/coverage/funnel/FPS.cpp.gcov.html @@ -0,0 +1,397 @@ + + + + + + + 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:9610096.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ + + + + + + + +

+
          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             : };
+     115             : 
+     116             : using namespace std;
+     117             : 
+     118       12514 : PLUMED_REGISTER_ACTION(FUNNEL_PS,"FUNNEL_PS")
+     119             : 
+     120           7 : void FUNNEL_PS::registerKeywords(Keywords& keys) {
+     121           7 :   Colvar::registerKeywords( keys );
+     122          14 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the structure you would like to align.");
+     123          14 :   keys.add("atoms","LIGAND","This MUST be a single atom, normally the COM of the ligand");
+     124          14 :   keys.add("atoms","ANCHOR","Closest protein atom to the ligand, picked to avoid pbc problems during the simulation");
+     125          14 :   keys.add("compulsory","POINTS","6 values defining x, y, and z of the 2 points used to construct the line. The order should be A_x,A_y,A_z,B_x,B_y,B_z.");
+     126          14 :   keys.addFlag("SQUARED-ROOT",false,"Used to initialize the creation of the alignment variable");
+     127          14 :   keys.addOutputComponent("lp","default","the position along the funnel line");
+     128          14 :   keys.addOutputComponent("ld","default","the distance from the funnel line");
+     129           7 : }
+     130             : 
+     131           5 : FUNNEL_PS::FUNNEL_PS(const ActionOptions&ao):
+     132             :   PLUMED_COLVAR_INIT(ao),
+     133           5 :   pbc(true),squared(true)
+     134             : {
+     135             :   string reference;
+     136          10 :   parse("REFERENCE",reference);
+     137             :   string type;
+     138           5 :   type.assign("OPTIMAL");
+     139          10 :   parseAtomList("LIGAND",ligand_com);
+     140           5 :   if(ligand_com.size()!=1)
+     141           0 :     error("Number of specified atoms should be one, normally the COM of the ligand");
+     142           5 :   parseVector("POINTS",points);
+     143           5 :   bool nopbc=!pbc;
+     144           5 :   parseFlag("NOPBC",nopbc);
+     145           5 :   pbc=!nopbc;
+     146             :   bool sq;
+     147           5 :   parseFlag("SQUARED-ROOT",sq);
+     148           5 :   if (sq) {
+     149           0 :     squared=false;
+     150             :   }
+     151           5 :   parseAtomList("ANCHOR",anchor);
+     152           5 :   checkRead();
+     153             : 
+     154             :   // read everything in ang and transform to nm if we are not in natural units
+     155          10 :   if( !pdb.read(reference,plumed.getAtoms().usingNaturalUnits(),0.1/ActionAtomistic::atoms.getUnits().getLength()) )
+     156           0 :     error("missing input file " + reference );
+     157             : 
+     158             :   bool remove_com=true;
+     159             :   bool normalize_weights=true;
+     160             :   // here displace is a simple vector of ones
+     161           5 :   align=pdb.getOccupancy();
+     162       16195 :   for(unsigned i=0; i<align.size(); i++) {
+     163       16190 :     align[i]=1.;
+     164             :   } ;
+     165           5 :   displace=pdb.getBeta();
+     166       16195 :   for(unsigned i=0; i<displace.size(); i++) {
+     167       16190 :     displace[i]=1.;
+     168             :   } ;
+     169             :   // reset again to reimpose uniform weights (safe to disable this)
+     170           5 :   alignment.set(align,displace,pdb.getPositions(),type,remove_com,normalize_weights);
+     171             : 
+     172             : 
+     173             : 
+     174             :   // Array with inside both the structure to align and the atom to be aligned
+     175           5 :   numbers=pdb.getAtomNumbers();
+     176           5 :   numbers.push_back(anchor[0]);
+     177           5 :   numbers.push_back(ligand_com[0]);
+     178             : 
+     179           5 :   log.printf("  average from file %s\n",reference.c_str());
+     180           5 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     181             : 
+     182           5 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     183           0 :   else    log.printf("  without periodic boundary conditions\n");
+     184             : 
+     185           5 :   addComponentWithDerivatives("lp");
+     186           5 :   componentIsNotPeriodic("lp");
+     187           5 :   addComponentWithDerivatives("ld");
+     188           5 :   componentIsNotPeriodic("ld");
+     189             : 
+     190           5 :   requestAtoms( numbers );
+     191             : 
+     192           5 : }
+     193             : 
+     194             : // calculator
+     195         150 : void FUNNEL_PS::calculate() {
+     196             : 
+     197         150 :   if(pbc) makeWhole();
+     198             : 
+     199         150 :   Tensor Rotation;
+     200             :   Matrix<std::vector<Vector> > drotdpos(3,3);
+     201             :   std::vector<Vector> alignedpos;
+     202             :   std::vector<Vector> centeredpos;
+     203             :   std::vector<Vector> centeredref;
+     204             :   std::vector<Vector> ddistdpos;
+     205             : 
+     206             :   std::vector<Vector> buffer;
+     207             : 
+     208         150 :   Vector centerreference;
+     209         150 :   Vector centerpositions;
+     210             : 
+     211             :   // Created only to give the correct object to calc_FitElements
+     212             :   std::vector<Vector> sourceAllPositions;
+     213             :   std::vector<Vector> sourcePositions;
+     214             : 
+     215             :   // SourcePositions contains only the coordinates of the COM of the ligand, we need only this point
+     216         150 :   sourceAllPositions=getPositions();
+     217         150 :   sourcePositions=sourceAllPositions;
+     218         150 :   sourcePositions.resize(sourcePositions.size()-2);// just the protein
+     219             : 
+     220             :   // The two points that define the axis : this can be moved in the initialization
+     221         150 :   Vector p1 = VectorGeneric<3>(points[0],points[1],points[2]);
+     222         150 :   Vector p2 = VectorGeneric<3>(points[3],points[4],points[5]);
+     223         150 :   Vector s = p2 - p1;
+     224             : 
+     225             :   // I call the method calc_FitElements that initializes all feature that I need
+     226             :   // except for centerreference that I need to calculate from scratch
+     227             :   // Buffer has no meaning but I had to fulfill the requirements of calc_FitElements
+     228         150 :   double rmsd = alignment.calc_FitElements( sourcePositions, Rotation, drotdpos, buffer, centerpositions, squared);
+     229             : 
+     230             :   // To Plumed developers: it would be interesting to make the functions to calculate centers of mass public or protected
+     231         150 :   centerreference.zero();
+     232      485850 :   for(unsigned i=0; i<pdb.size(); i++) {
+     233      485700 :     centerreference+=pdb.getPositions()[i]*align[i]/align.size();
+     234             :   }
+     235             : 
+     236             :   /*
+     237             :   // I cancelled the additional lines in the library of RMSD.h, thus I am missing the center of the reference
+     238             :   // Creating variable kito to extract only the center of the reference, since no method is calling
+     239             :   // function getReferenceCenter()
+     240             :   PLMD::RMSDCoreData* kito; kito = new RMSDCoreData(align,displace,sourcePositions,pdb->getPositions());
+     241             :   centerreference = kito->getReferenceCenter();
+     242             :   delete kito;
+     243             :   */
+     244             : 
+     245             :   // DEBUG
+     246             :   /*    log.printf(" RMSD: %13.6lf\n",rmsd );
+     247             :       log.printf(" cpos: %13.6lf %13.6lf %13.6lf\n",centerpositions[0],centerpositions[1],centerpositions[2] );
+     248             :       log.printf(" Rotation: %13.6lf %13.6lf %13.6lf\n",Rotation[0][0],Rotation[0][1],Rotation[0][2] );
+     249             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[1][0],Rotation[1][1],Rotation[1][2] );
+     250             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[2][0],Rotation[2][1],Rotation[2][2] );
+     251             :   */
+     252             : 
+     253             :   // the position is   Rot(ligand-com_prot_md)+ com_prot_ref
+     254         150 :   Vector ligand_centered =getPositions().back()-centerpositions;
+     255         150 :   Vector ligand_aligned =matmul(Rotation,ligand_centered);
+     256         150 :   Vector v = ligand_aligned +centerreference -p1;
+     257             : 
+     258             :   // DEBUG
+     259             : //    log.printf(" ligando: %13.6lf %13.6lf %13.6lf\n",getPositions().back()[0],getPositions().back()[1],getPositions().back()[2] );
+     260             : 
+     261             :   //Projection vector v onto s
+     262             : 
+     263         150 :   Vector prj = (dotProduct(s,v)/dotProduct(s,s))*s;
+     264         150 :   const double prj_length = prj.modulo() ;
+     265             :   const double inv_prj_length = 1.0/prj_length;
+     266             : 
+     267         150 :   Vector height = v - prj;
+     268         150 :   const double prj_height = height.modulo() ;
+     269         150 :   const double inv_prj_height = 1.0/prj_height;
+     270             : 
+     271             :   // derivative of the prj: only on the com of the ligand
+     272         150 :   Vector der_prj;
+     273         150 :   der_prj=s/s.modulo();
+     274             : 
+     275             :   // derivative of the height: only on the com of the ligand
+     276         150 :   Vector der_height(inv_prj_height*(height[0]-(s[0]/s.modulo2())*dotProduct(height,s)),
+     277         150 :                     inv_prj_height*(height[1]-(s[1]/s.modulo2())*dotProduct(height,s)),
+     278         150 :                     inv_prj_height*(height[2]-(s[2]/s.modulo2())*dotProduct(height,s)));
+     279             : 
+     280         150 :   Value* valuelp=getPntrToComponent("lp");
+     281         150 :   Value* valueld=getPntrToComponent("ld");
+     282         150 :   valuelp->set(dotProduct(s,v)/s.modulo()); // this includes the sign
+     283             :   valueld->set(prj_height);
+     284             : 
+     285             :   // DEBUG
+     286             : //    log.printf(" Dopo: %13.6lf  %13.6lf\n",dotProduct(s,v)/s.modulo(),prj_height );
+     287             : 
+     288         150 :   setAtomsDerivatives(valuelp,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_prj));
+     289         150 :   setAtomsDerivatives(valueld,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_height));
+     290             : 
+     291         150 :   Vector der_h;
+     292         150 :   Vector der_l;
+     293         150 :   double weight=1./float(getNumberOfAtoms()-2.);
+     294             : 
+     295      485850 :   for(unsigned iat=0; iat<getNumberOfAtoms()-2; iat++) {
+     296      485700 :     der_h.zero();
+     297      485700 :     der_l.zero();
+     298     1942800 :     for(unsigned a=0; a<3; a++) {
+     299     5828400 :       for(unsigned b=0; b<3; b++) {
+     300    17485200 :         for(unsigned g=0; g<3; g++) {
+     301    13113900 :           der_h[a]+=der_height[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     302    13113900 :           der_l[a]+=der_prj[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     303             :         }
+     304     4371300 :         der_h[a]-=der_height[b]*Rotation[b][a]*weight;
+     305     4371300 :         der_l[a]-=der_prj[b]*Rotation[b][a]*weight;
+     306             :       }
+     307             :     }
+     308      485700 :     setAtomsDerivatives(valuelp,iat,der_l);
+     309      485700 :     setAtomsDerivatives(valueld,iat,der_h);
+     310             :   }
+     311             : 
+     312         150 :   setBoxDerivativesNoPbc(valuelp);
+     313         150 :   setBoxDerivativesNoPbc(valueld);
+     314             : 
+     315         150 : }
+     316             : 
+     317             : }
+     318             : }
+     319             : 
+     320             : 
+     321             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func-sort-c.html b/coverage/funnel/Funnel.cpp.func-sort-c.html new file mode 100644 index 0000000000..3ddf8af84d --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143C2Ev4168
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func.html b/coverage/funnel/Funnel.cpp.func.html new file mode 100644 index 0000000000..33805591ea --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe1436createERKNS_13ActionOptionsE4
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143C2Ev4168
_ZN4PLMD6funnel12_GLOBAL__N_119FunnelRegisterMe143D2Ev4168
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.gcov.html b/coverage/funnel/Funnel.cpp.gcov.html new file mode 100644 index 0000000000..bfdc01dea3 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.gcov.html @@ -0,0 +1,528 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(Funnel,"FUNNEL")
+     144             : 
+     145           6 : void Funnel::registerKeywords(Keywords& keys) {
+     146           6 :   Bias::registerKeywords(keys);
+     147           6 :   keys.use("ARG");
+     148          12 :   keys.addFlag("NOSPLINE",false,"specifies that no spline interpolation is to be used when calculating the energy and forces due to the external potential");
+     149          12 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     150          12 :   keys.addFlag("SPHERE",false, "The Funnel potential including the binding site can be spherical instead of a cone");
+     151          12 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     152             : // old stuff?
+     153             :   //  componentsAreNotOptional(keys);
+     154             :   //  keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     155             : 
+     156             :   //Defining optional arguments
+     157          12 :   keys.add("optional","NBINS","number of bins along fps.lp");
+     158          12 :   keys.add("optional","NBINZ","number of bins along fps.ld");
+     159          12 :   keys.add("optional","MINS","minimum value assumed by fps.lp, if the ligand is able to go beyond this value the simulation will crash");
+     160          12 :   keys.add("optional","KAPPA","constant to be used for the funnel-shape restraint potential");
+     161          12 :   keys.add("optional","RCYL","radius of the cylindrical section");
+     162          12 :   keys.add("optional","SAFETY","To be used in case the SPHERE flag is chosen, it regulates how much the potential extends (in nm)");
+     163          12 :   keys.add("optional","SLOPE","Adjust the behavior of the potential outside the funnel, greater values than 1.0 will tend to push the ligand more towards the cylinder and vice versa");
+     164          12 :   keys.add("optional","ALPHA","angle to change the width of the cone section");
+     165             :   //Defining compulsory arguments
+     166          12 :   keys.add("compulsory","MAXS","MAXS","maximum value assumed by fps.lp");
+     167          12 :   keys.add("compulsory","ZCC","ZCC","switching point between cylinder and cone");
+     168          12 :   keys.add("compulsory","FILE","name of the Funnel potential file");
+     169          12 :   keys.addFlag("WALKERS_MPI",false,"To be used when gromacs + multiple walkers are used");
+     170           6 : }
+     171             : 
+     172             : // Old version 2.3
+     173             : //Funnel::~Funnel(){
+     174             : //  delete BiasGrid_;
+     175             : //}
+     176             : 
+     177           4 : Funnel::Funnel(const ActionOptions& ao):
+     178             :   PLUMED_BIAS_INIT(ao),
+     179             : // Old version 2.3
+     180             : // BiasGrid_(NULL),
+     181           4 :   NBINS(500.0),
+     182           4 :   NBINZ(500.0),
+     183           4 :   MINS(0.0),
+     184           4 :   KAPPA(84.0),
+     185           4 :   RCYL(0.1),
+     186           4 :   safety(1.0),
+     187           4 :   slope(1.0),
+     188           4 :   ALPHA(1.413)
+     189             : 
+     190             : {
+     191           4 :   bool sparsegrid=false;
+     192           4 :   parseFlag("SPARSE",sparsegrid);
+     193           4 :   bool nospline=false;
+     194           4 :   parseFlag("NOSPLINE",nospline);
+     195           4 :   bool spline=!nospline;
+     196           4 :   bool walkers_mpi=false;
+     197           4 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     198             : //  bool components=false;
+     199             : //  parseFlag("POINTS",components);
+     200           4 :   bool sphere=false;
+     201           4 :   parseFlag("SPHERE",sphere);
+     202           8 :   parse("SAFETY",safety);
+     203             :   string file;
+     204           8 :   parse("FILE",file);
+     205           4 :   if( file.length()==0 ) error("No funnel file name was specified");
+     206           4 :   parse("SCALE",scale_);
+     207             : 
+     208             :   //Reading optional arguments
+     209           4 :   parse("KAPPA",KAPPA);
+     210           4 :   parse("NBINS",NBINS);
+     211           4 :   parse("NBINZ",NBINZ);
+     212           4 :   parse("MINS",MINS);
+     213           4 :   parse("RCYL",RCYL);
+     214           4 :   parse("SLOPE",slope);
+     215           4 :   parse("ALPHA",ALPHA);
+     216             :   //Reading compulsory arguments
+     217           4 :   parse("MAXS",MAXS);
+     218           4 :   parse("ZCC",ZCC);
+     219             : 
+     220             : 
+     221           4 :   checkRead();
+     222             : 
+     223           4 :   log.printf("  External potential from file %s\n",file.c_str());
+     224           4 :   log.printf("  Multiplied by %lf\n",scale_);
+     225           4 :   if(spline) {
+     226           4 :     log.printf("  External potential uses spline interpolation\n");
+     227             :   }
+     228           4 :   if(sparsegrid) {
+     229           0 :     log.printf("  External potential uses sparse grid\n");
+     230             :   }
+     231             : 
+     232             :   // Non più necessario dalla 2.3
+     233             : //  addComponent("bias"); componentIsNotPeriodic("bias");
+     234             : 
+     235           4 :   std::string funcl=getLabel() + ".bias";
+     236             : 
+     237             : //  int size = plumed.comm.Get_size();
+     238             : //  int rank = plumed.comm.Get_rank();
+     239           4 :   IFile I_hate_this;
+     240           4 :   bool do_exist=I_hate_this.FileExist(file);
+     241             : 
+     242           4 :   if(walkers_mpi) {
+     243           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()==0) {
+     244           1 :       if(!do_exist) {
+     245           1 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     246             :       }
+     247             :     }
+     248           2 :     multi_sim_comm.Barrier();
+     249             :   } else {
+     250           2 :     if(comm.Get_rank()==0) {
+     251           2 :       if(!do_exist) {
+     252           2 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     253             :       }
+     254             :     }
+     255             :   }
+     256             : 
+     257             :   /*
+     258             :   if(comm.Get_rank()==0){
+     259             :     if(multi_sim_comm.Get_rank()==0 && walkers_mpi){
+     260             :           if(!do_exist){
+     261             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     262             :           }
+     263             :     } else {
+     264             :           if(!do_exist){
+     265             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     266             :           }
+     267             :     }
+     268             :     if(walkers_mpi) multi_sim_comm.Barrier();
+     269             :   }
+     270             :   */
+     271           4 :   comm.Barrier();
+     272             : 
+     273             : // read grid
+     274           4 :   IFile gridfile;
+     275           4 :   gridfile.open(file);
+     276           8 :   BiasGrid_=Grid::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     277             : //not necessary anymore?  gridfile.close();
+     278           4 :   if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+     279          12 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     280          16 :     if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+     281             :   }
+     282           4 :   comm.Barrier();
+     283           4 :   if(comm.Get_rank()==0 && walkers_mpi) multi_sim_comm.Barrier();
+     284           8 :   log<<"  Bibliography "<<plumed.cite("Limongelli, Bonomi, and Parrinello, PNAS 110, 6358 (2013)")<<"\n";
+     285           8 : }
+     286             : 
+     287             : 
+     288           3 : void Funnel::createBIAS(const double& R_cyl, const double& z_cc, const double& alpha,
+     289             :                         const double& KAPPA, const double& MIN_S, const double& MAX_S, const double& NBIN_S,
+     290             :                         const double& NBIN_Z, const double& safety, const bool& sphere, const double& slope,
+     291             :                         const string& funcl, const string& file) {
+     292             :   //R_cyl and z_cc forms the parameters of the cylinder.
+     293             :   //alpha defines the angle in degrees.
+     294             : 
+     295             :   //PARAMETERS OF THE CONE
+     296           3 :   double tg_alpha= tan(alpha);
+     297             : 
+     298             :   //parameters for PROGRESSION
+     299             :   //parameters for DISTANCE
+     300             :   double MIN_Z=0;
+     301             :   double MAX_Z;
+     302           3 :   if (sphere==false) {
+     303           2 :     MAX_Z=R_cyl + tg_alpha * (z_cc - MIN_S);
+     304             :   }
+     305             :   else {
+     306           1 :     MAX_Z=z_cc+safety;
+     307             :   }
+     308             : 
+     309             :   //bin size
+     310           3 :   double DX_Z = (MAX_Z - MIN_Z) / NBIN_Z;
+     311             :   double DX_S;
+     312           3 :   if (sphere==false) {
+     313           2 :     DX_S=(MAX_S - MIN_S) / NBIN_S;
+     314             :   }
+     315             :   else {
+     316           1 :     DX_S=(MAX_S + z_cc + safety)/NBIN_S;
+     317             :   }
+     318             : 
+     319             :   double SS, Zmax, ZZ, D, d;
+     320             :   double POT, FZ, FS;
+     321             : 
+     322           3 :   PLMD::OFile pof;
+     323           3 :   pof.open(file);
+     324             : 
+     325             :   //Write the header
+     326           3 :   pof.printf("#! FIELDS %s %s %s der_%s der_%s \n", getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str(), funcl.c_str(), getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str());
+     327           3 :   if (sphere==false) pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), MIN_S);
+     328           1 :   else pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), -z_cc-safety);
+     329           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(0)->getName().c_str(), MAX_S);
+     330           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(0)->getName().c_str(), NBIN_S);
+     331           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(0)->getName().c_str());
+     332           3 :   pof.printf("#! SET min_%s %f\n", getPntrToArgument(1)->getName().c_str(), MIN_Z);
+     333           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(1)->getName().c_str(), MAX_Z);
+     334           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(1)->getName().c_str(), NBIN_Z);
+     335           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(1)->getName().c_str());
+     336             : 
+     337             :   //Calculate and write the GRID
+     338             :   //Cone or cylinder?
+     339             : 
+     340        1506 :   for(int is=0; is <= NBIN_S; is++) {
+     341        1503 :     if (sphere==false) {
+     342        1002 :       SS = MIN_S + is * DX_S;
+     343             :     }
+     344             :     else {
+     345         501 :       SS = - z_cc - safety + is * DX_S;
+     346             :     }
+     347             :     bool cone = false;
+     348        1503 :     if (sphere==false) {
+     349        1002 :       if(SS <= z_cc) cone = true;
+     350             :     }
+     351             :     else {
+     352         501 :       if (SS <= sqrt(pow(z_cc,2)-pow(R_cyl,2))) cone = true;
+     353             :     }
+     354             :     //Set wall boundaries properly
+     355             :     if(cone == true) {
+     356         902 :       if(sphere==false) {
+     357         548 :         Zmax = R_cyl + (z_cc - SS) * tg_alpha;
+     358             :       }
+     359             :       else {
+     360         354 :         if (SS > -z_cc) {
+     361         277 :           Zmax = sqrt(pow(z_cc,2) - pow(SS,2));
+     362             :         }
+     363             :         else {
+     364             :           Zmax = 0;
+     365             :         }
+     366             :       }
+     367             :     }
+     368         601 :     else Zmax = R_cyl;
+     369             : 
+     370      754506 :     for(int iz=0; iz <= NBIN_Z; iz++) {
+     371      753003 :       ZZ = MIN_Z + iz * DX_Z;
+     372             : 
+     373             :       //Inside or outside?
+     374             :       bool inside;
+     375      753003 :       if(ZZ < Zmax) inside = true;
+     376             :       else inside = false;
+     377             : 
+     378             :       if(inside == true) {
+     379             :         POT = 0;
+     380             :         FS = 0;
+     381             :         FZ = 0;
+     382             :       }
+     383             :       else {
+     384      518149 :         if(cone == true) {
+     385      235130 :           if(sphere==false) {
+     386      127824 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     387      127824 :             FZ = - KAPPA * (ZZ - Zmax);
+     388      127824 :             FS = - KAPPA * (ZZ - Zmax) * tg_alpha;
+     389             :           }
+     390             :           else {
+     391      107306 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     392      107306 :             d = D - z_cc;
+     393      107306 :             POT = 0.5 * KAPPA * pow(d,2);
+     394      107306 :             FZ = - KAPPA * d * ZZ / D;
+     395      107306 :             FS = - KAPPA * d * SS / D;
+     396             :           }
+     397             :         }
+     398             :         else {
+     399      283019 :           if(sphere==false) {
+     400      212018 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     401      212018 :             FZ = - KAPPA * (ZZ - Zmax);
+     402             :             FS = 0;
+     403             :           }
+     404             :           else {
+     405       71001 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     406       71001 :             d = D - z_cc;
+     407       71001 :             if(ZZ>=R_cyl+slope*(SS-z_cc)) {
+     408       45984 :               POT = 0.5 * KAPPA * pow(d,2);
+     409       45984 :               FZ = - KAPPA * d * ZZ / D;
+     410       45984 :               FS = - KAPPA * d * SS / D;
+     411             :             }
+     412             :             else {
+     413       25017 :               POT = 0.5 * KAPPA * pow(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-
+     414             :                                       z_cc,2);
+     415       25017 :               FZ = - KAPPA*(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-z_cc)*
+     416       25017 :                    ZZ/sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2));
+     417             :               FS = 0;
+     418             :             }
+     419             :           }
+     420             :         }
+     421             :       }
+     422      753003 :       pof.printf("%13.6lf %13.6lf %13.6lf %13.6lf %13.6lf\n", SS, ZZ, POT, FS, FZ);
+     423             :     }
+     424        1503 :     pof.printf("\n");
+     425             :   }
+     426           3 :   pof.close();
+     427           3 : }
+     428             : 
+     429         120 : void Funnel::calculate()
+     430             : {
+     431         120 :   unsigned ncv=getNumberOfArguments();
+     432         120 :   vector<double> cv(ncv), der(ncv);
+     433             : 
+     434         360 :   for(unsigned i=0; i<ncv; ++i) {
+     435         240 :     cv[i]=getArgument(i);
+     436             :   }
+     437             : 
+     438             : //  log.printf("  In Funnel: %13.6lf  %13.6lf\n", cv[0], cv[1]);
+     439             : 
+     440         120 :   double ene=scale_*BiasGrid_->getValueAndDerivatives(cv,der);
+     441             : 
+     442             :   setBias(ene);
+     443             : 
+     444             : // set Forces
+     445         360 :   for(unsigned i=0; i<ncv; ++i) {
+     446         240 :     const double f=-scale_*der[i];
+     447         240 :     setOutputForce(i,f);
+     448             :   }
+     449         120 : }
+     450             : 
+     451             : }
+     452             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-f.html b/coverage/funnel/index-sort-f.html new file mode 100644 index 0000000000..1f9530f0b9 --- /dev/null +++ b/coverage/funnel/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24825398.0 %
Date:2024-05-27 13:05:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-l.html b/coverage/funnel/index-sort-l.html new file mode 100644 index 0000000000..08e97e2a6f --- /dev/null +++ b/coverage/funnel/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24825398.0 %
Date:2024-05-27 13:05:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index.html b/coverage/funnel/index.html new file mode 100644 index 0000000000..adef72d71d --- /dev/null +++ b/coverage/funnel/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24825398.0 %
Date:2024-05-27 13:05:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %96 / 10085.7 %6 / 7
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15387.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gcov.css b/coverage/gcov.css new file mode 100644 index 0000000000..0fcdff13ce --- /dev/null +++ b/coverage/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: #000000; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #b5f7af; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} diff --git a/coverage/generic/Debug.cpp.func-sort-c.html b/coverage/generic/Debug.cpp.func-sort-c.html new file mode 100644 index 0000000000..96e607898d --- /dev/null +++ b/coverage/generic/Debug.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe636createERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.func.html b/coverage/generic/Debug.cpp.func.html new file mode 100644 index 0000000000..fe31d5f722 --- /dev/null +++ b/coverage/generic/Debug.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe636createERKNS_13ActionOptionsE6
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117DebugRegisterMe63D2Ev4168
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.gcov.html b/coverage/generic/Debug.cpp.gcov.html new file mode 100644 index 0000000000..aa5774e760 --- /dev/null +++ b/coverage/generic/Debug.cpp.gcov.html @@ -0,0 +1,216 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(Debug,"DEBUG")
+      64             : 
+      65           8 : void Debug::registerKeywords( Keywords& keys ) {
+      66           8 :   Action::registerKeywords( keys );
+      67           8 :   ActionPilot::registerKeywords(keys);
+      68          16 :   keys.add("compulsory","STRIDE","1","the frequency with which this action is to be performed");
+      69          16 :   keys.addFlag("logActivity",false,"write in the log which actions are inactive and which are inactive");
+      70          16 :   keys.addFlag("logRequestedAtoms",false,"write in the log which atoms have been requested at a given time");
+      71          16 :   keys.addFlag("NOVIRIAL",false,"switch off the virial contribution for the entirety of the simulation");
+      72          16 :   keys.addFlag("DETAILED_TIMERS",false,"switch on detailed timers");
+      73          16 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      74           8 : }
+      75             : 
+      76           6 : Debug::Debug(const ActionOptions&ao):
+      77             :   Action(ao),
+      78             :   ActionPilot(ao),
+      79           6 :   logActivity(false),
+      80           6 :   logRequestedAtoms(false),
+      81           6 :   novirial(false) {
+      82           6 :   parseFlag("logActivity",logActivity);
+      83           6 :   if(logActivity) log.printf("  logging activity\n");
+      84           6 :   parseFlag("logRequestedAtoms",logRequestedAtoms);
+      85           6 :   if(logRequestedAtoms) log.printf("  logging requested atoms\n");
+      86           6 :   parseFlag("NOVIRIAL",novirial);
+      87           6 :   if(novirial) log.printf("  Switching off virial contribution\n");
+      88           6 :   if(novirial) plumed.novirial=true;
+      89           6 :   parseFlag("DETAILED_TIMERS",detailedTimers);
+      90           6 :   if(detailedTimers) {
+      91           2 :     log.printf("  Detailed timing on\n");
+      92           2 :     plumed.detailedTimers=true;
+      93             :   }
+      94           6 :   ofile.link(*this);
+      95             :   std::string file;
+      96          12 :   parse("FILE",file);
+      97           6 :   if(file.length()>0) {
+      98           2 :     ofile.open(file);
+      99           2 :     log.printf("  on file %s\n",file.c_str());
+     100             :   } else {
+     101           4 :     log.printf("  on plumed log file\n");
+     102           4 :     ofile.link(log);
+     103             :   }
+     104           6 :   checkRead();
+     105           6 : }
+     106             : 
+     107         140 : void Debug::apply() {
+     108         140 :   if(logActivity) {
+     109          10 :     const ActionSet&actionSet(plumed.getActionSet());
+     110             :     int a=0;
+     111         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.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func-sort-c.html b/coverage/generic/DumpAtoms.cpp.func-sort-c.html new file mode 100644 index 0000000000..7ade82f419 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe1436createERKNS_13ActionOptionsE173
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE173
_ZN4PLMD7generic9DumpAtomsD0Ev173
_ZN4PLMD7generic9DumpAtomsD1Ev173
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE175
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143D2Ev4168
_ZN4PLMD7generic9DumpAtoms6updateEv8876
_ZN4PLMD7generic9DumpAtoms5applyEv8971
_ZN4PLMD7generic9DumpAtoms9calculateEv8971
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func.html b/coverage/generic/DumpAtoms.cpp.func.html new file mode 100644 index 0000000000..9a661b42d8 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe1436createERKNS_13ActionOptionsE173
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122DumpAtomsRegisterMe143D2Ev4168
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE175
_ZN4PLMD7generic9DumpAtoms5applyEv8971
_ZN4PLMD7generic9DumpAtoms6updateEv8876
_ZN4PLMD7generic9DumpAtoms9calculateEv8971
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE173
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD0Ev173
_ZN4PLMD7generic9DumpAtomsD1Ev173
_ZN4PLMD7generic9DumpAtomsD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.gcov.html b/coverage/generic/DumpAtoms.cpp.gcov.html new file mode 100644 index 0000000000..6756fa04c8 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.gcov.html @@ -0,0 +1,390 @@ + + + + + + + LCOV - plumed test coverage - generic/DumpAtoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912198.3 %
Date:2024-05-27 13:05: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        8971 :   void calculate() override {}
+     139        8971 :   void apply() override {}
+     140             :   void update() override ;
+     141             : };
+     142             : 
+     143       12850 : PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
+     144             : 
+     145         175 : void DumpAtoms::registerKeywords( Keywords& keys ) {
+     146         175 :   Action::registerKeywords( keys );
+     147         175 :   ActionPilot::registerKeywords( keys );
+     148         175 :   ActionAtomistic::registerKeywords( keys );
+     149         350 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     150         350 :   keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
+     151         350 :   keys.add("compulsory", "FILE", "file on which to output coordinates; extension is automatically detected");
+     152         350 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     153         350 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     154         350 :   keys.add("optional", "TYPE","file type, either xyz, gro, xtc, or trr, can override an automatically detected file extension");
+     155         175 :   keys.use("RESTART");
+     156         175 :   keys.use("UPDATE_FROM");
+     157         175 :   keys.use("UPDATE_UNTIL");
+     158         175 : }
+     159             : 
+     160         173 : DumpAtoms::DumpAtoms(const ActionOptions&ao):
+     161             :   Action(ao),
+     162             :   ActionAtomistic(ao),
+     163             :   ActionPilot(ao),
+     164         173 :   iprecision(3)
+     165             : {
+     166             :   std::vector<AtomNumber> atoms;
+     167             :   std::string file;
+     168         346 :   parse("FILE",file);
+     169         173 :   if(file.length()==0) error("name out output file was not specified");
+     170         173 :   type=Tools::extension(file);
+     171         173 :   log<<"  file name "<<file<<"\n";
+     172         345 :   if(type=="gro" || type=="xyz" || type=="xtc" || type=="trr") {
+     173         157 :     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         346 :   parse("TYPE",ntype);
+     180         173 :   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         346 :   parse("PRECISION",precision);
+     193         173 :   if(precision.length()>0) {
+     194          92 :     Tools::convert(precision,iprecision);
+     195          92 :     log<<"  with precision "<<iprecision<<"\n";
+     196             :     std::string a,b;
+     197          92 :     Tools::convert(iprecision+5,a);
+     198          92 :     Tools::convert(iprecision,b);
+     199         184 :     fmt_gro_pos="%"+a+"."+b+"f";
+     200             :     fmt_gro_box=fmt_gro_pos;
+     201             :     fmt_xyz=fmt_gro_box;
+     202             :   }
+     203             : 
+     204         346 :   parseAtomList("ATOMS",atoms);
+     205             : 
+     206         346 :   std::string unitname; parse("UNITS",unitname);
+     207         173 :   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         413 :   } else if(type=="gro" || type=="xtc" || type=="trr") lenunit=plumed.getAtoms().getUnits().getLength();
+     214         113 :   else lenunit=1.0;
+     215             : 
+     216         173 :   checkRead();
+     217         173 :   of.link(*this);
+     218         173 :   of.open(file);
+     219             :   std::string path=of.getPath();
+     220         173 :   log<<"  Writing on file "<<path<<"\n";
+     221             :   std::string mode=of.getMode();
+     222         173 :   if(type=="xtc") {
+     223           6 :     of.close();
+     224           6 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     225         167 :   } else if(type=="trr") {
+     226           4 :     of.close();
+     227           4 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     228             :   }
+     229         173 :   log.printf("  printing the following atoms in %s :", unitname.c_str() );
+     230       18814 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     231         173 :   log.printf("\n");
+     232         173 :   requestAtoms(atoms);
+     233         173 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     234         173 :   if( moldat ) {
+     235          56 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     236          56 :     names.resize(atoms.size());
+     237        5835 :     for(unsigned i=0; i<atoms.size(); i++) if(atoms[i].index()<moldat->getPDBsize()) names[i]=moldat->getAtomName(atoms[i]);
+     238          56 :     residueNumbers.resize(atoms.size());
+     239        5835 :     for(unsigned i=0; i<residueNumbers.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNumbers[i]=moldat->getResidueNumber(atoms[i]);
+     240          56 :     residueNames.resize(atoms.size());
+     241        5835 :     for(unsigned i=0; i<residueNames.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNames[i]=moldat->getResidueName(atoms[i]);
+     242             :   }
+     243         173 : }
+     244             : 
+     245        8876 : void DumpAtoms::update() {
+     246        8876 :   if(type=="xyz") {
+     247        8290 :     of.printf("%d\n",getNumberOfAtoms());
+     248        8290 :     const Tensor & t(getPbc().getBox());
+     249        8290 :     if(getPbc().isOrthorombic()) {
+     250         348 :       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       16232 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     253        8116 :                 lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     254        8116 :                 lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     255        8116 :                 lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     256             :                );
+     257             :     }
+     258       52064 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     259             :       const char* defname="X";
+     260             :       const char* name=defname;
+     261       43774 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     262       87548 :       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             : // here we cannot use a std::vector<rvec> since it does not compile.
+     293             : // we thus use a std::unique_ptr<rvec[]>
+     294         120 :     auto pos = Tools::make_unique<xdrfile::rvec[]>(natoms);
+     295       25464 :     for(int i=0; i<natoms; i++) for(int j=0; j<3; j++) pos[i][j]=lenunit*getPosition(i)(j);
+     296         120 :     if(type=="xtc") {
+     297          72 :       write_xtc(xd,natoms,step,time,box,&pos[0],precision);
+     298          48 :     } else if(type=="trr") {
+     299          48 :       write_trr(xd,natoms,step,time,0.0,box,&pos[0],NULL,NULL);
+     300             :     }
+     301           0 :   } else plumed_merror("unknown file type "+type);
+     302        8876 : }
+     303             : 
+     304         346 : DumpAtoms::~DumpAtoms() {
+     305         173 :   if(type=="xtc") {
+     306           6 :     xdrfile_close(xd);
+     307         167 :   } else if(type=="trr") {
+     308           4 :     xdrfile_close(xd);
+     309             :   }
+     310         692 : }
+     311             : 
+     312             : 
+     313             : }
+     314             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func-sort-c.html b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html new file mode 100644 index 0000000000..95f750c9d9 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe716createERKNS_13ActionOptionsE282
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE282
_ZN4PLMD7generic15DumpDerivativesD0Ev282
_ZN4PLMD7generic15DumpDerivativesD1Ev282
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE284
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71D2Ev4168
_ZN4PLMD7generic15DumpDerivatives6updateEv13446
_ZN4PLMD7generic15DumpDerivatives5applyEv13461
_ZN4PLMD7generic15DumpDerivatives9calculateEv13503
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func.html b/coverage/generic/DumpDerivatives.cpp.func.html new file mode 100644 index 0000000000..c43210b671 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe716createERKNS_13ActionOptionsE282
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127DumpDerivativesRegisterMe71D2Ev4168
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE284
_ZN4PLMD7generic15DumpDerivatives5applyEv13461
_ZN4PLMD7generic15DumpDerivatives6updateEv13446
_ZN4PLMD7generic15DumpDerivatives9calculateEv13503
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE282
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD0Ev282
_ZN4PLMD7generic15DumpDerivativesD1Ev282
_ZN4PLMD7generic15DumpDerivativesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.gcov.html b/coverage/generic/DumpDerivatives.cpp.gcov.html new file mode 100644 index 0000000000..3164cb2fdd --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + 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-05-27 13:05: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       13503 :   void calculate() override {}
+      64             :   explicit DumpDerivatives(const ActionOptions&);
+      65             :   static void registerKeywords(Keywords& keys);
+      66       13461 :   void apply() override {}
+      67             :   void update() override;
+      68             :   ~DumpDerivatives();
+      69             : };
+      70             : 
+      71       13068 : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
+      72             : 
+      73         284 : void DumpDerivatives::registerKeywords(Keywords& keys) {
+      74         284 :   Action::registerKeywords(keys);
+      75         284 :   ActionPilot::registerKeywords(keys);
+      76         284 :   ActionWithArguments::registerKeywords(keys);
+      77         284 :   keys.use("ARG");
+      78         568 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      79         568 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      80         568 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      81         284 :   keys.use("RESTART");
+      82         284 :   keys.use("UPDATE_FROM");
+      83         284 :   keys.use("UPDATE_UNTIL");
+      84         284 : }
+      85             : 
+      86         282 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89             :   ActionWithArguments(ao),
+      90         282 :   fmt("%15.10f")
+      91             : {
+      92         564 :   parse("FILE",file);
+      93         282 :   if( file.length()==0 ) error("name of output file was not specified");
+      94         282 :   parse("FMT",fmt);
+      95         282 :   fmt=" "+fmt;
+      96         282 :   of.link(*this);
+      97         282 :   of.open(file);
+      98         282 :   log.printf("  on file %s\n",file.c_str());
+      99         282 :   log.printf("  with format %s\n",fmt.c_str());
+     100             :   unsigned nargs=getNumberOfArguments();
+     101         282 :   if( nargs==0 ) error("no arguments specified");
+     102         282 :   (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
+     103         282 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     104         282 :   if( npar==0 ) error("one or more arguments has no derivatives");
+     105         896 :   for(unsigned i=1; i<nargs; i++) {
+     106         614 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+     107         614 :     if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
+     108             :   }
+     109         282 :   checkRead();
+     110         282 : }
+     111             : 
+     112             : 
+     113       13446 : void DumpDerivatives::update() {
+     114       13446 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     115      915367 :   for(unsigned ipar=0; ipar<npar; ipar++) {
+     116      901921 :     of.fmtField(" %f");
+     117      901921 :     of.printField("time",getTime());
+     118      901921 :     of.printField("parameter",(int)ipar);
+     119     4516889 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     120     3614968 :       of.fmtField(fmt);
+     121     3614968 :       of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
+     122             :     }
+     123      901921 :     of.printField();
+     124             :   }
+     125       13446 : }
+     126             : 
+     127         564 : DumpDerivatives::~DumpDerivatives() {
+     128         564 : }
+     129             : 
+     130             : }
+     131             : 
+     132             : 
+     133             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func-sort-c.html b/coverage/generic/DumpForces.cpp.func-sort-c.html new file mode 100644 index 0000000000..a22acd33f1 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func.html b/coverage/generic/DumpForces.cpp.func.html new file mode 100644 index 0000000000..910ead1030 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe696createERKNS_13ActionOptionsE28
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122DumpForcesRegisterMe69D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.gcov.html b/coverage/generic/DumpForces.cpp.gcov.html new file mode 100644 index 0000000000..30c5a3c9d7 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + 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-05-27 13:05: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       12560 : PLUMED_REGISTER_ACTION(DumpForces,"DUMPFORCES")
+      70             : 
+      71          30 : void DumpForces::registerKeywords(Keywords& keys) {
+      72          30 :   Action::registerKeywords(keys);
+      73          30 :   ActionPilot::registerKeywords(keys);
+      74          30 :   ActionWithArguments::registerKeywords(keys);
+      75          30 :   keys.use("ARG");
+      76          60 :   keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
+      77          60 :   keys.add("compulsory","FILE","the name of the file on which to output the forces");
+      78          60 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      79          30 :   keys.use("RESTART");
+      80          30 :   keys.use("UPDATE_FROM");
+      81          30 :   keys.use("UPDATE_UNTIL");
+      82          30 : }
+      83             : 
+      84          28 : DumpForces::DumpForces(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   ActionPilot(ao),
+      87             :   ActionWithArguments(ao),
+      88          28 :   fmt("%15.10f")
+      89             : {
+      90          56 :   parse("FILE",file);
+      91          28 :   if( file.length()==0 ) error("name of file was not specified");
+      92          28 :   parse("FMT",fmt);
+      93          28 :   fmt=" "+fmt;
+      94          28 :   of.link(*this);
+      95          28 :   of.open(file);
+      96          28 :   log.printf("  on file %s\n",file.c_str());
+      97          28 :   log.printf("  with format %s\n",fmt.c_str());
+      98          28 :   if( getNumberOfArguments()==0 ) error("no arguments have been specified");
+      99          28 :   checkRead();
+     100          28 : }
+     101             : 
+     102             : 
+     103         400 : void DumpForces::update() {
+     104         400 :   of.fmtField(" %f");
+     105         400 :   of.printField("time",getTime());
+     106        4992 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     107        4592 :     of.fmtField(fmt);
+     108        4592 :     of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getForce());
+     109             :   }
+     110         400 :   of.printField();
+     111         400 : }
+     112             : 
+     113          56 : DumpForces::~DumpForces() {
+     114          56 : }
+     115             : 
+     116             : }
+     117             : 
+     118             : 
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func-sort-c.html b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html new file mode 100644 index 0000000000..c20f7b2ffc --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func.html b/coverage/generic/DumpMassCharge.cpp.func.html new file mode 100644 index 0000000000..87996e652a --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe966createERKNS_13ActionOptionsE12
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_126DumpMassChargeRegisterMe96D2Ev4168
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassChargeD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.gcov.html b/coverage/generic/DumpMassCharge.cpp.gcov.html new file mode 100644 index 0000000000..d091b186fd --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + 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-05-27 13:05: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       12528 : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE")
+      97             : 
+      98          14 : void DumpMassCharge::registerKeywords( Keywords& keys ) {
+      99          14 :   Action::registerKeywords( keys );
+     100          14 :   ActionPilot::registerKeywords( keys );
+     101          14 :   ActionAtomistic::registerKeywords( keys );
+     102          28 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     103          28 :   keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out");
+     104          28 :   keys.add("compulsory", "FILE", "file on which to output charges and masses.");
+     105          28 :   keys.addFlag("ONLY_MASSES",false,"Only output masses to file");
+     106          28 :   keys.addFlag("ONLY_CHARGES",false,"Only output charges to file");
+     107          14 : }
+     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        1006 :   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        1006 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     175         994 :     int ii=getAbsoluteIndex(i).index();
+     176         994 :     of.printField("index",ii);
+     177        1880 :     if(print_masses) {of.printField("mass",getMass(i));}
+     178        1880 :     if(print_charges) {of.printField("charge",getCharge(i));}
+     179         994 :     of.printField();
+     180             :   }
+     181          12 : }
+     182             : 
+     183          24 : DumpMassCharge::~DumpMassCharge() {
+     184          24 : }
+     185             : 
+     186             : 
+     187             : }
+     188             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func-sort-c.html b/coverage/generic/DumpProjections.cpp.func-sort-c.html new file mode 100644 index 0000000000..f5e4c48a14 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func.html b/coverage/generic/DumpProjections.cpp.func.html new file mode 100644 index 0000000000..bc74c27e05 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe676createERKNS_13ActionOptionsE1
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127DumpProjectionsRegisterMe67D2Ev4168
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.gcov.html b/coverage/generic/DumpProjections.cpp.gcov.html new file mode 100644 index 0000000000..9dbc649e77 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(DumpProjections,"DUMPPROJECTIONS")
+      68             : 
+      69           3 : void DumpProjections::registerKeywords(Keywords& keys) {
+      70           3 :   Action::registerKeywords(keys);
+      71           3 :   ActionPilot::registerKeywords(keys);
+      72           3 :   ActionWithArguments::registerKeywords(keys);
+      73           3 :   keys.use("ARG");
+      74           6 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      75           6 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      76           6 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      77           3 :   keys.use("RESTART");
+      78           3 :   keys.use("UPDATE_FROM");
+      79           3 :   keys.use("UPDATE_UNTIL");
+      80           3 : }
+      81             : 
+      82           1 : DumpProjections::DumpProjections(const ActionOptions&ao):
+      83             :   Action(ao),
+      84             :   ActionPilot(ao),
+      85             :   ActionWithArguments(ao),
+      86           1 :   fmt("%15.10f")
+      87             : {
+      88           2 :   parse("FILE",file);
+      89           1 :   if( file.length()==0 ) error("filename not specified");
+      90           1 :   parse("FMT",fmt);
+      91           1 :   fmt=" "+fmt;
+      92           1 :   of.open(file);
+      93           1 :   log.printf("  on file %s\n",file.c_str());
+      94           1 :   log.printf("  with format %s\n",fmt.c_str());
+      95           1 :   checkRead();
+      96             : 
+      97           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      98           2 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      99             :   }
+     100           1 : }
+     101             : 
+     102             : 
+     103           3 : void DumpProjections::update() {
+     104           6 :   of.fmtField(" %f").printField("time",getTime());
+     105           9 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     106          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     107          12 :       of.fmtField(fmt);
+     108          24 :       of.printField(getPntrToArgument(i)->getName()+"-"+getPntrToArgument(j)->getName(),getProjection(i,j));
+     109             :     }
+     110             :   }
+     111           3 :   of.printField();
+     112           3 : }
+     113             : 
+     114           2 : DumpProjections::~DumpProjections() {
+     115           2 : }
+     116             : 
+     117             : }
+     118             : 
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html new file mode 100644 index 0000000000..61b5f492d4 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe1236createERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe123C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_133EffectiveEnergyDriftRegisterMe123D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func.html b/coverage/generic/EffectiveEnergyDrift.cpp.func.html new file mode 100644 index 0000000000..3dacb1e6a9 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe656createERKNS_13ActionOptionsE263
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE263
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE265
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func.html b/coverage/generic/EndPlumed.cpp.func.html new file mode 100644 index 0000000000..fd636ce8ad --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe656createERKNS_13ActionOptionsE263
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_121EndPlumedRegisterMe65D2Ev4168
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE265
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.gcov.html b/coverage/generic/EndPlumed.cpp.gcov.html new file mode 100644 index 0000000000..6b4ab590cc --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05: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       12767 : PLUMED_REGISTER_ACTION(EndPlumed,"ENDPLUMED")
+      66             : 
+      67         265 : void EndPlumed::registerKeywords( Keywords& keys ) {
+      68         265 :   Action::registerKeywords( keys );
+      69         265 : }
+      70             : 
+      71         263 : EndPlumed::EndPlumed(const ActionOptions&ao):
+      72         263 :   Action(ao)
+      73             : {
+      74         263 :   checkRead();
+      75         263 :   plumed.setEndPlumed();
+      76         263 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func-sort-c.html b/coverage/generic/FitToTemplate.cpp.func-sort-c.html new file mode 100644 index 0000000000..150f872121 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func.html b/coverage/generic/FitToTemplate.cpp.func.html new file mode 100644 index 0000000000..62ea27c18d --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe2016createERKNS_13ActionOptionsE9
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_126FitToTemplateRegisterMe201D2Ev4168
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.gcov.html b/coverage/generic/FitToTemplate.cpp.gcov.html new file mode 100644 index 0000000000..0a515aef96 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.gcov.html @@ -0,0 +1,450 @@ + + + + + + + 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-05-27 13:05: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       12522 : PLUMED_REGISTER_ACTION(FitToTemplate,"FIT_TO_TEMPLATE")
+     202             : 
+     203          11 : void FitToTemplate::registerKeywords( Keywords& keys ) {
+     204          11 :   Action::registerKeywords( keys );
+     205          11 :   ActionAtomistic::registerKeywords( keys );
+     206          22 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     207          22 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     208          22 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     209          22 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     210          11 : }
+     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.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func-sort-c.html b/coverage/generic/Flush.cpp.func-sort-c.html new file mode 100644 index 0000000000..bf96f2398b --- /dev/null +++ b/coverage/generic/Flush.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe796createERKNS_13ActionOptionsE17
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func.html b/coverage/generic/Flush.cpp.func.html new file mode 100644 index 0000000000..f69c0e1d9f --- /dev/null +++ b/coverage/generic/Flush.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe796createERKNS_13ActionOptionsE17
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117FlushRegisterMe79D2Ev4168
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.gcov.html b/coverage/generic/Flush.cpp.gcov.html new file mode 100644 index 0000000000..af494b87d7 --- /dev/null +++ b/coverage/generic/Flush.cpp.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-05-27 13:05: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        3942 :     for(const auto & p : actionSet)
+      75        3381 :       p->fflush();
+      76         561 :   }
+      77             : };
+      78             : 
+      79       12538 : PLUMED_REGISTER_ACTION(Flush,"FLUSH")
+      80             : 
+      81          19 : void Flush::registerKeywords( Keywords& keys ) {
+      82          19 :   Action::registerKeywords( keys );
+      83          19 :   ActionPilot::registerKeywords( keys );
+      84          38 :   keys.add("compulsory","STRIDE","the frequency with which all the open files should be flushed");
+      85          19 :   keys.remove("LABEL");
+      86          19 : }
+      87             : 
+      88             : }
+      89             : }
+      90             : 
+      91             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Group.cpp.func-sort-c.html b/coverage/generic/Group.cpp.func-sort-c.html new file mode 100644 index 0000000000..b07deb4cf8 --- /dev/null +++ b/coverage/generic/Group.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Group5applyEv0
_ZN4PLMD7generic5Group9calculateEv0
_ZN4PLMD7generic5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5GroupD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe1436createERKNS_13ActionOptionsE132
_ZN4PLMD7generic5GroupC1ERKNS_13ActionOptionsE132
_ZN4PLMD7generic5GroupD0Ev132
_ZN4PLMD7generic5GroupD1Ev132
_ZN4PLMD7generic5Group16registerKeywordsERNS_8KeywordsE134
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Group.cpp.func.html b/coverage/generic/Group.cpp.func.html new file mode 100644 index 0000000000..d9d7905b23 --- /dev/null +++ b/coverage/generic/Group.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:71163.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe1436createERKNS_13ActionOptionsE132
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_118GroupRegisterMe143D2Ev4168
_ZN4PLMD7generic5Group16registerKeywordsERNS_8KeywordsE134
_ZN4PLMD7generic5Group5applyEv0
_ZN4PLMD7generic5Group9calculateEv0
_ZN4PLMD7generic5GroupC1ERKNS_13ActionOptionsE132
_ZN4PLMD7generic5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5GroupD0Ev132
_ZN4PLMD7generic5GroupD1Ev132
_ZN4PLMD7generic5GroupD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Group.cpp.gcov.html b/coverage/generic/Group.cpp.gcov.html new file mode 100644 index 0000000000..d39fbc6401 --- /dev/null +++ b/coverage/generic/Group.cpp.gcov.html @@ -0,0 +1,322 @@ + + + + + + + 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-05-27 13:05: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       12768 : PLUMED_REGISTER_ACTION(Group,"GROUP")
+     144             : 
+     145         132 : Group::Group(const ActionOptions&ao):
+     146             :   Action(ao),
+     147         132 :   ActionAtomistic(ao)
+     148             : {
+     149             :   std::vector<AtomNumber> atoms;
+     150         264 :   parseAtomList("ATOMS",atoms);
+     151             :   std::string ndxfile,ndxgroup;
+     152         132 :   parse("NDX_FILE",ndxfile);
+     153         264 :   parse("NDX_GROUP",ndxgroup);
+     154         132 :   if(ndxfile.length()>0 && atoms.size()>0) error("either use explicit atom list or import from index file");
+     155         132 :   if(ndxfile.length()==0 && ndxgroup.size()>0) error("NDX_GROUP can be only used is NDX_FILE is also used");
+     156             : 
+     157         132 :   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         264 :   parseAtomList("REMOVE",remove);
+     186         132 :   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         132 :   bool sortme=false;
+     208         132 :   parseFlag("SORT",sortme);
+     209         132 :   if(sortme) {
+     210           1 :     log<<"  atoms are sorted\n";
+     211           1 :     sort(atoms.begin(),atoms.end());
+     212             :   }
+     213         132 :   bool unique=false;
+     214         132 :   parseFlag("UNIQUE",unique);
+     215         132 :   if(unique) {
+     216           1 :     log<<"  sorting atoms and removing duplicates\n";
+     217           1 :     Tools::removeDuplicates(atoms);
+     218             :   }
+     219             : 
+     220         132 :   this->atoms.insertGroup(getLabel(),atoms);
+     221         132 :   log.printf("  list of atoms:");
+     222      183007 :   for(unsigned i=0; i<atoms.size(); i++) {
+     223      182875 :     if(i%25==0) log<<"\n";
+     224      182875 :     log<<" "<<atoms[i].serial();
+     225             :   }
+     226         132 :   log.printf("\n");
+     227         132 : }
+     228             : 
+     229         134 : void Group::registerKeywords( Keywords& keys ) {
+     230         134 :   Action::registerKeywords( keys );
+     231         134 :   ActionAtomistic::registerKeywords( keys );
+     232         268 :   keys.add("atoms", "ATOMS", "the numerical indexes for the set of atoms in the group");
+     233         268 :   keys.add("atoms", "REMOVE","remove these atoms from the list");
+     234         268 :   keys.addFlag("SORT",false,"sort the resulting list");
+     235         268 :   keys.addFlag("UNIQUE",false,"sort atoms and remove duplicated ones");
+     236         268 :   keys.add("optional", "NDX_FILE", "the name of index file (gromacs syntax)");
+     237         268 :   keys.add("optional", "NDX_GROUP", "the name of the group to be imported (gromacs syntax) - first group found is used by default");
+     238         134 : }
+     239             : 
+     240         264 : Group::~Group() {
+     241         132 :   atoms.removeGroup(getLabel());
+     242         264 : }
+     243             : 
+     244             : }
+     245             : }
+     246             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func-sort-c.html b/coverage/generic/Include.cpp.func-sort-c.html new file mode 100644 index 0000000000..f7e5135732 --- /dev/null +++ b/coverage/generic/Include.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE20
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func.html b/coverage/generic/Include.cpp.func.html new file mode 100644 index 0000000000..96ec1bea01 --- /dev/null +++ b/coverage/generic/Include.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe1606createERKNS_13ActionOptionsE18
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120IncludeRegisterMe160D2Ev4168
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE18
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.gcov.html b/coverage/generic/Include.cpp.gcov.html new file mode 100644 index 0000000000..863443d1c6 --- /dev/null +++ b/coverage/generic/Include.cpp.gcov.html @@ -0,0 +1,255 @@ + + + + + + + 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-05-27 13:05: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       12540 : PLUMED_REGISTER_ACTION(Include,"INCLUDE")
+     161             : 
+     162          20 : void Include::registerKeywords( Keywords& keys ) {
+     163          20 :   Action::registerKeywords(keys);
+     164          40 :   keys.add("compulsory","FILE","file to be included");
+     165          20 : }
+     166             : 
+     167          18 : Include::Include(const ActionOptions&ao):
+     168             :   Action(ao),
+     169          18 :   ActionAnyorder(ao)
+     170             : {
+     171             :   std::string f;
+     172          18 :   parse("FILE",f);
+     173          18 :   checkRead();
+     174          18 :   plumed.readInputFile(f);
+     175          18 : }
+     176             : 
+     177             : }
+     178             : }
+     179             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.func-sort-c.html b/coverage/generic/MolInfo.cpp.func-sort-c.html new file mode 100644 index 0000000000..7b59220664 --- /dev/null +++ b/coverage/generic/MolInfo.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe2666createERKNS_13ActionOptionsE87
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.func.html b/coverage/generic/MolInfo.cpp.func.html new file mode 100644 index 0000000000..c70ee22286 --- /dev/null +++ b/coverage/generic/MolInfo.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe2666createERKNS_13ActionOptionsE87
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120MolInfoRegisterMe266D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/MolInfo.cpp.gcov.html b/coverage/generic/MolInfo.cpp.gcov.html new file mode 100644 index 0000000000..7a33791818 --- /dev/null +++ b/coverage/generic/MolInfo.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + 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-05-27 13:05: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       12678 : PLUMED_REGISTER_ACTION(MolInfo,"MOLINFO")
+     267             : 
+     268             : }
+     269             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func-sort-c.html b/coverage/generic/Plumed.cpp.func-sort-c.html new file mode 100644 index 0000000000..2e687df475 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE14
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6Plumed7prepareEv164
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func.html b/coverage/generic/Plumed.cpp.func.html new file mode 100644 index 0000000000..a01d7d4f02 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe1726createERKNS_13ActionOptionsE12
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_119PlumedRegisterMe172D2Ev4168
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed7prepareEv164
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.gcov.html b/coverage/generic/Plumed.cpp.gcov.html new file mode 100644 index 0000000000..4f20602a72 --- /dev/null +++ b/coverage/generic/Plumed.cpp.gcov.html @@ -0,0 +1,495 @@ + + + + + + + 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-05-27 13:05: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       12528 : PLUMED_REGISTER_ACTION(Plumed,"PLUMED")
+     173             : 
+     174          14 : void Plumed::registerKeywords( Keywords& keys ) {
+     175          14 :   Action::registerKeywords( keys );
+     176          14 :   ActionPilot::registerKeywords( keys );
+     177          14 :   ActionAtomistic::registerKeywords( keys );
+     178          28 :   keys.add("compulsory","STRIDE","1","stride different from 1 are not supported yet");
+     179          28 :   keys.add("optional","FILE","input file for the guest PLUMED instance");
+     180          28 :   keys.add("optional","KERNEL","kernel to be used for the guest PLUMED instance (USE WITH CAUTION!)");
+     181          28 :   keys.add("optional","LOG","log file for the guest PLUMED instance. By default the host log is used");
+     182          28 :   keys.add("optional","CHDIR","run guest in a separate directory");
+     183          28 :   keys.addFlag("NOREPLICAS",false,"run multiple replicas as isolated ones, without letting them know that the host has multiple replicas");
+     184          28 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     185          14 : }
+     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.16
+
+ + + diff --git a/coverage/generic/Print.cpp.func-sort-c.html b/coverage/generic/Print.cpp.func-sort-c.html new file mode 100644 index 0000000000..42751261c2 --- /dev/null +++ b/coverage/generic/Print.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD2Ev0
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe956createERKNS_13ActionOptionsE820
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE820
_ZN4PLMD7generic5PrintD0Ev820
_ZN4PLMD7generic5PrintD1Ev820
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE822
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95D2Ev4168
_ZN4PLMD7generic5Print6updateEv211498
_ZN4PLMD7generic5Print5applyEv212121
_ZN4PLMD7generic5Print9calculateEv212243
_ZN4PLMD7generic5Print7prepareEv212366
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.func.html b/coverage/generic/Print.cpp.func.html new file mode 100644 index 0000000000..aa081cda0f --- /dev/null +++ b/coverage/generic/Print.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe956createERKNS_13ActionOptionsE820
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117PrintRegisterMe95D2Ev4168
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE822
_ZN4PLMD7generic5Print5applyEv212121
_ZN4PLMD7generic5Print6updateEv211498
_ZN4PLMD7generic5Print7prepareEv212366
_ZN4PLMD7generic5Print9calculateEv212243
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE820
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD0Ev820
_ZN4PLMD7generic5PrintD1Ev820
_ZN4PLMD7generic5PrintD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.gcov.html b/coverage/generic/Print.cpp.gcov.html new file mode 100644 index 0000000000..a6fc2cf798 --- /dev/null +++ b/coverage/generic/Print.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + 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-05-27 13:05: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      212243 :   void calculate() override {}
+      87             :   void prepare() override;
+      88             :   explicit Print(const ActionOptions&);
+      89             :   static void registerKeywords(Keywords& keys);
+      90      212121 :   void apply() override {}
+      91             :   void update() override;
+      92             :   ~Print();
+      93             : };
+      94             : 
+      95       14144 : PLUMED_REGISTER_ACTION(Print,"PRINT")
+      96             : 
+      97         822 : void Print::registerKeywords(Keywords& keys) {
+      98         822 :   Action::registerKeywords(keys);
+      99         822 :   ActionPilot::registerKeywords(keys);
+     100         822 :   ActionWithArguments::registerKeywords(keys);
+     101         822 :   keys.use("ARG");
+     102        1644 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     103        1644 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+     104        1644 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     105        1644 :   keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
+     106         822 :   keys.use("RESTART");
+     107         822 :   keys.use("UPDATE_FROM");
+     108         822 :   keys.use("UPDATE_UNTIL");
+     109         822 : }
+     110             : 
+     111         820 : Print::Print(const ActionOptions&ao):
+     112             :   Action(ao),
+     113             :   ActionPilot(ao),
+     114             :   ActionWithArguments(ao),
+     115         820 :   fmt("%f"),
+     116        1640 :   rotate(0)
+     117             : {
+     118         820 :   ofile.link(*this);
+     119        1640 :   parse("FILE",file);
+     120         820 :   if(file.length()>0) {
+     121         820 :     ofile.open(file);
+     122         820 :     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         820 :   parse("FMT",fmt);
+     128         820 :   fmt=" "+fmt;
+     129         820 :   log.printf("  with format %s\n",fmt.c_str());
+     130        6289 :   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         820 :   parse("_ROTATE",rotate);
+     136         820 :   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         820 :   checkRead();
+     145         820 : }
+     146             : 
+     147      212366 : void Print::prepare() {
+     148             : /////////////////////////////////////////
+     149             : // these are crazy things just for debug:
+     150             : // they allow to change regularly the
+     151             : // printed argument
+     152      212366 :   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      212366 : }
+     163             : 
+     164      211498 : void Print::update() {
+     165      211498 :   ofile.fmtField(" %f");
+     166      211498 :   ofile.printField("time",getTime());
+     167      742572 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     168      531074 :     ofile.fmtField(fmt);
+     169      531074 :     ofile.printField( getPntrToArgument(i), getArgument(i) );
+     170             :   }
+     171      211498 :   ofile.printField();
+     172      211498 : }
+     173             : 
+     174        1640 : Print::~Print() {
+     175        1640 : }
+     176             : 
+     177             : }
+     178             : 
+     179             : 
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func-sort-c.html b/coverage/generic/RandomExchanges.cpp.func-sort-c.html new file mode 100644 index 0000000000..21fdb55c37 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe836createERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func.html b/coverage/generic/RandomExchanges.cpp.func.html new file mode 100644 index 0000000000..07ee8a2a96 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe836createERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127RandomExchangesRegisterMe83D2Ev4168
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.gcov.html b/coverage/generic/RandomExchanges.cpp.gcov.html new file mode 100644 index 0000000000..5cecfdf1ec --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(RandomExchanges,"RANDOM_EXCHANGES")
+      84             : 
+      85           2 : void RandomExchanges::registerKeywords( Keywords& keys ) {
+      86           2 :   Action::registerKeywords(keys);
+      87           4 :   keys.add("optional","SEED","seed for random exchanges");
+      88           2 : }
+      89             : 
+      90           0 : RandomExchanges::RandomExchanges(const ActionOptions&ao):
+      91           0 :   Action(ao)
+      92             : {
+      93           0 :   plumed.getExchangePatterns().setFlag(ExchangePatterns::RANDOM);
+      94             : // I convert the seed to -seed because I think it is more general to use a positive seed in input
+      95           0 :   int seed=-1;
+      96           0 :   parse("SEED",seed);
+      97           0 :   if(seed>=0) plumed.getExchangePatterns().setSeed(-seed);
+      98           0 : }
+      99             : 
+     100             : }
+     101             : }
+     102             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func-sort-c.html b/coverage/generic/Read.cpp.func-sort-c.html new file mode 100644 index 0000000000..524b612813 --- /dev/null +++ b/coverage/generic/Read.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE88
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108D2Ev4168
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func.html b/coverage/generic/Read.cpp.func.html new file mode 100644 index 0000000000..c24f20498f --- /dev/null +++ b/coverage/generic/Read.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:121485.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe1086createERKNS_13ActionOptionsE86
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_117ReadRegisterMe108D2Ev4168
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD7generic4Read17turnOnDerivativesEv28
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7getFileEv37
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE86
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.gcov.html b/coverage/generic/Read.cpp.gcov.html new file mode 100644 index 0000000000..071556df45 --- /dev/null +++ b/coverage/generic/Read.cpp.gcov.html @@ -0,0 +1,332 @@ + + + + + + + LCOV - plumed test coverage - generic/Read.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9510095.0 %
Date:2024-05-27 13:05: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       12676 : PLUMED_REGISTER_ACTION(Read,"READ")
+     109             : 
+     110          88 : void Read::registerKeywords(Keywords& keys) {
+     111          88 :   Action::registerKeywords(keys);
+     112          88 :   ActionPilot::registerKeywords(keys);
+     113          88 :   ActionWithValue::registerKeywords(keys);
+     114         176 :   keys.add("compulsory","STRIDE","1","the frequency with which the file should be read.");
+     115         176 :   keys.add("compulsory","EVERY","1","only read every \\f$n\\f$th line of the colvar file. This should be used if the colvar was written more frequently than the trajectory.");
+     116         176 :   keys.add("compulsory","VALUES","the values to read from the file");
+     117         176 :   keys.add("compulsory","FILE","the name of the file from which to read these quantities");
+     118         176 :   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         176 :   keys.addFlag("IGNORE_FORCES",false,"use this flag if the forces added by any bias can be safely ignored.  As an example forces can be "
+     121             :                "safely ignored if you are doing post processing that does not involve outputting forces");
+     122          88 :   keys.remove("NUMERICAL_DERIVATIVES");
+     123          88 :   keys.use("UPDATE_FROM");
+     124          88 :   keys.use("UPDATE_UNTIL");
+     125          88 :   ActionWithValue::useCustomisableComponents(keys);
+     126          88 : }
+     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.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func-sort-c.html b/coverage/generic/ResetCell.cpp.func-sort-c.html new file mode 100644 index 0000000000..9309f45476 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe1066createERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func.html b/coverage/generic/ResetCell.cpp.func.html new file mode 100644 index 0000000000..2e55c84cab --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe1066createERKNS_13ActionOptionsE2
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_122ResetCellRegisterMe106D2Ev4168
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.gcov.html b/coverage/generic/ResetCell.cpp.gcov.html new file mode 100644 index 0000000000..deac9d0312 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ResetCell,"RESET_CELL")
+     107             : 
+     108           4 : void ResetCell::registerKeywords( Keywords& keys ) {
+     109           4 :   Action::registerKeywords( keys );
+     110           4 :   ActionAtomistic::registerKeywords( keys );
+     111           8 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     112           8 :   keys.add("compulsory","TYPE","TRIANGULAR","the manner in which the cell is reset");
+     113           4 : }
+     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.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func-sort-c.html b/coverage/generic/Time.cpp.func-sort-c.html new file mode 100644 index 0000000000..b4d21dfa10 --- /dev/null +++ b/coverage/generic/Time.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func.html b/coverage/generic/Time.cpp.func.html new file mode 100644 index 0000000000..d8b36dee1a --- /dev/null +++ b/coverage/generic/Time.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:3933.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe546createERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_116TimeRegisterMe54D2Ev4168
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.gcov.html b/coverage/generic/Time.cpp.gcov.html new file mode 100644 index 0000000000..a9a04f9f48 --- /dev/null +++ b/coverage/generic/Time.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(Time,"TIME")
+      55             : 
+      56           2 : void Time::registerKeywords( Keywords& keys ) {
+      57           2 :   Action::registerKeywords( keys );
+      58           2 :   ActionWithValue::registerKeywords( keys );
+      59           2 : }
+      60             : 
+      61           0 : Time::Time(const ActionOptions&ao):
+      62           0 :   Action(ao),ActionWithValue(ao)
+      63             : {
+      64           0 :   addValueWithDerivatives(); setNotPeriodic();
+      65             :   // resize derivative by hand to a nonzero value
+      66           0 :   getPntrToValue()->resizeDerivatives(1);
+      67           0 : }
+      68             : 
+      69           0 : void Time::calculate() {
+      70           0 :   setValue           (getTime());
+      71           0 : }
+      72             : 
+      73             : }
+      74             : 
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func-sort-c.html b/coverage/generic/UpdateIf.cpp.func-sort-c.html new file mode 100644 index 0000000000..634e1d0d35 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE9
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func.html b/coverage/generic/UpdateIf.cpp.func.html new file mode 100644 index 0000000000..394fc8a4a8 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe976createERKNS_13ActionOptionsE7
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_120UpdateIfRegisterMe97D2Ev4168
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIfD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.gcov.html b/coverage/generic/UpdateIf.cpp.gcov.html new file mode 100644 index 0000000000..3769359842 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + 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-05-27 13:05: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       12518 : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
+      98             : 
+      99           9 : void UpdateIf::registerKeywords(Keywords& keys) {
+     100           9 :   Action::registerKeywords(keys);
+     101           9 :   ActionPilot::registerKeywords(keys);
+     102           9 :   ActionWithArguments::registerKeywords(keys);
+     103           9 :   keys.use("ARG");
+     104          18 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     105          18 :   keys.addFlag("END",false,"end");
+     106          18 :   keys.add("optional","LESS_THAN","upper bound");
+     107          18 :   keys.add("optional","MORE_THAN","lower bound");
+     108           9 : }
+     109             : 
+     110           7 : UpdateIf::UpdateIf(const ActionOptions&ao):
+     111             :   Action(ao),
+     112             :   ActionPilot(ao),
+     113             :   ActionWithArguments(ao),
+     114           7 :   on(false),
+     115           7 :   end(false)
+     116             : {
+     117           7 :   parseFlag("END",end);
+     118           7 :   parseVector("LESS_THAN",upper);
+     119           7 :   parseVector("MORE_THAN",lower);
+     120           7 :   if(end && upper.size()!=0) error("END and LESS_THAN are not compatible");
+     121           7 :   if(end && lower.size()!=0) error("END and MORE_THAN are not compatible");
+     122           7 :   if(upper.size()==0) upper.assign(getNumberOfArguments(),+std::numeric_limits<double>::max());
+     123           7 :   if(lower.size()==0) lower.assign(getNumberOfArguments(),-std::numeric_limits<double>::max());
+     124           7 :   if(upper.size()!=getNumberOfArguments()) error("LESS_THAN should have the same size as ARG");
+     125           7 :   if(lower.size()!=getNumberOfArguments()) error("MORE_THAN should have the same size as ARG");
+     126          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     127           8 :     log<<"  boundaries for argument "<<i<<"    "<<lower[i]<<" "<<upper[i]<<"\n";
+     128             :   }
+     129           7 :   checkRead();
+     130           7 : }
+     131             : 
+     132          28 : void UpdateIf::prepare() {
+     133          28 :   on=false;
+     134          28 : }
+     135             : 
+     136          28 : void UpdateIf::calculate() {
+     137          28 :   on=true;
+     138          60 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     139          32 :     if(getArgument(i)>=upper[i] || getArgument(i)<=lower[i]) on=false;
+     140             :   }
+     141          28 : }
+     142             : 
+     143          28 : void UpdateIf::beforeUpdate() {
+     144          28 :   if(end) plumed.updateFlagsPop();
+     145             :   else {
+     146          23 :     if(on) plumed.updateFlagsPush(plumed.updateFlagsTop());
+     147           9 :     else   plumed.updateFlagsPush(false);
+     148             :   }
+     149          28 : }
+     150             : 
+     151             : 
+     152          14 : UpdateIf::~UpdateIf() {
+     153          14 : }
+     154             : 
+     155             : }
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func-sort-c.html b/coverage/generic/WholeMolecules.cpp.func-sort-c.html new file mode 100644 index 0000000000..c0c1aed21b --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:607085.7 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe1186createERKNS_13ActionOptionsE36
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE36
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD7generic14WholeMolecules5applyEv3319
_ZN4PLMD7generic14WholeMolecules9calculateEv3319
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func.html b/coverage/generic/WholeMolecules.cpp.func.html new file mode 100644 index 0000000000..cc77370f29 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:607085.7 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe1186createERKNS_13ActionOptionsE36
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_127WholeMoleculesRegisterMe118D2Ev4168
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD7generic14WholeMolecules5applyEv3319
_ZN4PLMD7generic14WholeMolecules9calculateEv3319
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE36
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.gcov.html b/coverage/generic/WholeMolecules.cpp.gcov.html new file mode 100644 index 0000000000..9fa519e656 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.gcov.html @@ -0,0 +1,319 @@ + + + + + + + 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:607085.7 %
Date:2024-05-27 13:05: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        3319 :   void apply() override {}
+     116             : };
+     117             : 
+     118       12576 : PLUMED_REGISTER_ACTION(WholeMolecules,"WHOLEMOLECULES")
+     119             : 
+     120          38 : void WholeMolecules::registerKeywords( Keywords& keys ) {
+     121          38 :   Action::registerKeywords( keys );
+     122          38 :   ActionPilot::registerKeywords( keys );
+     123          38 :   ActionAtomistic::registerKeywords( keys );
+     124          76 :   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          76 :   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          76 :   keys.reset_style("ENTITY","atoms");
+     127          76 :   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          76 :   keys.add("optional","MOLTYPE","the type of molecule that is under study.  This is used to define the backbone atoms");
+     132          76 :   keys.addFlag("EMST", false, "Define atoms sequence in entities using an Euclidean minimum spanning tree");
+     133          76 :   keys.addFlag("ADDREFERENCE", false, "Define the reference position of the first atom of each entity using a PDB file");
+     134          38 : }
+     135             : 
+     136          36 : WholeMolecules::WholeMolecules(const ActionOptions&ao):
+     137             :   Action(ao),
+     138             :   ActionPilot(ao),
+     139             :   ActionAtomistic(ao),
+     140          36 :   doemst(false), addref(false)
+     141             : {
+     142             :   // parse optional flags
+     143          36 :   parseFlag("EMST", doemst);
+     144          72 :   parseFlag("ADDREFERENCE", addref);
+     145             : 
+     146             :   // create groups from ENTITY
+     147          37 :   for(int i=0;; i++) {
+     148             :     std::vector<AtomNumber> group;
+     149         146 :     parseAtomList("ENTITY",i,group);
+     150          73 :     if( group.empty() ) break;
+     151          37 :     groups.push_back(group);
+     152          37 :   }
+     153             : 
+     154             :   // Read residues to align from MOLINFO
+     155          72 :   std::vector<std::string> resstrings; parseVector("RESIDUES",resstrings);
+     156          36 :   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          36 :   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          36 :   if(doemst) {
+     176           2 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     177           2 :     if( !moldat ) error("MOLINFO is required to use EMST");
+     178             :     // initialize tree
+     179           2 :     Tree tree = Tree(moldat);
+     180             :     // cycle on groups and reorder atoms
+     181           4 :     for(unsigned i=0; i<groups.size(); ++i) {
+     182           4 :       groups[i] = tree.getTree(groups[i]);
+     183             :       // store root atoms
+     184           4 :       roots.push_back(tree.getRoot());
+     185             :     }
+     186             :   } else {
+     187             :     // fill root vector with previous atom in groups
+     188          69 :     for(unsigned i=0; i<groups.size(); ++i) {
+     189             :       std::vector<AtomNumber> root;
+     190        2661 :       for(unsigned j=0; j<groups[i].size()-1; ++j) root.push_back(groups[i][j]);
+     191             :       // store root atoms
+     192          35 :       roots.push_back(root);
+     193             :     }
+     194             :   }
+     195             : 
+     196             :   // adding reference if needed
+     197          36 :   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          73 :   for(unsigned i=0; i<groups.size(); ++i) {
+     208          37 :     log.printf("  atoms in entity %d : ",i);
+     209        2943 :     for(unsigned j=0; j<groups[i].size(); ++j) log.printf("%d ",groups[i][j].serial() );
+     210          37 :     log.printf("\n");
+     211          37 :     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          73 :   for(unsigned i=0; i<groups.size(); ++i) {
+     217          37 :     merge.insert(merge.end(),groups[i].begin(),groups[i].end());
+     218             :   }
+     219             : 
+     220          36 :   checkRead();
+     221          36 :   Tools::removeDuplicates(merge);
+     222          36 :   requestAtoms(merge);
+     223             :   doNotRetrieve();
+     224             :   doNotForce();
+     225          36 : }
+     226             : 
+     227        3319 : void WholeMolecules::calculate() {
+     228        6643 :   for(unsigned i=0; i<groups.size(); ++i) {
+     229        3324 :     if(addref) {
+     230             :       Vector & first (modifyGlobalPosition(groups[i][0]));
+     231          12 :       first = refs[i]+pbcDistance(refs[i],first);
+     232             :     }
+     233      294850 :     for(unsigned j=0; j<groups[i].size()-1; ++j) {
+     234             :       const Vector & first (getGlobalPosition(roots[i][j]));
+     235      291526 :       Vector & second (modifyGlobalPosition(groups[i][j+1]));
+     236      291526 :       second=first+pbcDistance(first,second);
+     237             :     }
+     238             :   }
+     239        3319 : }
+     240             : 
+     241             : 
+     242             : }
+     243             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func-sort-c.html b/coverage/generic/WrapAround.cpp.func-sort-c.html new file mode 100644 index 0000000000..cf76813fb4 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:535498.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe1636createERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe163C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe163D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func.html b/coverage/generic/WrapAround.cpp.func.html new file mode 100644 index 0000000000..55878b49cd --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:535498.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe1636createERKNS_13ActionOptionsE5
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe163C2Ev4168
_ZN4PLMD7generic12_GLOBAL__N_123WrapAroundRegisterMe163D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.gcov.html b/coverage/generic/WrapAround.cpp.gcov.html new file mode 100644 index 0000000000..6dbcd3fe6c --- /dev/null +++ b/coverage/generic/WrapAround.cpp.gcov.html @@ -0,0 +1,327 @@ + + + + + + + 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:535498.1 %
Date:2024-05-27 13:05: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             :   // cppcheck-suppress duplInheritedMember
+     152             :   std::vector<AtomNumber> atoms;
+     153             :   std::vector<AtomNumber> reference;
+     154             :   unsigned groupby;
+     155             :   bool pair_;
+     156             : public:
+     157             :   explicit WrapAround(const ActionOptions&ao);
+     158             :   static void registerKeywords( Keywords& keys );
+     159             :   void calculate() override;
+     160         579 :   void apply() override {}
+     161             : };
+     162             : 
+     163       12514 : PLUMED_REGISTER_ACTION(WrapAround,"WRAPAROUND")
+     164             : 
+     165           7 : void WrapAround::registerKeywords( Keywords& keys ) {
+     166           7 :   Action::registerKeywords( keys );
+     167           7 :   ActionAtomistic::registerKeywords( keys );
+     168           7 :   ActionPilot::registerKeywords( keys );
+     169          14 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     170          14 :   keys.add("atoms","AROUND","reference atoms");
+     171          14 :   keys.add("atoms","ATOMS","wrapped atoms");
+     172          14 :   keys.add("compulsory","GROUPBY","1","group atoms so as not to break molecules");
+     173          14 :   keys.addFlag("PAIR", false, "Pair atoms in AROUND and ATOMS groups");
+     174           7 : }
+     175             : 
+     176           5 : WrapAround::WrapAround(const ActionOptions&ao):
+     177             :   Action(ao),
+     178             :   ActionPilot(ao),
+     179             :   ActionAtomistic(ao),
+     180           5 :   groupby(1),
+     181           5 :   pair_(false)
+     182             : {
+     183           5 :   parseAtomList("ATOMS",atoms);
+     184           5 :   parseAtomList("AROUND",reference);
+     185           5 :   parse("GROUPBY",groupby);
+     186           5 :   parseFlag("PAIR", pair_);
+     187             : 
+     188           5 :   log.printf("  atoms in reference :");
+     189          11 :   for(unsigned j=0; j<reference.size(); ++j) log.printf(" %d",reference[j].serial() );
+     190           5 :   log.printf("\n");
+     191           5 :   log.printf("  atoms to be wrapped :");
+     192         399 :   for(unsigned j=0; j<atoms.size(); ++j) log.printf(" %d",atoms[j].serial() );
+     193           5 :   log.printf("\n");
+     194           5 :   if(groupby>1) log<<"  atoms will be grouped by "<<groupby<<"\n";
+     195           5 :   if(pair_) log.printf("  pairing atoms and references\n");
+     196             : 
+     197           5 :   if(atoms.size()%groupby!=0) error("number of atoms should be a multiple of groupby option");
+     198             :   // additional checks with PAIR
+     199           5 :   if(pair_ && atoms.size()!=reference.size()*groupby) error("with PAIR you must have: #ATOMS = #AROUND * #GROUPBY");
+     200             : 
+     201           5 :   checkRead();
+     202             : 
+     203             :   // do not remove duplicates with pair
+     204           5 :   if(!pair_) {
+     205           5 :     if(groupby<=1) Tools::removeDuplicates(atoms);
+     206           5 :     Tools::removeDuplicates(reference);
+     207             :   }
+     208             : 
+     209           5 :   std::vector<AtomNumber> merged(atoms.size()+reference.size());
+     210           5 :   merge(atoms.begin(),atoms.end(),reference.begin(),reference.end(),merged.begin());
+     211           5 :   Tools::removeDuplicates(merged);
+     212           5 :   requestAtoms(merged);
+     213             :   doNotRetrieve();
+     214             :   doNotForce();
+     215           5 : }
+     216             : 
+     217         579 : void WrapAround::calculate() {
+     218       15012 :   for(unsigned i=0; i<atoms.size(); i+=groupby) {
+     219             :     Vector & first (modifyGlobalPosition(atoms[i]));
+     220             :     double mindist2=std::numeric_limits<double>::max();
+     221             :     int closest=-1;
+     222       14433 :     if(pair_) {
+     223           0 :       closest = i/groupby;
+     224             :     } else {
+     225       29416 :       for(unsigned j=0; j<reference.size(); ++j) {
+     226             :         const Vector & second (modifyGlobalPosition(reference[j]));
+     227       14983 :         const Vector distance=pbcDistance(first,second);
+     228       14983 :         const double distance2=modulo2(distance);
+     229       14983 :         if(distance2<mindist2) {
+     230             :           mindist2=distance2;
+     231       14713 :           closest=j;
+     232             :         }
+     233             :       }
+     234       14433 :       plumed_massert(closest>=0,"closest not found");
+     235             :     }
+     236       14433 :     Vector & second (modifyGlobalPosition(reference[closest]));
+     237             : // place first atom of the group
+     238       14433 :     first=second+pbcDistance(second,first);
+     239             : // then place other atoms close to the first of the group
+     240       14928 :     for(unsigned j=1; j<groupby; j++) {
+     241         495 :       Vector & second (modifyGlobalPosition(atoms[i+j]));
+     242         495 :       second=first+pbcDistance(first,second);
+     243             :     }
+     244             :   }
+     245         579 : }
+     246             : 
+     247             : 
+     248             : 
+     249             : }
+     250             : 
+     251             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index-sort-f.html b/coverage/generic/index-sort-f.html new file mode 100644 index 0000000000..518f221919 --- /dev/null +++ b/coverage/generic/index-sort-f.html @@ -0,0 +1,303 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1210127594.9 %
Date:2024-05-27 13:05: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
DumpDerivatives.cpp +
100.0%
+
100.0 %47 / 4783.3 %10 / 12
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %119 / 12183.3 %10 / 12
DumpForces.cpp +
100.0%
+
100.0 %38 / 3883.3 %10 / 12
EffectiveEnergyDrift.cpp +
96.9%96.9%
+
96.9 %123 / 12783.3 %10 / 12
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6384.6 %11 / 13
Print.cpp +
96.6%96.6%
+
96.6 %56 / 5884.6 %11 / 13
DumpProjections.cpp +
100.0%
+
100.0 %39 / 3984.6 %11 / 13
UpdateIf.cpp +
100.0%
+
100.0 %43 / 4384.6 %11 / 13
Read.cpp +
95.0%95.0%
+
95.0 %95 / 10085.7 %12 / 14
Plumed.cpp +
93.3%93.3%
+
93.3 %167 / 17985.7 %12 / 14
ResetCell.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
Debug.cpp +
100.0%
+
100.0 %57 / 5787.5 %7 / 8
WholeMolecules.cpp +
85.7%85.7%
+
85.7 %60 / 7087.5 %7 / 8
WrapAround.cpp +
98.1%98.1%
+
98.1 %53 / 5487.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.16
+
+ + + diff --git a/coverage/generic/index-sort-l.html b/coverage/generic/index-sort-l.html new file mode 100644 index 0000000000..800785d5af --- /dev/null +++ b/coverage/generic/index-sort-l.html @@ -0,0 +1,303 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1210127594.9 %
Date:2024-05-27 13:05: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
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
WholeMolecules.cpp +
85.7%85.7%
+
85.7 %60 / 7087.5 %7 / 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
WrapAround.cpp +
98.1%98.1%
+
98.1 %53 / 5487.5 %7 / 8
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
ResetCell.cpp +
100.0%
+
100.0 %43 / 4387.5 %7 / 8
UpdateIf.cpp +
100.0%
+
100.0 %43 / 4384.6 %11 / 13
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.16
+
+ + + diff --git a/coverage/generic/index.html b/coverage/generic/index.html new file mode 100644 index 0000000000..ef77a7aaaa --- /dev/null +++ b/coverage/generic/index.html @@ -0,0 +1,303 @@ + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1210127594.9 %
Date:2024-05-27 13:05: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 +
85.7%85.7%
+
85.7 %60 / 7087.5 %7 / 8
WrapAround.cpp +
98.1%98.1%
+
98.1 %53 / 5487.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/glass.png b/coverage/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abc00680a3093c49fdb775ae6bdb6764c95af2 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)gaEa{HEjtmSN`?>!lvI6;R0X`wF z|Ns97GD8ntt^-nxB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SSr1Gf+eGhVt|_XjA* zUgGKN%6^Gmn4d%Ph(nkFP>9RZ#WAE}PI3Z}&BVayv3^M*kj3EX>gTe~DWM4f=_Dpv literal 0 HcmV?d00001 diff --git a/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..8091a89100 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE88
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.func.html b/coverage/gridtools/ActionWithGrid.cpp.func.html new file mode 100644 index 0000000000..2c3116c450 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGrid10createGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_65
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD9gridtools14ActionWithGrid17turnOnDerivativesEv16
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE70
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.gcov.html b/coverage/gridtools/ActionWithGrid.cpp.gcov.html new file mode 100644 index 0000000000..21aadedb4e --- /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-05-27 13:05: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          88 : void ActionWithGrid::registerKeywords( Keywords& keys ) {
+      30          88 :   vesselbase::ActionWithAveraging::registerKeywords( keys );
+      31         176 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      32         176 :   keys.add("compulsory","KERNEL","gaussian","the kernel function you are using.  More details on  the kernels available "
+      33             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+      34         176 :   keys.add("optional","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions");
+      35          88 : }
+      36             : 
+      37          70 : ActionWithGrid::ActionWithGrid( const ActionOptions& ao):
+      38             :   Action(ao),
+      39             :   ActionWithAveraging(ao),
+      40          70 :   mygrid(NULL)
+      41             : {
+      42          70 : }
+      43             : 
+      44          65 : std::unique_ptr<GridVessel> ActionWithGrid::createGrid( const std::string& type, const std::string& inputstr ) {
+      45             :   // Start creating the input for the grid
+      46          65 :   std::string vstring = inputstr;
+      47         130 :   if( keywords.exists("KERNEL") ) {
+      48          90 :     std::string vconc; parse("CONCENTRATION",vconc);
+      49          45 :     if( vconc.length()>0 ) {
+      50           4 :       vstring += " TYPE=fibonacci CONCENTRATION=" + vconc;
+      51             :     } else {
+      52          86 :       std::string kstring; parse("KERNEL",kstring);
+      53          53 :       if( kstring=="DISCRETE" ) vstring += " KERNEL=" + kstring;
+      54          66 :       else vstring += " KERNEL=" + kstring + " " + getKeyword("BANDWIDTH");
+      55             :     }
+      56             :   }
+      57         130 :   vesselbase::VesselOptions da("mygrid","",-1,vstring,this);
+      58          65 :   Keywords keys; gridtools::AverageOnGrid::registerKeywords( keys );
+      59          65 :   vesselbase::VesselOptions dar( da, keys );
+      60          65 :   std::unique_ptr<GridVessel> grid;
+      61          65 :   if( type=="histogram" ) {
+      62          37 :     grid=Tools::make_unique<HistogramOnGrid>(dar);
+      63          28 :   } else if( type=="average" ) {
+      64           8 :     grid=Tools::make_unique<AverageOnGrid>(dar);
+      65          20 :   } else if( type=="grid" ) {
+      66          40 :     grid=Tools::make_unique<GridVessel>(dar);
+      67             :   } else {
+      68           0 :     plumed_merror("no way to create grid of type " + type );
+      69             :   }
+      70             :   // cppcheck-suppress danglingLifetime
+      71          65 :   mygrid=grid.get();
+      72          65 :   return grid;
+      73          65 : }
+      74             : 
+      75          16 : void ActionWithGrid::turnOnDerivatives() {
+      76          16 :   needsDerivatives(); ActionWithValue::turnOnDerivatives();
+      77          16 :   if( getStride()==1 ) setStride(0);
+      78           8 :   else if( getStride()!=0 ) error("conflicting instructions for grid - stride was set but must be evaluated on every step for derivatives - remove STRIDE keyword");
+      79          16 :   if( clearstride>1 ) error("conflicting instructions for grid - CLEAR was set but grid must be reset on every step for derivatives - remove CLEAR keyword" );
+      80          16 :   if( weights.size()>0 ) error("conflicting instructions for grid - LOGWEIGHTS was set but weights are not considered when derivatives of grid are evaluated - remove LOGWEIGHTS keyword");
+      81          16 : }
+      82             : 
+      83         215 : void ActionWithGrid::calculate() {
+      84             :   // Do nothing if derivatives are not required
+      85         215 :   if( doNotCalculateDerivatives() ) return;
+      86             :   // Clear on every step
+      87          40 :   if( mygrid ) clearAverage();
+      88             :   // Should not be any reweighting so just set these accordingly
+      89          40 :   lweight=0; cweight=1.0;
+      90             :   // Prepare to do the averaging
+      91          40 :   prepareForAveraging();
+      92             :   // Run all the tasks (if required
+      93          40 :   if( useRunAllTasks ) runAllTasks();
+      94             :   // This the averaging if it is not done using task list
+      95          20 :   else performOperations( true );
+      96             :   // Update the norm
+      97          40 :   if( mygrid ) mygrid->setNorm( cweight );
+      98             :   // Finish the averaging
+      99          40 :   finishAveraging();
+     100             :   // And reset for next step
+     101          40 :   if( mygrid ) mygrid->reset();
+     102             : }
+     103             : 
+     104       57902 : void ActionWithGrid::runTask( const unsigned& current, MultiValue& myvals ) const {
+     105             :   // Set the weight of this point
+     106       57902 :   myvals.setValue( 0, cweight ); compute( current, myvals );
+     107       57902 : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html b/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..07b7e57e50 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE39
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.func.html b/coverage/gridtools/ActionWithInputGrid.cpp.func.html new file mode 100644 index 0000000000..035d9d8091 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE39
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html b/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html new file mode 100644 index 0000000000..021fe2c4bb --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05: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          39 : void ActionWithInputGrid::registerKeywords( Keywords& keys ) {
+      30          39 :   ActionWithGrid::registerKeywords( keys );
+      31          78 :   keys.add("compulsory","GRID","the action that creates the input grid you would like to use");
+      32          78 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to use");
+      33          39 : }
+      34             : 
+      35          25 : ActionWithInputGrid::ActionWithInputGrid(const ActionOptions&ao):
+      36             :   Action(ao),
+      37             :   ActionWithGrid(ao),
+      38          25 :   ingrid(NULL)
+      39             : {
+      40          25 :   std::string mlab; parse("GRID",mlab);
+      41          25 :   vesselbase::ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<vesselbase::ActionWithVessel*>(mlab);
+      42          25 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      43          25 :   addDependency(mves);
+      44             : 
+      45          25 :   for(unsigned i=0; i<mves->getNumberOfVessels(); ++i) {
+      46          25 :     ingrid=dynamic_cast<GridVessel*>( mves->getPntrToVessel(i) );
+      47          25 :     if( ingrid ) break;
+      48             :   }
+      49          25 :   if( !ingrid ) error("input action does not calculate a grid");
+      50             : 
+      51          25 :   if( ingrid->getNumberOfComponents()==1 ) {
+      52          25 :     mycomp=0;
+      53             :   } else {
+      54           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      55           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      56           0 :     mycomp=tcomp;
+      57             :   }
+      58          25 :   log.printf("  using %uth component of grid calculated by action %s \n",mycomp,mves->getLabel().c_str() );
+      59          25 : }
+      60             : 
+      61          26 : void ActionWithInputGrid::clearAverage() {
+      62          52 :   if( mygrid->getType()=="flat" ) mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), mygrid->getNbin(), mygrid->getGridSpacing() );
+      63          26 :   ActionWithAveraging::clearAverage();
+      64          26 : }
+      65             : 
+      66          70 : void ActionWithInputGrid::prepareForAveraging() {
+      67          70 :   if( checkAllActive() ) {
+      68       93583 :     for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+      69       93513 :       if( ingrid->inactive(i) ) error("if FIND_CONTOUR is used with BUFFER option then other actions cannot be performed with grid");
+      70             :     }
+      71             :   }
+      72          70 : }
+      73             : 
+      74          21 : void ActionWithInputGrid::performOperations( const bool& from_update ) {
+      75          21 :   prepareForAveraging(); runAllTasks();
+      76          21 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html b/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html new file mode 100644 index 0000000000..a8125eea30 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.func.html b/coverage/gridtools/ActionWithInputGrid.h.func.html new file mode 100644 index 0000000000..ccffab7e8b --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.gcov.html b/coverage/gridtools/ActionWithInputGrid.h.gcov.html new file mode 100644 index 0000000000..7e10fe3ffa --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.gcov.html @@ -0,0 +1,145 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html b/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html new file mode 100644 index 0000000000..9d8c9c11a2 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.func.html b/coverage/gridtools/ActionWithIntegral.cpp.func.html new file mode 100644 index 0000000000..4c1a9e271e --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.gcov.html b/coverage/gridtools/ActionWithIntegral.cpp.gcov.html new file mode 100644 index 0000000000..39433ac768 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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           6 : void ActionWithIntegral::registerKeywords( Keywords& keys ) {
+      28           6 :   ActionWithInputGrid::registerKeywords( keys );
+      29          12 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      30          18 :   keys.remove("CLEAR"); keys.add("compulsory","CLEAR","1","the frequency with which to clear all the accumulated data.");
+      31           6 : }
+      32             : 
+      33           4 : ActionWithIntegral::ActionWithIntegral(const ActionOptions&ao):
+      34             :   Action(ao),
+      35           4 :   ActionWithInputGrid(ao)
+      36             : {
+      37           4 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      38             :   // Retrieve the volume of the grid (for integration)
+      39           4 :   volume = ingrid->getCellVolume();
+      40             :   // Create something that is going to calculate the sum of all the values
+      41             :   // at the various grid points - this is going to be the integral
+      42           8 :   std::string fake_input; addVessel( "SUM", fake_input, -1 ); readVesselKeywords();
+      43             :   // Now create task list - number of tasks is equal to the number of grid points
+      44             :   // as we have to evaluate the function at each grid points
+      45        1145 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) addTaskToList(i);
+      46             :   // And activate all tasks
+      47           4 :   deactivateAllTasks();
+      48        1145 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+      49           4 :   lockContributors();
+      50           4 : }
+      51             : 
+      52           8 : void ActionWithIntegral::turnOnDerivatives() {
+      53           8 :   ActionWithGrid::turnOnDerivatives();
+      54           8 :   forcesToApply.resize( ingrid->getNumberOfPoints() );
+      55           8 : }
+      56             : 
+      57          20 : void ActionWithIntegral::apply() {
+      58          20 :   if( getForcesFromVessels( forcesToApply ) ) ingrid->setForce( forcesToApply );
+      59          20 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html b/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html new file mode 100644 index 0000000000..79e1d14f23 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.func.html b/coverage/gridtools/ActionWithIntegral.h.func.html new file mode 100644 index 0000000000..0a42272759 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.gcov.html b/coverage/gridtools/ActionWithIntegral.h.gcov.html new file mode 100644 index 0000000000..17a2bd3656 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.gcov.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html b/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..cdb49b20c9 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.func.html b/coverage/gridtools/AverageOnGrid.cpp.func.html new file mode 100644 index 0000000000..7a086b9268 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.gcov.html b/coverage/gridtools/AverageOnGrid.cpp.gcov.html new file mode 100644 index 0000000000..5bccc9867b --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.gcov.html @@ -0,0 +1,145 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.func-sort-c.html b/coverage/gridtools/AverageOnGrid.h.func-sort-c.html new file mode 100644 index 0000000000..89c6ae5770 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.func.html b/coverage/gridtools/AverageOnGrid.h.func.html new file mode 100644 index 0000000000..0d42fb7c24 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.gcov.html b/coverage/gridtools/AverageOnGrid.h.gcov.html new file mode 100644 index 0000000000..f45bc746c5 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.gcov.html @@ -0,0 +1,125 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html b/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..1a8c951ab5 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.func.html b/coverage/gridtools/ContourFindingBase.cpp.func.html new file mode 100644 index 0000000000..6a6ab37f8e --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.gcov.html b/coverage/gridtools/ContourFindingBase.cpp.gcov.html new file mode 100644 index 0000000000..37b747ff05 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.gcov.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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           9 : void ContourFindingBase::registerKeywords( Keywords& keys ) {
+      28           9 :   ActionWithInputGrid::registerKeywords( keys );
+      29          18 :   keys.add("compulsory","CONTOUR","the value we would like to draw the contour at in the space");
+      30          18 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      31           9 : }
+      32             : 
+      33           3 : ContourFindingBase::ContourFindingBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithInputGrid(ao),
+      36           3 :   mymin(this)
+      37             : {
+      38           3 :   if( ingrid->noDerivatives() ) error("cannot find contours if input grid has no derivatives");
+      39           3 :   parse("CONTOUR",contour);
+      40           3 :   log.printf("  calculating dividing surface along which function equals %f \n", contour);
+      41           3 : }
+      42             : 
+      43             : }
+      44             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.func-sort-c.html b/coverage/gridtools/ContourFindingBase.h.func-sort-c.html new file mode 100644 index 0000000000..e986c90670 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8245
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.func.html b/coverage/gridtools/ContourFindingBase.h.func.html new file mode 100644 index 0000000000..19478776ef --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8245
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.gcov.html b/coverage/gridtools/ContourFindingBase.h.gcov.html new file mode 100644 index 0000000000..9f5229bff0 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.gcov.html @@ -0,0 +1,139 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html new file mode 100644 index 0000000000..a4738bb65b --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE17
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81D2Ev4168
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func.html b/coverage/gridtools/ConvertToFES.cpp.func.html new file mode 100644 index 0000000000..60d993a2e2 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES10isPeriodicEv0
_ZN4PLMD9gridtools12ConvertToFES12runFinalJobsEv15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZN4PLMD9gridtools12ConvertToFES7prepareEv12
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe816createERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_124ConvertToFESRegisterMe81D2Ev4168
_ZNK4PLMD9gridtools12ConvertToFES19ignoreNormalizationEv15
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.gcov.html b/coverage/gridtools/ConvertToFES.cpp.gcov.html new file mode 100644 index 0000000000..0c5c9cde1a --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05: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, H(x), to a free energy surface using F(x) = -k_B T ln H(x).
+      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       12534 : PLUMED_REGISTER_ACTION(ConvertToFES,"CONVERT_TO_FES")
+      82             : 
+      83          17 : void ConvertToFES::registerKeywords( Keywords& keys ) {
+      84          17 :   ActionWithInputGrid::registerKeywords( keys );
+      85          34 :   keys.add("optional","TEMP","the temperature at which you are operating");
+      86          34 :   keys.addFlag("MINTOZERO",false,"set the minimum in the free energy to be equal to zero");
+      87          51 :   keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      88          51 :   keys.remove("LOGWEIGHTS"); keys.remove("CLEAR"); keys.remove("NORMALIZATION");
+      89          17 : }
+      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          30 :   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.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.func-sort-c.html b/coverage/gridtools/DumpCube.cpp.func-sort-c.html new file mode 100644 index 0000000000..165835709a --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe736createERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.func.html b/coverage/gridtools/DumpCube.cpp.func.html new file mode 100644 index 0000000000..2f91a1ba9c --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe736createERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_120DumpCubeRegisterMe73D2Ev4168
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.gcov.html b/coverage/gridtools/DumpCube.cpp.gcov.html new file mode 100644 index 0000000000..72c77b2043 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(DumpCube,"DUMPCUBE")
+      74             : 
+      75           8 : void DumpCube::registerKeywords( Keywords& keys ) {
+      76           8 :   GridPrintingBase::registerKeywords( keys );
+      77          16 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to output");
+      78           8 : }
+      79             : 
+      80           6 : DumpCube::DumpCube(const ActionOptions&ao):
+      81             :   Action(ao),
+      82           6 :   GridPrintingBase(ao)
+      83             : {
+      84           6 :   fmt = fmt + " ";
+      85          12 :   if( ingrid->getType()!="flat" ) error("cannot dump grid of type " + ingrid->getType() + " using DUMPCUBE");
+      86           6 :   if( ingrid->getDimension()!=3 ) error("cannot print cube file if grid does not contain three dimensional data");
+      87             : 
+      88           6 :   if( ingrid->getNumberOfComponents()==1 ) {
+      89           6 :     mycomp=0;
+      90             :   } else {
+      91           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      92           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      93           0 :     mycomp=tcomp*(1+ingrid->getDimension()); if( ingrid->noDerivatives() ) mycomp=tcomp;
+      94           0 :     log.printf("  using %dth component of grid \n",tcomp );
+      95             :   }
+      96             : 
+      97           6 :   checkRead();
+      98           6 : }
+      99             : 
+     100           8 : void DumpCube::printGrid( OFile& ofile ) const {
+     101           8 :   double lunit = ingrid->getCubeUnits();
+     102             : 
+     103           8 :   ofile.printf("PLUMED CUBE FILE\n");
+     104           8 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     105             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     106          16 :   std::string ostr = "%d " + fmt + fmt + fmt + "\n";
+     107           8 :   ofile.printf(ostr.c_str(),1,-0.5*lunit*ingrid->getGridExtent(0),-0.5*lunit*ingrid->getGridExtent(1),-0.5*lunit*ingrid->getGridExtent(2));
+     108           8 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[0],lunit*ingrid->getGridSpacing()[0],0.0,0.0);  // Number of bins in each direction followed by
+     109           8 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[1],0.0,lunit*ingrid->getGridSpacing()[1],0.0);  // shape of voxel
+     110          16 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[2],0.0,0.0,lunit*ingrid->getGridSpacing()[2]);
+     111           8 :   ofile.printf(ostr.c_str(),1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     112           8 :   std::vector<unsigned> pp(3); std::vector<unsigned> nbin( ingrid->getNbin() );
+     113         112 :   for(pp[0]=0; pp[0]<nbin[0]; ++pp[0]) {
+     114        1800 :     for(pp[1]=0; pp[1]<nbin[1]; ++pp[1]) {
+     115       40184 :       for(pp[2]=0; pp[2]<nbin[2]; ++pp[2]) {
+     116       38488 :         ofile.printf(fmt.c_str(), ingrid->getGridElement( ingrid->getIndex(pp), mycomp ) );
+     117       38488 :         if(pp[2]%6==5) ofile.printf("\n");
+     118             :       }
+     119        1696 :       ofile.printf("\n");
+     120             :     }
+     121             :   }
+     122           8 : }
+     123             : 
+     124             : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func-sort-c.html b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..b78965da63 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe1496createERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE51
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func.html b/coverage/gridtools/DumpGrid.cpp.func.html new file mode 100644 index 0000000000..0e0635bdd7 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe1496createERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_121DumpGridRegisterMe149D2Ev4168
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE51
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.gcov.html b/coverage/gridtools/DumpGrid.cpp.gcov.html new file mode 100644 index 0000000000..ece31db7dc --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + 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-05-27 13:05: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       12602 : PLUMED_REGISTER_ACTION(DumpGrid,"DUMPGRID")
+     150             : 
+     151          51 : void DumpGrid::registerKeywords( Keywords& keys ) {
+     152          51 :   GridPrintingBase::registerKeywords( keys );
+     153          51 : }
+     154             : 
+     155          49 : DumpGrid::DumpGrid(const ActionOptions&ao):
+     156             :   Action(ao),
+     157          49 :   GridPrintingBase(ao)
+     158             : {
+     159          98 :   if( ingrid->getType()!="flat" ) error("cannot dump grid of type " + ingrid->getType() + " using DUMPGRID");
+     160          98 :   fmt = " " + fmt; checkRead();
+     161          49 : }
+     162             : 
+     163          60 : void DumpGrid::printGrid( OFile& ofile ) const {
+     164          60 :   ofile.addConstantField("normalisation");
+     165         128 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     166         136 :     ofile.addConstantField("min_" + ingrid->getComponentName(i) );
+     167         136 :     ofile.addConstantField("max_" + ingrid->getComponentName(i) );
+     168         136 :     ofile.addConstantField("nbins_" + ingrid->getComponentName(i) );
+     169         136 :     ofile.addConstantField("periodic_" + ingrid->getComponentName(i) );
+     170             :   }
+     171             : 
+     172          60 :   std::vector<double> xx( ingrid->getDimension() );
+     173          60 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     174      103636 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     175      103576 :     ingrid->getIndices( i, ind );
+     176      103576 :     if(i>0 && ingrid->getDimension()==2 && ind[ingrid->getDimension()-2]==0) ofile.printf("\n");
+     177      103576 :     ofile.fmtField(fmt); ofile.printField("normalisation", ingrid->getNorm() );
+     178      306047 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) {
+     179      404942 :       ofile.printField("min_" + ingrid->getComponentName(j), ingrid->getMin()[j] );
+     180      404942 :       ofile.printField("max_" + ingrid->getComponentName(j), ingrid->getMax()[j] );
+     181      404942 :       ofile.printField("nbins_" + ingrid->getComponentName(j), static_cast<int>(ingrid->getNbin()[j]) );
+     182      219655 :       if( ingrid->isPeriodic(j) ) ofile.printField("periodic_" + ingrid->getComponentName(j), "true" );
+     183      370574 :       else          ofile.printField("periodic_" + ingrid->getComponentName(j), "false" );
+     184             :     }
+     185             :     // Retrieve and print the grid coordinates
+     186      103576 :     ingrid->getGridPointCoordinates(i, xx );
+     187      306047 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) { ofile.fmtField(fmt); ofile.printField(ingrid->getComponentName(j),xx[j]); }
+     188      440087 :     for(unsigned j=0; j<ingrid->getNumberOfQuantities(); ++j) {
+     189      336511 :       ofile.fmtField(fmt); ofile.printField(ingrid->arg_names[ingrid->dimension+j], ingrid->getGridElement( i, j ) );
+     190             :     }
+     191      103576 :     ofile.printField();
+     192             :   }
+     193          60 : }
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.func-sort-c.html b/coverage/gridtools/FindContour.cpp.func-sort-c.html new file mode 100644 index 0000000000..b40ab8ec30 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.func.html b/coverage/gridtools/FindContour.cpp.func.html new file mode 100644 index 0000000000..8e429e64d9 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11FindContour10isPeriodicEv0
_ZN4PLMD9gridtools11FindContour15finishAveragingEv1
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZN4PLMD9gridtools11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools11FindContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_124FindContourRegisterMe113D2Ev4168
_ZNK4PLMD9gridtools11FindContour14checkAllActiveEv0
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.gcov.html b/coverage/gridtools/FindContour.cpp.gcov.html new file mode 100644 index 0000000000..ba2817a54d --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.gcov.html @@ -0,0 +1,323 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(FindContour,"FIND_CONTOUR")
+     114             : 
+     115           3 : void FindContour::registerKeywords( Keywords& keys ) {
+     116           3 :   ContourFindingBase::registerKeywords( keys );
+     117             : // We want a better way of doing this bit
+     118           6 :   keys.add("compulsory","BUFFER","0","number of buffer grid points around location where grid was found on last step.  If this is zero the full grid is calculated on each step");
+     119           6 :   keys.add("compulsory","FILE","file on which to output coordinates");
+     120           6 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     121           6 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     122           3 : }
+     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.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html b/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html new file mode 100644 index 0000000000..397b2a56bf --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.func.html b/coverage/gridtools/FindContourSurface.cpp.func.html new file mode 100644 index 0000000000..6900291fe8 --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_131FindContourSurfaceRegisterMe106D2Ev4168
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.gcov.html b/coverage/gridtools/FindContourSurface.cpp.gcov.html new file mode 100644 index 0000000000..c9af497830 --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.gcov.html @@ -0,0 +1,339 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(FindContourSurface,"FIND_CONTOUR_SURFACE")
+     107             : 
+     108           3 : void FindContourSurface::registerKeywords( Keywords& keys ) {
+     109           3 :   ContourFindingBase::registerKeywords( keys );
+     110           6 :   keys.add("compulsory","SEARCHDIR","In which directions do you wish to search for the contour.");
+     111           6 :   keys.add("compulsory","BUFFER","0","number of buffer grid points around location where grid was found on last step.  If this is zero the full grid is calculated on each step");
+     112           3 : }
+     113             : 
+     114           1 : FindContourSurface::FindContourSurface(const ActionOptions&ao):
+     115             :   Action(ao),
+     116             :   ContourFindingBase(ao),
+     117           1 :   firsttime(true),
+     118           1 :   ones(ingrid->getDimension(),1)
+     119             : {
+     120           1 :   if( ingrid->getDimension()<2 ) error("cannot find dividing surface if input grid is one dimensional");
+     121             : 
+     122           2 :   std::string dir; parse("SEARCHDIR",dir); parse("BUFFER",gbuffer);
+     123           1 :   log.printf("  calculating location of contour on %d dimensional grid \n", ingrid->getDimension()-1 );
+     124           1 :   if( gbuffer>0 ) log.printf("  after first step a subset of only %u grid points around where the countour was found will be checked\n",gbuffer);
+     125           1 :   checkRead();
+     126             : 
+     127           1 :   unsigned n=0; gdirs.resize( ingrid->getDimension()-1 );
+     128           4 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     129           3 :     if( ingrid->getComponentName(i)==dir ) {
+     130           1 :       dir_n=i;
+     131             :     } else {
+     132           2 :       if( n==gdirs.size() ) error("could not find " + dir + " direction in input grid");
+     133           2 :       gdirs[n]=i; n++;
+     134             :     }
+     135             :   }
+     136           1 :   if( n!=(ingrid->getDimension()-1) ) error("output of grid is not understood");
+     137             : 
+     138             :   // Create the input from the old string
+     139           2 :   std::string vstring = "COMPONENTS=" + getLabel() + " COORDINATES=" + ingrid->getComponentName( gdirs[0] );
+     140           2 :   for(unsigned i=1; i<gdirs.size(); ++i) vstring += "," + ingrid->getComponentName( gdirs[i] );
+     141             :   vstring += " PBC=";
+     142           1 :   if( ingrid->isPeriodic(gdirs[0]) ) vstring+="T";
+     143             :   else vstring+="F";
+     144           2 :   for(unsigned i=1; i<gdirs.size(); ++i) {
+     145           1 :     if( ingrid->isPeriodic(gdirs[i]) ) vstring+=",T"; else vstring+=",F";
+     146             :   }
+     147           2 :   auto grid=createGrid( "grid", vstring ); grid->setNoDerivatives();
+     148           1 :   setAveragingAction( std::move(grid), true );
+     149           2 : }
+     150             : 
+     151           3 : void FindContourSurface::clearAverage() {
+     152             :   // Set the boundaries of the output grid
+     153           3 :   std::vector<double> fspacing; std::vector<unsigned> snbins( ingrid->getDimension()-1 );
+     154           3 :   std::vector<std::string> smin( ingrid->getDimension()-1 ), smax( ingrid->getDimension()-1 );
+     155           9 :   for(unsigned i=0; i<gdirs.size(); ++i) {
+     156          18 :     smin[i]=ingrid->getMin()[gdirs[i]]; smax[i]=ingrid->getMax()[gdirs[i]];
+     157           6 :     snbins[i]=ingrid->getNbin()[gdirs[i]];
+     158             :   }
+     159           3 :   mygrid->setBounds( smin, smax, snbins, fspacing); resizeFunctions();
+     160           3 :   ActionWithAveraging::clearAverage();
+     161           6 : }
+     162             : 
+     163           3 : void FindContourSurface::prepareForAveraging() {
+     164             :   // Create a task list if first time
+     165           3 :   if( firsttime ) {
+     166           1 :     std::vector<unsigned> find( ingrid->getDimension() );
+     167           1 :     std::vector<unsigned> ind( mygrid->getDimension() );
+     168         197 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     169         196 :       find.assign( find.size(), 0 ); mygrid->getIndices( i, ind );
+     170         588 :       for(unsigned j=0; j<gdirs.size(); ++j) find[gdirs[j]]=ind[j];
+     171             :       // Current will be set equal to the start point for this grid index
+     172         196 :       addTaskToList( ingrid->getIndex(find) );
+     173             :     }
+     174             :     // And prepare the task list
+     175           1 :     deactivateAllTasks();
+     176         197 :     for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     177           1 :     lockContributors();
+     178             :     // Set the direction in which to look for the contour
+     179           1 :     direction.resize( ingrid->getDimension(), 0 );
+     180           1 :     direction[dir_n] = 0.999999999*ingrid->getGridSpacing()[dir_n];
+     181             :   }
+     182           3 : }
+     183             : 
+     184           3 : void FindContourSurface::finishAveraging() {
+     185             :   ContourFindingBase::finishAveraging();
+     186             :   // And update the list of active grid points
+     187           3 :   if( gbuffer>0 ) {
+     188           3 :     std::vector<double> dx( ingrid->getGridSpacing() );
+     189           3 :     std::vector<double> point( ingrid->getDimension() );
+     190           3 :     std::vector<double> lpoint( mygrid->getDimension() );
+     191             :     std::vector<unsigned> neighbours; unsigned num_neighbours;
+     192           3 :     std::vector<unsigned> ugrid_indices( ingrid->getDimension() );
+     193           3 :     std::vector<bool> active( ingrid->getNumberOfPoints(), false );
+     194           3 :     std::vector<unsigned> gbuffer_vec( ingrid->getDimension(), gbuffer );
+     195         591 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     196             :       // Retrieve the coordinates of this grid point
+     197         588 :       mygrid->getGridPointCoordinates( i, lpoint );
+     198         588 :       point[dir_n] = mygrid->getGridElement( i, 0 );
+     199             :       // 0.5*dx added here to prevent problems with flooring of grid points
+     200        1764 :       for(unsigned j=0; j<gdirs.size(); ++j) point[gdirs[j]]=lpoint[j] + 0.5*dx[gdirs[j]];
+     201         588 :       ingrid->getIndices( point, ugrid_indices );
+     202             :       // Now activate buffer region
+     203         588 :       ingrid->getNeighbors( ugrid_indices, gbuffer_vec, num_neighbours, neighbours );
+     204       16464 :       for(unsigned n=0; n<num_neighbours; ++n) active[ neighbours[n] ]=true;
+     205             :     }
+     206           3 :     ingrid->activateThesePoints( active );
+     207             :   }
+     208           3 :   firsttime=false;
+     209           3 : }
+     210             : 
+     211         588 : void FindContourSurface::compute( const unsigned& current, MultiValue& myvals ) const {
+     212             :   std::vector<unsigned> neighbours; unsigned num_neighbours; unsigned nfound=0; double minp=0;
+     213         588 :   std::vector<unsigned> bins_n( ingrid->getNbin() ); unsigned shiftn=current;
+     214         588 :   std::vector<unsigned> ind( ingrid->getDimension() ); std::vector<double> point( ingrid->getDimension() );
+     215             : #ifndef NDEBUG
+     216             :   std::vector<unsigned> oind( mygrid->getDimension() ); mygrid->getIndices( current, oind );
+     217             : #endif
+     218       16749 :   for(unsigned i=0; i<bins_n[dir_n]; ++i) {
+     219             : #ifndef NDEBUG
+     220             :     std::vector<unsigned> base_ind( ingrid->getDimension() ); ingrid->getIndices( shiftn, base_ind );
+     221             :     for(unsigned j=0; j<gdirs.size(); ++j) plumed_dbg_assert( base_ind[gdirs[j]]==oind[j] );
+     222             : #endif
+     223             :     // Ensure inactive grid points are ignored
+     224       16749 :     if( ingrid->inactive( shiftn ) ) { shiftn += ingrid->getStride()[dir_n]; continue; }
+     225             :     // Get the index of the current grid point
+     226        7857 :     ingrid->getIndices( shiftn, ind );
+     227             :     // Exit if we are at the edge of the grid
+     228        7857 :     if( !ingrid->isPeriodic(dir_n) && (ind[dir_n]+1)==bins_n[dir_n] ) {
+     229           0 :       shiftn += ingrid->getStride()[dir_n]; continue;
+     230             :     }
+     231             : 
+     232             :     // Ensure points with inactive neighbours are ignored
+     233        7857 :     ingrid->getNeighbors( ind, ones, num_neighbours, neighbours );
+     234             :     bool cycle=false;
+     235      179020 :     for(unsigned j=0; j<num_neighbours; ++j) {
+     236      172753 :       if( ingrid->inactive( neighbours[j]) ) { cycle=true; break; }
+     237             :     }
+     238        7857 :     if( cycle ) { shiftn += ingrid->getStride()[dir_n]; continue; }
+     239             : 
+     240             :     // Now get the function value at two points
+     241        6267 :     double val1=getFunctionValue( shiftn ) - contour; double val2;
+     242        6267 :     if( (ind[dir_n]+1)==bins_n[dir_n] ) val2 = getFunctionValue( current ) - contour;
+     243        6267 :     else val2=getFunctionValue( shiftn + ingrid->getStride()[dir_n] ) - contour;
+     244             : 
+     245             :     // Check if the minimum is bracketed
+     246        6267 :     if( val1*val2<0 ) {
+     247         588 :       ingrid->getGridPointCoordinates( shiftn, point ); findContour( direction, point );
+     248         588 :       minp=point[dir_n]; nfound++; break;
+     249             :     }
+     250             : 
+     251             : 
+     252             :     // This moves us on to the next point
+     253        5679 :     shiftn += ingrid->getStride()[dir_n];
+     254             :   }
+     255             :   if( nfound==0 ) {
+     256           0 :     std::string num; Tools::convert( getStep(), num );
+     257           0 :     error("On step " + num + " failed to find required grid point");
+     258             :   }
+     259             :   myvals.setValue( 1, minp );
+     260         588 : }
+     261             : 
+     262             : }
+     263             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html b/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html new file mode 100644 index 0000000000..19311d5761 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe1226createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.func.html b/coverage/gridtools/FindSphericalContour.cpp.func.html new file mode 100644 index 0000000000..34f3d42391 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe1226createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_133FindSphericalContourRegisterMe122D2Ev4168
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.gcov.html b/coverage/gridtools/FindSphericalContour.cpp.gcov.html new file mode 100644 index 0000000000..67006382a3 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(FindSphericalContour,"FIND_SPHERICAL_CONTOUR")
+     123             : 
+     124           3 : void FindSphericalContour::registerKeywords( Keywords& keys ) {
+     125           3 :   ContourFindingBase::registerKeywords( keys );
+     126           6 :   keys.add("compulsory","NPOINTS","the number of points for which we are looking for the contour");
+     127           6 :   keys.add("compulsory","INNER_RADIUS","the minimum radius on which to look for the contour");
+     128           6 :   keys.add("compulsory","OUTER_RADIUS","the outer radius on which to look for the contour");
+     129           6 :   keys.add("compulsory","NBINS","1","the number of discrete sections in which to divide the distance between the inner and outer radius when searching for a contour");
+     130           3 : }
+     131             : 
+     132           1 : FindSphericalContour::FindSphericalContour(const ActionOptions&ao):
+     133             :   Action(ao),
+     134           1 :   ContourFindingBase(ao)
+     135             : {
+     136           1 :   if( ingrid->getDimension()!=3 ) error("input grid must be three dimensional");
+     137             : 
+     138           1 :   unsigned npoints; parse("NPOINTS",npoints);
+     139           1 :   log.printf("  searching for %u points on dividing surface \n",npoints);
+     140           3 :   parse("INNER_RADIUS",min); parse("OUTER_RADIUS",max); parse("NBINS",nbins);
+     141           1 :   log.printf("  expecting to find dividing surface at radii between %f and %f \n",min,max);
+     142           1 :   log.printf("  looking for contour in windows of length %f \n", (max-min)/nbins);
+     143             :   // Set this here so the same set of grid points are used on every turn
+     144           1 :   std::string vstring = "TYPE=fibonacci COMPONENTS=" + getLabel() + " COORDINATES=x,y,z PBC=F,F,F";
+     145           2 :   auto grid=createGrid( "grid", vstring ); grid->setNoDerivatives();
+     146           1 :   setAveragingAction( std::move(grid), true );
+     147             :   // use mygrid, since at this point grid has been moved
+     148           1 :   mygrid->setupFibonacciGrid( npoints );
+     149             : 
+     150           1 :   checkRead();
+     151             :   // Create a task list
+     152         101 :   for(unsigned i=0; i<npoints; ++i) addTaskToList( i );
+     153           1 :   deactivateAllTasks();
+     154         101 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     155           1 :   lockContributors();
+     156           2 : }
+     157             : 
+     158         100 : void FindSphericalContour::compute( const unsigned& current, MultiValue& myvals ) const {
+     159             :   // Generate contour point on inner sphere
+     160         100 :   std::vector<double> contour_point(3), direction(3), der(3), tmp(3);
+     161             :   // Retrieve this contour point from grid
+     162         100 :   mygrid->getGridPointCoordinates( current, direction );
+     163             :   // Now setup contour point on inner sphere
+     164         400 :   for(unsigned j=0; j<3; ++j) {
+     165         300 :     contour_point[j] = min*direction[j];
+     166         300 :     direction[j] = (max-min)*direction[j] / static_cast<double>(nbins);
+     167             :   }
+     168             :   bool found=false;
+     169         100 :   for(unsigned k=0; k<nbins; ++k) {
+     170         400 :     for(unsigned j=0; j<3; ++j) tmp[j] = contour_point[j] + direction[j];
+     171             :     double val1 = getDifferenceFromContour( contour_point, der );
+     172             :     double val2 = getDifferenceFromContour( tmp, der );
+     173         100 :     if( val1*val2<0 ) {
+     174             :       findContour( direction, contour_point );
+     175         400 :       double norm=0; for(unsigned j=0; j<3; ++j) norm += contour_point[j]*contour_point[j];
+     176         100 :       myvals.setValue( 1, std::sqrt(norm) ); found=true; break;
+     177             :     }
+     178           0 :     for(unsigned j=0; j<3; ++j) contour_point[j] = tmp[j];
+     179             :   }
+     180           0 :   if( !found ) error("range does not bracket the dividing surface");
+     181         100 : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.func-sort-c.html b/coverage/gridtools/FourierTransform.cpp.func-sort-c.html new file mode 100644 index 0000000000..517d80b1f5 --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.func.html b/coverage/gridtools/FourierTransform.cpp.func.html new file mode 100644 index 0000000000..ba0afa24f4 --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_128FourierTransformRegisterMe87D2Ev4168
_ZN4PLMD9gridtools16FourierTransform10isPeriodicEv0
_ZN4PLMD9gridtools16FourierTransform12clearAverageEv1
_ZN4PLMD9gridtools16FourierTransform16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
_ZN4PLMD9gridtools16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools16FourierTransform7computeERKjRNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.gcov.html b/coverage/gridtools/FourierTransform.cpp.gcov.html new file mode 100644 index 0000000000..bae056672f --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.gcov.html @@ -0,0 +1,328 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(FourierTransform,"FOURIER_TRANSFORM")
+      88             : 
+      89           3 : void FourierTransform::registerKeywords( Keywords& keys ) {
+      90           6 :   ActionWithInputGrid::registerKeywords( keys ); keys.remove("BANDWIDTH"); keys.remove("KERNEL");
+      91           6 :   keys.add("optional","FT_TYPE","choose what kind of data you want as output on the grid. Possible values are: ABS = compute the complex modulus of Fourier coefficients (DEFAULT); NORM = compute the norm (i.e. ABS^2) of Fourier coefficients; COMPLEX = store the FFTW complex output on the grid (as a vector).");
+      92           6 :   keys.add("compulsory","FOURIER_PARAMETERS","default","what kind of normalization is applied to the output and if the Fourier transform in FORWARD or BACKWARD. This keyword takes the form FOURIER_PARAMETERS=A,B, where A and B can be 0, 1 or -1. The default values are A=1 (no normalization at all) and B=1 (forward FFT). Other possible choices for A are: "
+      93             :            "A=-1: normalize by the number of data, "
+      94             :            "A=0: normalize by the square root of the number of data (one forward and followed by backward FFT recover the original data). ");
+      95           3 : }
+      96             : 
+      97           1 : FourierTransform::FourierTransform(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   ActionWithInputGrid(ao),
+     100           1 :   real_output(true),
+     101           1 :   store_norm(false),
+     102           1 :   fourier_params(2)
+     103             : {
+     104             : #ifndef __PLUMED_HAS_FFTW
+     105             :   error("this feature is only available if you compile PLUMED with FFTW");
+     106             : #else
+     107           1 :   if( ingrid->getDimension()!=2 ) error("fourier transform currently only works with two dimensional grids");
+     108             : 
+     109             :   // Get the type of FT
+     110           2 :   parse("FT_TYPE",output_type);
+     111           1 :   if (output_type.length()==0) {
+     112           0 :     log<<"  keyword FT_TYPE unset. By default output grid will contain REAL Fourier coefficients\n";
+     113           2 :   } else if ( output_type=="ABS" || output_type=="abs") {
+     114           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the MODULUS of Fourier coefficients\n";
+     115           2 :   } else if ( output_type=="NORM" || output_type=="norm") {
+     116           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the NORM of Fourier coefficients\n";
+     117           0 :     store_norm=true;
+     118           2 :   } else if ( output_type=="COMPLEX" || output_type=="complex" ) {
+     119           1 :     log<<"  keyword FT_TYPE is '"<< output_type <<"' : output grid will contain the COMPLEX Fourier coefficients\n";
+     120           1 :     real_output=false;
+     121           0 :   } else error("keyword FT_TYPE unrecognized!");
+     122             : 
+     123             :   // Normalize output?
+     124           2 :   std::string params_str; parse("FOURIER_PARAMETERS",params_str);
+     125           1 :   if (params_str=="default") {
+     126           0 :     fourier_params.assign( fourier_params.size(), 1 );
+     127           0 :     log.printf("  default values of Fourier parameters A=%i, B=%i : the output will NOT be normalized and BACKWARD Fourier transform is computed \n", fourier_params[0],fourier_params[1]);
+     128             :   } else {
+     129           1 :     std::vector<std::string> fourier_str = Tools::getWords(params_str, "\t\n ,");
+     130           1 :     if (fourier_str.size()>2) error("FOURIER_PARAMETERS can take just two values");
+     131           3 :     for (unsigned i=0; i<fourier_str.size(); ++i) {
+     132           2 :       Tools::convert(fourier_str[i],fourier_params[i]);
+     133           2 :       if (fourier_params[i]>1 || fourier_params[i]<-1) error("values accepted for FOURIER_PARAMETERS are only -1, 1 or 0");
+     134             :     }
+     135           1 :     log.printf("  Fourier parameters are A=%i, B=%i \n", fourier_params[0],fourier_params[1]);
+     136           1 :   }
+     137             : 
+     138             : 
+     139             :   // Create the input from the old string
+     140             :   std::string vstring;
+     141           1 :   if (real_output) {
+     142           0 :     if (!store_norm) vstring="COMPONENTS=" + getLabel() + "_abs";
+     143           0 :     else vstring="COMPONENTS=" + getLabel() + "_norm";
+     144           2 :   } else vstring="COMPONENTS=" + getLabel() + "_real," + getLabel() + "_imag";
+     145             : 
+     146             :   // Set COORDINATES keyword
+     147           2 :   vstring += " COORDINATES=" + ingrid->getComponentName( 0 );
+     148           3 :   for(unsigned i=1; i<ingrid->getDimension(); ++i) vstring += "," + ingrid->getComponentName( i );
+     149             : 
+     150             :   // Set PBC keyword
+     151             :   vstring += " PBC=";
+     152           1 :   if( ingrid->isPeriodic(0) ) vstring+="T"; else vstring+="F";
+     153           2 :   for(unsigned i=1; i<ingrid->getDimension(); ++i) {
+     154           1 :     if( ingrid->isPeriodic(i) ) vstring+=",T"; else vstring+=",F";
+     155             :   }
+     156             : 
+     157             : 
+     158             :   // Create a grid on which to store the fourier transform of the input grid
+     159           1 :   auto grid=createGrid( "grid", vstring );
+     160           1 :   if( ingrid->noDerivatives() ) grid->setNoDerivatives();
+     161           1 :   setAveragingAction( std::move(grid), false );
+     162             : 
+     163           1 :   checkRead();
+     164             : #endif
+     165           2 : }
+     166             : 
+     167           1 : void FourierTransform::clearAverage() {
+     168             :   std::vector<double> fspacing;
+     169           1 :   std::vector<std::string> ft_min( ingrid->getMin() ), ft_max( ingrid->getMax() );
+     170           3 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     171           2 :     Tools::convert( 0.0, ft_min[i] ); Tools::convert( 2.0*pi*ingrid->getNbin()[i]/ ingrid->getGridExtent(i), ft_max[i] );
+     172             :   }
+     173           2 :   mygrid->setBounds( ft_min, ft_max, ingrid->getNbin(), fspacing); resizeFunctions();
+     174           1 :   ActionWithAveraging::clearAverage();
+     175           2 : }
+     176             : 
+     177             : #ifdef __PLUMED_HAS_FFTW
+     178           4 : void FourierTransform::performOperations( const bool& from_update ) {
+     179             : 
+     180             :   // Spacing of the real grid
+     181           4 :   std::vector<double> g_spacing ( ingrid->getGridSpacing() );
+     182             : 
+     183             :   // *** CHECK CORRECT k-GRID BOUNDARIES ***
+     184             :   //log<<"Real grid boundaries: \n"
+     185             :   //    <<"  min_x: "<<mygrid->getMin()[0]<<"  min_y: "<<mygrid->getMin()[1]<<"\n"
+     186             :   //    <<"  max_x: "<<mygrid->getMax()[0]<<"  max_y: "<<mygrid->getMax()[1]<<"\n"
+     187             :   //    <<"K-grid boundaries:"<<"\n"
+     188             :   //    <<"  min_x: "<<ft_min[0]<<"  min_y: "<<ft_min[1]<<"\n"
+     189             :   //    <<"  max_x: "<<ft_max[0]<<"  max_y: "<<ft_max[1]<<"\n";
+     190             : 
+     191             :   // Get the size of the input data arrays (to allocate FFT data)
+     192           4 :   size_t fft_dimension=static_cast<size_t>( ingrid->getNumberOfPoints() );
+     193           4 :   std::vector<unsigned> N_input_data( ingrid->getNbin() );
+     194          12 :   for(unsigned i=0; i<N_input_data.size(); ++i) if( !ingrid->isPeriodic(i) ) N_input_data[i]++;
+     195             :   // size_t fft_dimension=1; for(unsigned i=0; i<N_input_data.size(); ++i) fft_dimension*=static_cast<size_t>( N_input_data[i] );
+     196             : 
+     197             :   // FFT arrays
+     198           4 :   std::vector<std::complex<double> > input_data(fft_dimension), fft_data(fft_dimension);
+     199             : 
+     200             : 
+     201             :   // Fill real input with the data on the grid
+     202           4 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     203       40808 :   for (unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     204             :     // Get point indices
+     205       40804 :     ingrid->getIndices(i, ind);
+     206             :     // Fill input data in row-major order
+     207       40804 :     input_data[ind[0]*N_input_data[0]+ind[1]].real( getFunctionValue( i ) );
+     208       40804 :     input_data[ind[0]*N_input_data[0]+ind[1]].imag( 0.0 );
+     209             :   }
+     210             : 
+     211             :   // *** HERE is the only clear limitation: I'm computing explicitly a 2D FT. It should not happen to deal with other than two-dimensional grid ...
+     212           4 :   fftw_plan plan_complex = fftw_plan_dft_2d(N_input_data[0], N_input_data[1], reinterpret_cast<fftw_complex*>(&input_data[0]), reinterpret_cast<fftw_complex*>(&fft_data[0]), fourier_params[1], FFTW_ESTIMATE);
+     213             : 
+     214             :   // Compute FT
+     215           4 :   fftw_execute( plan_complex );
+     216             : 
+     217             :   // Compute the normalization constant
+     218             :   double norm=1.0;
+     219          12 :   for (unsigned i=0; i<N_input_data.size(); ++i) {
+     220           8 :     norm *= pow( N_input_data[i], (1-fourier_params[0])/2 );
+     221             :   }
+     222             : 
+     223             :   // Save FT data to output grid
+     224           4 :   std::vector<unsigned> N_out_data ( mygrid->getNbin() );
+     225           8 :   std::vector<unsigned> out_ind ( mygrid->getDimension() );
+     226       40808 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     227       40804 :     mygrid->getIndices( i, out_ind );
+     228       40804 :     if (real_output) {
+     229             :       double ft_value;
+     230             :       // Compute abs/norm and fix normalization
+     231           0 :       if (!store_norm) ft_value=std::abs( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     232           0 :       else ft_value=std::norm( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     233             :       // Set the value
+     234           0 :       mygrid->setGridElement( i, 0, ft_value );
+     235             :     } else {
+     236             :       double ft_value_real, ft_value_imag;
+     237       40804 :       ft_value_real=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].real() / norm;
+     238       40804 :       ft_value_imag=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].imag() / norm;
+     239             :       // Set values
+     240       40804 :       mygrid->setGridElement( i, 0, ft_value_real);
+     241       40804 :       mygrid->setGridElement( i, 1, ft_value_imag);
+     242             :     }
+     243             :   }
+     244             : 
+     245             :   // Free FFTW stuff
+     246           4 :   fftw_destroy_plan(plan_complex);
+     247             : 
+     248           4 : }
+     249             : #endif
+     250             : 
+     251             : } // end namespace 'gridtools'
+     252             : } // end namespace 'PLMD'
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html b/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..deb75a9361 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.func.html b/coverage/gridtools/GridPrintingBase.cpp.func.html new file mode 100644 index 0000000000..a31e581ec6 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.gcov.html b/coverage/gridtools/GridPrintingBase.cpp.gcov.html new file mode 100644 index 0000000000..9d2f12cf0e --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.gcov.html @@ -0,0 +1,181 @@ + + + + + + + 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-05-27 13:05: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          63 : void GridPrintingBase::registerKeywords( Keywords& keys ) {
+      31          63 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         126 :   keys.add("compulsory","GRID","the action that creates the grid you would like to output");
+      33         126 :   keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file.  The default "
+      34             :            "value of 0 ensures that the grid is only output at the end of the trajectory");
+      35         126 :   keys.add("compulsory","FILE","density","the file on which to write the grid.");
+      36         126 :   keys.add("compulsory","REPLICA","0","the replica for which you would like to output this information");
+      37         126 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      38          63 : }
+      39             : 
+      40          57 : GridPrintingBase::GridPrintingBase(const ActionOptions&ao):
+      41             :   Action(ao),
+      42             :   ActionPilot(ao),
+      43         114 :   fmt("%f"),
+      44          57 :   output_for_all_replicas(false)
+      45             : {
+      46          57 :   std::string mlab; parse("GRID",mlab);
+      47          57 :   vesselbase::ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<vesselbase::ActionWithVessel*>(mlab);
+      48          57 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      49          57 :   addDependency(mves);
+      50             : 
+      51          57 :   for(unsigned i=0; i<mves->getNumberOfVessels(); ++i) {
+      52          57 :     ingrid=dynamic_cast<GridVessel*>( mves->getPntrToVessel(i) );
+      53          57 :     if( ingrid ) break;
+      54             :   }
+      55          57 :   if( !ingrid ) error("input action does not calculate a grid");
+      56             : 
+      57         114 :   parse("FILE",filename);
+      58          57 :   if(filename.length()==0) error("name out output file was not specified");
+      59          57 :   log.printf("  outputting grid calculated by action %s to file named %s",mves->getLabel().c_str(), filename.c_str() );
+      60         114 :   if( keywords.exists("FMT") ) {
+      61         110 :     parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() );
+      62             :   } else {
+      63           2 :     log.printf("\n");
+      64             :   }
+      65         114 :   std::string rep_data; parse("REPLICA",rep_data);
+      66          57 :   if( rep_data=="all" ) output_for_all_replicas=true;
+      67          57 :   else { preps.resize(1); Tools::convert( rep_data, preps[0] ); }
+      68          57 :   if( output_for_all_replicas ) log.printf("  outputting files for all replicas \n");
+      69             :   else {
+      70          57 :     log.printf("  outputting data for replicas ");
+      71         114 :     for(unsigned i=0; i<preps.size(); ++i) log.printf("%d ", preps[i] );
+      72             :   }
+      73          57 : }
+      74             : 
+      75          68 : void GridPrintingBase::update() {
+      76          68 :   if( !output_for_all_replicas ) {
+      77          68 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+      78          68 :     for(unsigned i=0; i<preps.size(); ++i) {
+      79          68 :       if( myrep==preps[i] ) { found=true; break; }
+      80             :     }
+      81          93 :     if( !found ) return;
+      82             :   }
+      83          68 :   if( getStep()==0 || getStride()==0 ) return ;
+      84             : 
+      85          43 :   OFile ofile; ofile.link(*this);
+      86          43 :   ofile.setBackupString("analysis");
+      87          43 :   ofile.open( filename ); printGrid( ofile );
+      88          43 : }
+      89             : 
+      90          57 : void GridPrintingBase::runFinalJobs() {
+      91          57 :   if( !output_for_all_replicas ) {
+      92          57 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+      93          62 :     for(unsigned i=0; i<preps.size(); ++i) {
+      94          57 :       if( myrep==preps[i] ) { found=true; break; }
+      95             :     }
+      96          82 :     if( !found ) return;
+      97             :   }
+      98          52 :   if( getStride()>0 ) return;
+      99             : 
+     100          27 :   OFile ofile; ofile.link(*this);
+     101          27 :   ofile.open( filename ); printGrid( ofile );
+     102          27 : }
+     103             : 
+     104             : }
+     105             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.func-sort-c.html b/coverage/gridtools/GridPrintingBase.h.func-sort-c.html new file mode 100644 index 0000000000..f2ab75224c --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.func.html b/coverage/gridtools/GridPrintingBase.h.func.html new file mode 100644 index 0000000000..a34e50d194 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.gcov.html b/coverage/gridtools/GridPrintingBase.h.gcov.html new file mode 100644 index 0000000000..7b9b744406 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func-sort-c.html b/coverage/gridtools/GridSearch.h.func-sort-c.html new file mode 100644 index 0000000000..f0c4187939 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func.html b/coverage/gridtools/GridSearch.h.func.html new file mode 100644 index 0000000000..3760a5ff1e --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.gcov.html b/coverage/gridtools/GridSearch.h.gcov.html new file mode 100644 index 0000000000..879c27f2d1 --- /dev/null +++ b/coverage/gridtools/GridSearch.h.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html b/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html new file mode 100644 index 0000000000..3503203faf --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.func.html b/coverage/gridtools/GridToXYZ.cpp.func.html new file mode 100644 index 0000000000..478993cf9e --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe506createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_121GridToXYZRegisterMe50D2Ev4168
_ZN4PLMD9gridtools9GridToXYZ16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9gridtools9GridToXYZC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools9GridToXYZC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools9GridToXYZ9printGridERNS_5OFileE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.gcov.html b/coverage/gridtools/GridToXYZ.cpp.gcov.html new file mode 100644 index 0000000000..dcd3f61c68 --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(GridToXYZ,"GRID_TO_XYZ")
+      51             : 
+      52           4 : void GridToXYZ::registerKeywords( Keywords& keys ) {
+      53           4 :   GridPrintingBase::registerKeywords( keys );
+      54           8 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to output");
+      55           8 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      56           8 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+      57           4 :   keys.remove("FMT");
+      58           4 : }
+      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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.func-sort-c.html b/coverage/gridtools/GridVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..f5856d40c1 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.func-sort-c.html @@ -0,0 +1,228 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.func.html b/coverage/gridtools/GridVessel.cpp.func.html new file mode 100644 index 0000000000..c4ae8abb23 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.func.html @@ -0,0 +1,228 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.gcov.html b/coverage/gridtools/GridVessel.cpp.gcov.html new file mode 100644 index 0000000000..b9ced51e71 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.gcov.html @@ -0,0 +1,602 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.func-sort-c.html b/coverage/gridtools/GridVessel.h.func-sort-c.html new file mode 100644 index 0000000000..c23ac2df98 --- /dev/null +++ b/coverage/gridtools/GridVessel.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.func.html b/coverage/gridtools/GridVessel.h.func.html new file mode 100644 index 0000000000..f276eed422 --- /dev/null +++ b/coverage/gridtools/GridVessel.h.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.gcov.html b/coverage/gridtools/GridVessel.h.gcov.html new file mode 100644 index 0000000000..ae5f4ea376 --- /dev/null +++ b/coverage/gridtools/GridVessel.h.gcov.html @@ -0,0 +1,363 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html b/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..e25d983ac1 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.func.html b/coverage/gridtools/HistogramOnGrid.cpp.func.html new file mode 100644 index 0000000000..5bb1a097fc --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.gcov.html b/coverage/gridtools/HistogramOnGrid.cpp.gcov.html new file mode 100644 index 0000000000..8c196939b6 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-05-27 13:05: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             :   }
+      75          50 : }
+      76             : 
+      77       23625 : std::unique_ptr<KernelFunctions> HistogramOnGrid::getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const {
+      78       23625 :   if( discrete ) {
+      79        4222 :     plumed_assert( getType()=="flat" );
+      80        4222 :     num_neigh=1; for(unsigned i=0; i<dimension; ++i) point[i] += 0.5*dx[i];
+      81        2111 :     neighbors[0] = getIndex( point ); return NULL;
+      82       43028 :   } else if( getType()=="flat" ) {
+      83       21457 :     auto kernel=Tools::make_unique<KernelFunctions>( point, bandwidths, kerneltype, "DIAGONAL", 1.0 );
+      84             : // GB: Now values is destroyed when exiting this function.
+      85             : // I think before there was a leak
+      86       21457 :     std::vector<std::unique_ptr<Value>> values=getVectorOfValues();
+      87       64371 :     kernel->normalize( Tools::unique2raw(values) ); getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors );
+      88             :     return kernel;
+      89       21571 :   } else if( getType()=="fibonacci" ) {
+      90          57 :     getNeighbors( point, nneigh, num_neigh, neighbors );
+      91             :     return NULL;
+      92             :   } else {
+      93           0 :     plumed_error();
+      94             :   }
+      95             :   return NULL;
+      96             : }
+      97             : 
+      98      115624 : std::vector<std::unique_ptr<Value>> HistogramOnGrid::getVectorOfValues() const {
+      99             :   std::vector<std::unique_ptr<Value>> vv;
+     100      225230 :   for(unsigned i=0; i<dimension; ++i) {
+     101      167418 :     vv.emplace_back(Tools::make_unique<Value>());
+     102      167418 :     if( pbc[i] ) vv[i]->setDomain( str_min[i], str_max[i] );
+     103       64454 :     else vv[i]->setNotPeriodic();
+     104             :   }
+     105       57812 :   return vv;
+     106           0 : }
+     107             : 
+     108       38461 : void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+     109       38461 :   if( addOneKernelAtATime ) {
+     110             :     plumed_dbg_assert( myvals.getNumberOfValues()==2 && !wasforced );
+     111       14908 :     std::vector<double> der( dimension );
+     112       54492 :     for(unsigned i=0; i<dimension; ++i) der[i]=myvals.getDerivative( 1, i );
+     113       14908 :     accumulate( getAction()->getPositionInCurrentTaskList(current), myvals.get(0), myvals.get(1), der, buffer );
+     114             :   } else {
+     115             :     plumed_dbg_assert( myvals.getNumberOfValues()==dimension+2 );
+     116       23553 :     std::vector<double> point( dimension ); double weight=myvals.get(0)*myvals.get( 1+dimension );
+     117       89610 :     for(unsigned i=0; i<dimension; ++i) point[i]=myvals.get( 1+i );
+     118             :     // Get the kernel
+     119       23553 :     unsigned num_neigh; std::vector<unsigned> neighbors(1);
+     120       23553 :     std::vector<double> der( dimension );
+     121       23553 :     std::unique_ptr<KernelFunctions> kernel=getKernelAndNeighbors( point, num_neigh, neighbors );
+     122             : 
+     123       27879 :     if( !kernel && getType()=="flat" ) {
+     124        2106 :       plumed_dbg_assert( num_neigh==1 ); der.resize(0);
+     125        2106 :       accumulate( neighbors[0], weight, 1.0, der, buffer );
+     126             :     } else {
+     127             :       double totwforce=0.0;
+     128       21447 :       std::vector<double> intforce( 2*dimension, 0.0 );
+     129       21447 :       std::vector<std::unique_ptr<Value>> vv( getVectorOfValues() );
+     130             : 
+     131       21447 :       double newval; std::vector<unsigned> tindices( dimension ); std::vector<double> xx( dimension );
+     132    20582512 :       for(unsigned i=0; i<num_neigh; ++i) {
+     133    20561065 :         unsigned ineigh=neighbors[i];
+     134    20561065 :         if( inactive( ineigh ) ) continue ;
+     135    11848693 :         getGridPointCoordinates( ineigh, tindices, xx );
+     136    11848693 :         if( kernel ) {
+     137    47354528 :           for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
+     138    11843920 :           newval = kernel->evaluate( Tools::unique2raw(vv), der, true );
+     139             :         } else {
+     140             :           // Evalulate dot product
+     141       19092 :           double dot=0; for(unsigned j=0; j<dimension; ++j) { dot+=xx[j]*point[j]; der[j]=xx[j]; }
+     142             :           // Von misses distribution for concentration parameter
+     143        4773 :           newval = von_misses_norm*exp( von_misses_concentration*dot );
+     144             :           // And final derivatives
+     145       19092 :           for(unsigned j=0; j<dimension; ++j) der[j] *= von_misses_concentration*newval;
+     146             :         }
+     147    11848693 :         accumulate( ineigh, weight, newval, der, buffer );
+     148    11848693 :         if( wasForced() ) {
+     149        5744 :           accumulateForce( ineigh, weight, der, intforce );
+     150        5744 :           totwforce += myvals.get( 1+dimension )*newval*forces[ineigh];
+     151             :         }
+     152             :       }
+     153       21447 :       if( wasForced() ) {
+     154             :         // Minus sign for kernel here as we are taking derivative with respect to position of center of
+     155             :         // kernel NOT derivative wrt to grid point
+     156         110 :         double pref = 1; if( kernel ) pref = -1;
+     157         110 :         unsigned nder = getAction()->getNumberOfDerivatives();
+     158         110 :         unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
+     159         300 :         for(unsigned j=0; j<dimension; ++j) {
+     160       33940 :           for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
+     161             :             unsigned kder=myvals.getActiveIndex(k);
+     162       33750 :             buffer[ bufstart + gridbuf + kder ] += pref*intforce[j]*myvals.getDerivative( j+1, kder );
+     163             :           }
+     164             :         }
+     165             :         // Accumulate the sum of all the weights
+     166         110 :         buffer[ bufstart + gridbuf + nder ] += myvals.get(0);
+     167             :         // Add the derivatives of the weights into the force -- this is separate loop as weights of all parts are considered together
+     168       32060 :         for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
+     169             :           unsigned kder=myvals.getActiveIndex(k);
+     170       31950 :           buffer[ bufstart + gridbuf + kder ] += totwforce*myvals.getDerivative( 0, kder );
+     171       31950 :           buffer[ bufstart + gridbuf + nder + 1 + kder ] += myvals.getDerivative( 0, kder );
+     172             :         }
+     173             :       }
+     174       21447 :     }
+     175       23553 :   }
+     176       38461 : }
+     177             : 
+     178       40596 : void HistogramOnGrid::accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const {
+     179       40596 :   buffer[bufstart+nper*ipoint] += weight*dens;
+     180      168672 :   if( der.size()>0 ) for(unsigned j=0; j<dimension; ++j) buffer[bufstart+nper*ipoint + 1 + j] += weight*der[j];
+     181       40596 : }
+     182             : 
+     183        5744 : void HistogramOnGrid::accumulateForce( const unsigned& ipoint, const double& weight, const std::vector<double>& der, std::vector<double>& intforce ) const {
+     184       18414 :   for(unsigned j=0; j<der.size(); ++j) intforce[j] += forces[ipoint]*weight*der[j];
+     185        5744 : }
+     186             : 
+     187          20 : void HistogramOnGrid::getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) {
+     188          20 :   if( finalForces.size()!=getAction()->getNumberOfDerivatives() ) finalForces.resize( getAction()->getNumberOfDerivatives() );
+     189             :   // And the final force
+     190          20 :   unsigned nder = getAction()->getNumberOfDerivatives();
+     191             :   // Derivatives due to normalization
+     192          20 :   unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
+     193        3815 :   for(unsigned i=0; i<finalForces.size(); ++i) finalForces[i] = buffer[ bufstart + gridbuf + i ];
+     194             :   // Derivatives due to normalization
+     195          20 :   if( !noAverage() ) {
+     196          15 :     unsigned wderstart = bufstart + gridbuf + nder; double pref=0;
+     197        3620 :     for(unsigned ipoint=0; ipoint<getNumberOfPoints(); ++ipoint) {
+     198        3605 :       pref += forces[ipoint]*buffer[ bufstart + ipoint*nper ] / buffer[wderstart];
+     199             :     }
+     200        3570 :     for(unsigned j=0; j<finalForces.size(); ++j) finalForces[j] -= pref*buffer[ wderstart + 1 + j ];
+     201             :   }
+     202          20 : }
+     203             : 
+     204         156 : void HistogramOnGrid::finish( const std::vector<double>& buffer ) {
+     205         156 :   if( addOneKernelAtATime ) {
+     206       14975 :     for(unsigned i=0; i<getAction()->getCurrentNumberOfActiveTasks(); ++i) {
+     207       69400 :       for(unsigned j=0; j<nper; ++j) addDataElement( nper*getAction()->getActiveTask(i)+j, buffer[bufstart+i*nper+j] );
+     208             :     }
+     209             :   } else {
+     210          89 :     GridVessel::finish( buffer );
+     211             :   }
+     212         156 : }
+     213             : 
+     214             : }
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html b/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html new file mode 100644 index 0000000000..21ec26a17e --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.func.html b/coverage/gridtools/HistogramOnGrid.h.func.html new file mode 100644 index 0000000000..85c3655bfa --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.gcov.html b/coverage/gridtools/HistogramOnGrid.h.gcov.html new file mode 100644 index 0000000000..a87bbc6dd4 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.gcov.html @@ -0,0 +1,147 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html b/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..f073f79b76 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe446createERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44D2Ev4168
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.func.html b/coverage/gridtools/IntegrateGrid.cpp.func.html new file mode 100644 index 0000000000..21c280b6c9 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe446createERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_125IntegrateGridRegisterMe44D2Ev4168
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.gcov.html b/coverage/gridtools/IntegrateGrid.cpp.gcov.html new file mode 100644 index 0000000000..5ea1302bc9 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(IntegrateGrid,"INTEGRATE_GRID")
+      45             : 
+      46           6 : void IntegrateGrid::registerKeywords( Keywords& keys ) {
+      47           6 :   ActionWithIntegral::registerKeywords( keys );
+      48           6 : }
+      49             : 
+      50           4 : IntegrateGrid::IntegrateGrid(const ActionOptions&ao):
+      51             :   Action(ao),
+      52           4 :   ActionWithIntegral(ao)
+      53             : {
+      54           4 : }
+      55             : 
+      56        5705 : void IntegrateGrid::compute( const unsigned& current, MultiValue& myvals ) const {
+      57        5705 :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, getVolume()*getFunctionValue( current ) );
+      58        5705 :   if( !doNotCalculateDerivatives() ) myvals.addDerivative( 1, current, getVolume() );
+      59        5705 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..ecd8f080f9 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func.html b/coverage/gridtools/InterpolateGrid.cpp.func.html new file mode 100644 index 0000000000..26c6b6ffd3 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe626createERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62C2Ev4168
_ZN4PLMD9gridtools12_GLOBAL__N_127InterpolateGridRegisterMe62D2Ev4168
_ZN4PLMD9gridtools15InterpolateGrid10isPeriodicEv0
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.gcov.html b/coverage/gridtools/InterpolateGrid.cpp.gcov.html new file mode 100644 index 0000000000..502d0e71ea --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(InterpolateGrid,"INTERPOLATE_GRID")
+      63             : 
+      64           4 : void InterpolateGrid::registerKeywords( Keywords& keys ) {
+      65           4 :   ActionWithInputGrid::registerKeywords( keys );
+      66           8 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+      67           8 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      68           8 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      69           4 : }
+      70             : 
+      71           2 : InterpolateGrid::InterpolateGrid(const ActionOptions&ao):
+      72             :   Action(ao),
+      73           2 :   ActionWithInputGrid(ao)
+      74             : {
+      75           2 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      76           2 :   if( ingrid->noDerivatives() ) error("cannot interpolate a grid that does not have derivatives");
+      77             :   // Create the input from the old string
+      78           4 :   auto grid=createGrid( "grid", "COMPONENTS=" + getLabel() + " " + ingrid->getInputString()  );
+      79             :   // notice that createGrid also sets mygrid=grid.get()
+      80             : 
+      81           4 :   std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+      82           4 :   std::vector<double> gspacing; parseVector("GRID_SPACING",gspacing);
+      83           2 :   if( nbin.size()!=ingrid->getDimension() && gspacing.size()!=ingrid->getDimension() ) {
+      84           0 :     error("GRID_BIN or GRID_SPACING must be set");
+      85             :   }
+      86             : 
+      87             :   // Need this for creation of tasks
+      88           2 :   grid->setBounds( ingrid->getMin(), ingrid->getMax(), nbin, gspacing );
+      89           2 :   setAveragingAction( std::move(grid), true );
+      90             : 
+      91             :   // Now create task list
+      92         202 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+      93             :   // And activate all tasks
+      94           2 :   deactivateAllTasks();
+      95         202 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+      96           2 :   lockContributors();
+      97           2 : }
+      98             : 
+      99           8 : unsigned InterpolateGrid::getNumberOfQuantities() const {
+     100           8 :   return 2 + ingrid->getDimension();
+     101             : }
+     102             : 
+     103         200 : void InterpolateGrid::compute( const unsigned& current, MultiValue& myvals ) const {
+     104         200 :   std::vector<double> pos( mygrid->getDimension() ); mygrid->getGridPointCoordinates( current, pos );
+     105         200 :   std::vector<double> der( mygrid->getDimension() ); double val = getFunctionValueAndDerivatives( pos, der );
+     106             :   myvals.setValue( 0, 1.0 ); myvals.setValue(1, val );
+     107         400 :   for(unsigned i=0; i<mygrid->getDimension(); ++i) myvals.setValue( 2+i, der[i] );
+     108         200 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-f.html b/coverage/gridtools/index-sort-f.html new file mode 100644 index 0000000000..6495ea011c --- /dev/null +++ b/coverage/gridtools/index-sort-f.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1183126493.6 %
Date:2024-05-27 13:05: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
ActionWithIntegral.cpp +
100.0%
+
100.0 %22 / 2280.0 %4 / 5
GridPrintingBase.cpp +
100.0%
+
100.0 %53 / 5380.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
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
DumpGrid.cpp +
100.0%
+
100.0 %34 / 3485.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
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.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 %118 / 120100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-l.html b/coverage/gridtools/index-sort-l.html new file mode 100644 index 0000000000..f5c086fd5b --- /dev/null +++ b/coverage/gridtools/index-sort-l.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1183126493.6 %
Date:2024-05-27 13:05: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 %118 / 120100.0 %12 / 12
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
HistogramOnGrid.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
ActionWithInputGrid.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
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.16
+
+ + + diff --git a/coverage/gridtools/index.html b/coverage/gridtools/index.html new file mode 100644 index 0000000000..5e01a29fe1 --- /dev/null +++ b/coverage/gridtools/index.html @@ -0,0 +1,343 @@ + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1183126493.6 %
Date:2024-05-27 13:05: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 %118 / 120100.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.16
+
+ + + diff --git a/coverage/index-sort-f.html b/coverage/index-sort-f.html new file mode 100644 index 0000000000..78ac08ddd2 --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,473 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:498925850485.3 %
Date:2024-05-27 13:05:14Functions:5554696679.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
46.4%46.4%
+
46.4 %64 / 13846.0 %23 / 50
wrapper +
52.7%52.7%
+
52.7 %247 / 46957.1 %144 / 252
manyrestraints +
81.5%81.5%
+
81.5 %75 / 9269.2 %18 / 26
ves +
82.1%82.1%
+
82.1 %5938 / 723070.4 %555 / 788
dimred +
84.8%84.8%
+
84.8 %556 / 65673.1 %79 / 108
piv +
71.8%71.8%
+
71.8 %428 / 59675.0 %6 / 8
crystallization +
83.8%83.8%
+
83.8 %1015 / 121177.0 %144 / 187
analysis +
88.5%88.5%
+
88.5 %859 / 97177.2 %156 / 202
multicolvar +
78.6%78.6%
+
78.6 %2377 / 302578.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.9%94.9%
+
94.9 %1210 / 127579.7 %177 / 222
core +
85.9%85.9%
+
85.9 %3237 / 376780.6 %431 / 535
tools +
83.5%83.5%
+
83.5 %5628 / 673881.4 %1406 / 1728
isdb +
81.6%81.6%
+
81.6 %8645 / 1059581.5 %198 / 243
s2cm +
91.6%91.6%
+
91.6 %152 / 16681.8 %9 / 11
adjmat +
88.6%88.6%
+
88.6 %1038 / 117182.1 %183 / 223
colvar +
94.0%94.0%
+
94.0 %2098 / 223282.5 %184 / 223
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
function +
85.9%85.9%
+
85.9 %909 / 105884.0 %84 / 100
sasa +
82.0%82.0%
+
82.0 %998 / 121784.4 %27 / 32
maze +
85.3%85.3%
+
85.3 %661 / 77584.3 %86 / 102
gridtools +
93.6%93.6%
+
93.6 %1183 / 126485.5 %171 / 200
bias +
91.4%91.4%
+
91.4 %2393 / 261785.6 %143 / 167
membranefusion +
88.2%88.2%
+
88.2 %456 / 51785.7 %18 / 21
funnel +
98.0%98.0%
+
98.0 %248 / 25386.7 %13 / 15
eds +
92.6%92.6%
+
92.6 %452 / 48887.0 %20 / 23
pytorch +
83.1%83.1%
+
83.1 %54 / 6587.5 %7 / 8
vatom +
99.1%99.1%
+
99.1 %221 / 22387.5 %21 / 24
annfunc +
97.1%97.1%
+
97.1 %134 / 13888.9 %8 / 9
mapping +
93.7%93.7%
+
93.7 %758 / 80989.0 %89 / 100
vesselbase +
92.9%92.9%
+
92.9 %1141 / 122889.5 %231 / 258
cltools +
80.0%80.0%
+
80.0 %1359 / 169992.0 %103 / 112
logmfd +
87.6%87.6%
+
87.6 %326 / 37293.8 %15 / 16
opes +
96.1%96.1%
+
96.1 %2161 / 224993.8 %135 / 144
drr +
94.3%94.3%
+
94.3 %1194 / 126694.8 %92 / 97
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 0000000000..d1c1eda7dd --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,473 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:498925850485.3 %
Date:2024-05-27 13:05:14Functions:5554696679.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
46.4%46.4%
+
46.4 %64 / 13846.0 %23 / 50
wrapper +
52.7%52.7%
+
52.7 %247 / 46957.1 %144 / 252
piv +
71.8%71.8%
+
71.8 %428 / 59675.0 %6 / 8
multicolvar +
78.6%78.6%
+
78.6 %2377 / 302578.0 %329 / 422
fisst +
79.6%79.6%
+
79.6 %319 / 40182.8 %24 / 29
cltools +
80.0%80.0%
+
80.0 %1359 / 169992.0 %103 / 112
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
pamm +
81.4%81.4%
+
81.4 %215 / 26479.4 %27 / 34
manyrestraints +
81.5%81.5%
+
81.5 %75 / 9269.2 %18 / 26
isdb +
81.6%81.6%
+
81.6 %8645 / 1059581.5 %198 / 243
sasa +
82.0%82.0%
+
82.0 %998 / 121784.4 %27 / 32
ves +
82.1%82.1%
+
82.1 %5938 / 723070.4 %555 / 788
pytorch +
83.1%83.1%
+
83.1 %54 / 6587.5 %7 / 8
tools +
83.5%83.5%
+
83.5 %5628 / 673881.4 %1406 / 1728
crystallization +
83.8%83.8%
+
83.8 %1015 / 121177.0 %144 / 187
dimred +
84.8%84.8%
+
84.8 %556 / 65673.1 %79 / 108
maze +
85.3%85.3%
+
85.3 %661 / 77584.3 %86 / 102
function +
85.9%85.9%
+
85.9 %909 / 105884.0 %84 / 100
core +
85.9%85.9%
+
85.9 %3237 / 376780.6 %431 / 535
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
logmfd +
87.6%87.6%
+
87.6 %326 / 37293.8 %15 / 16
membranefusion +
88.2%88.2%
+
88.2 %456 / 51785.7 %18 / 21
analysis +
88.5%88.5%
+
88.5 %859 / 97177.2 %156 / 202
adjmat +
88.6%88.6%
+
88.6 %1038 / 117182.1 %183 / 223
bias +
91.4%91.4%
+
91.4 %2393 / 261785.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 %1141 / 122889.5 %231 / 258
gridtools +
93.6%93.6%
+
93.6 %1183 / 126485.5 %171 / 200
mapping +
93.7%93.7%
+
93.7 %758 / 80989.0 %89 / 100
colvar +
94.0%94.0%
+
94.0 %2098 / 223282.5 %184 / 223
drr +
94.3%94.3%
+
94.3 %1194 / 126694.8 %92 / 97
generic +
94.9%94.9%
+
94.9 %1210 / 127579.7 %177 / 222
opes +
96.1%96.1%
+
96.1 %2161 / 224993.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.0%98.0%
+
98.0 %248 / 25386.7 %13 / 15
vatom +
99.1%99.1%
+
99.1 %221 / 22387.5 %21 / 24
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000000..1683eee5c1 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,473 @@ + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:498925850485.3 %
Date:2024-05-27 13:05:14Functions:5554696679.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe1236createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_120CaliberRegisterMe123D2Ev4168
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.gcov.html b/coverage/isdb/Caliber.cpp.gcov.html new file mode 100644 index 0000000000..8bb984c85e --- /dev/null +++ b/coverage/isdb/Caliber.cpp.gcov.html @@ -0,0 +1,423 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(Caliber,"CALIBER")
+     124             : 
+     125           6 : void Caliber::registerKeywords( Keywords& keys ) {
+     126           6 :   Bias::registerKeywords(keys);
+     127           6 :   keys.use("ARG");
+     128          12 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     129          12 :   keys.add("compulsory","FILE","the name of the file containing the time-resolved values");
+     130          12 :   keys.add("compulsory","KAPPA","a force constant, this can be use to scale a constant estimated on-the-fly using AVERAGING");
+     131          12 :   keys.add("optional","AVERAGING", "Stride for calculation of the optimum kappa, if 0 only KAPPA is used.");
+     132          12 :   keys.add("compulsory","TSCALE","1.0","Apply a time scaling on the experimental time scale");
+     133          12 :   keys.add("compulsory","SCALE","1.0","Apply a constant scaling on the data provided as arguments");
+     134          12 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     135          12 :   keys.addOutputComponent("x0","default","the instantaneous value of the center of the potential");
+     136          12 :   keys.addOutputComponent("mean","default","the current average value of the calculated observable");
+     137          12 :   keys.addOutputComponent("kappa","default","the current force constant");
+     138          12 :   keys.addOutputComponent("scale","REGRES_ZERO","the current scaling constant");
+     139           6 : }
+     140             : 
+     141           4 : Caliber::Caliber(const ActionOptions&ao):
+     142             :   PLUMED_BIAS_INIT(ao),
+     143           4 :   mult(0),
+     144           4 :   scale_(1),
+     145           4 :   doregres_zero_(false),
+     146           4 :   nregres_zero_(0),
+     147           4 :   optsigmamean_stride_(0)
+     148             : {
+     149           8 :   parse("KAPPA",mult);
+     150             :   std::string filename;
+     151           8 :   parse("FILE",filename);
+     152           4 :   if( filename.length()==0 ) error("No external variable file was specified");
+     153           4 :   unsigned averaging=0;
+     154           4 :   parse("AVERAGING", averaging);
+     155           4 :   if(averaging>0) optsigmamean_stride_ = averaging;
+     156           4 :   double tscale=1.0;
+     157           4 :   parse("TSCALE", tscale);
+     158           4 :   if(tscale<=0.) error("The time scale factor must be greater than 0.");
+     159           4 :   parse("SCALE", scale_);
+     160           4 :   if(scale_==0.) error("The time scale factor cannot be 0.");
+     161             :   // regression with zero intercept
+     162           4 :   parse("REGRES_ZERO", nregres_zero_);
+     163           4 :   if(nregres_zero_>0) {
+     164             :     // set flag
+     165           0 :     doregres_zero_=true;
+     166           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     167             :   }
+     168             : 
+     169             : 
+     170           4 :   bool noensemble = false;
+     171           4 :   parseFlag("NOENSEMBLE", noensemble);
+     172             : 
+     173           4 :   checkRead();
+     174             : 
+     175             :   // set up replica stuff
+     176           4 :   master = (comm.Get_rank()==0);
+     177           4 :   if(master) {
+     178           4 :     nrep_    = multi_sim_comm.Get_size();
+     179           4 :     replica_ = multi_sim_comm.Get_rank();
+     180           4 :     if(noensemble) nrep_ = 1;
+     181             :   } else {
+     182           0 :     nrep_    = 0;
+     183           0 :     replica_ = 0;
+     184             :   }
+     185           4 :   comm.Sum(&nrep_,1);
+     186           4 :   comm.Sum(&replica_,1);
+     187             : 
+     188             :   const unsigned narg = getNumberOfArguments();
+     189           4 :   sigma_mean2_.resize(narg,1);
+     190           4 :   sigma_mean2_last_.resize(narg);
+     191           8 :   for(unsigned j=0; j<narg; j++) sigma_mean2_last_[j].push_back(0.000001);
+     192             : 
+     193           4 :   log.printf("  Time resolved data from file %s\n",filename.c_str());
+     194           4 :   std::ifstream varfile(filename.c_str());
+     195           4 :   if(varfile.fail()) error("Cannot open "+filename);
+     196           4 :   var.resize(narg);
+     197           4 :   dvar.resize(narg);
+     198        2012 :   while (!varfile.eof()) {
+     199             :     double tempT, tempVar;
+     200             :     varfile >> tempT;
+     201        2008 :     time.push_back(tempT/tscale);
+     202        4016 :     for(unsigned i=0; i<narg; i++) {
+     203             :       varfile >> tempVar;
+     204        2008 :       var[i].push_back(tempVar);
+     205             :     }
+     206             :   }
+     207           4 :   varfile.close();
+     208             : 
+     209           4 :   const double deltat = time[1] - time[0];
+     210           8 :   for(unsigned i=0; i<narg; i++) {
+     211        2012 :     for(unsigned j=0; j<var[i].size(); j++) {
+     212        2008 :       if(j==0) dvar[i].push_back((var[i][j+1] - var[i][j])/(deltat));
+     213        2004 :       else if(j==var[i].size()-1) dvar[i].push_back((var[i][j] - var[i][j-1])/(deltat));
+     214        2000 :       else dvar[i].push_back((var[i][j+1] - var[i][j-1])/(2.*deltat));
+     215             :     }
+     216             :   }
+     217             : 
+     218           8 :   for(unsigned i=0; i<narg; i++) {
+     219           4 :     std::string num; Tools::convert(i,num);
+     220          12 :     addComponent("x0-"+num); componentIsNotPeriodic("x0-"+num); x0comp.push_back(getPntrToComponent("x0-"+num));
+     221          12 :     addComponent("kappa-"+num); componentIsNotPeriodic("kappa-"+num); kcomp.push_back(getPntrToComponent("kappa-"+num));
+     222          12 :     addComponent("mean-"+num); componentIsNotPeriodic("mean-"+num); mcomp.push_back(getPntrToComponent("mean-"+num));
+     223             :   }
+     224             : 
+     225           4 :   if(doregres_zero_) {
+     226           0 :     addComponent("scale");
+     227           0 :     componentIsNotPeriodic("scale");
+     228           0 :     valueScale=getPntrToComponent("scale");
+     229             :   }
+     230             : 
+     231           8 :   log<<"  Bibliography "<<plumed.cite("Capelli, Tiana, Camilloni, J Chem Phys, 148, 184114");
+     232           8 : }
+     233             : 
+     234           0 : void Caliber::get_sigma_mean(const double fact, const std::vector<double> &mean)
+     235             : {
+     236           0 :   const unsigned narg = getNumberOfArguments();
+     237           0 :   const double dnrep = static_cast<double>(nrep_);
+     238             : 
+     239           0 :   if(sigma_mean2_last_[0].size()==optsigmamean_stride_) for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[i].erase(sigma_mean2_last_[i].begin());
+     240           0 :   std::vector<double> sigma_mean2_now(narg,0);
+     241           0 :   if(master) {
+     242           0 :     for(unsigned i=0; i<narg; ++i) {
+     243           0 :       double tmp = getArgument(i)-mean[i];
+     244           0 :       sigma_mean2_now[i] = fact*tmp*tmp;
+     245             :     }
+     246           0 :     if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+     247             :   }
+     248           0 :   comm.Sum(&sigma_mean2_now[0], narg);
+     249             : 
+     250           0 :   for(unsigned i=0; i<narg; ++i) {
+     251           0 :     sigma_mean2_last_[i].push_back(sigma_mean2_now[i]/dnrep);
+     252           0 :     sigma_mean2_[i] = *max_element(sigma_mean2_last_[i].begin(), sigma_mean2_last_[i].end());
+     253             :   }
+     254           0 : }
+     255             : 
+     256        2004 : void Caliber::replica_averaging(const double fact, std::vector<double> &mean)
+     257             : {
+     258        2004 :   const unsigned narg = getNumberOfArguments();
+     259        2004 :   if(master) {
+     260        4008 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     261        2004 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+     262             :   }
+     263        2004 :   comm.Sum(&mean[0], narg);
+     264        2004 : }
+     265             : 
+     266        2004 : double Caliber::getSpline(const unsigned iarg)
+     267             : {
+     268        2004 :   const double deltat = time[1] - time[0];
+     269        2004 :   const int tindex = static_cast<int>(getTime()/deltat);
+     270             : 
+     271             :   unsigned start, end;
+     272        2004 :   start=tindex;
+     273        2004 :   if(tindex+1<var[iarg].size()) end=tindex+2;
+     274           0 :   else end=var[iarg].size();
+     275             : 
+     276             :   double value=0;
+     277        6012 :   for(unsigned ipoint=start; ipoint<end; ++ipoint) {
+     278        4008 :     double grid=var[iarg][ipoint];
+     279        4008 :     double dder=dvar[iarg][ipoint];
+     280             :     double yy=0.;
+     281        4008 :     if(std::abs(grid)>0.0000001) yy=-dder/grid;
+     282             : 
+     283             :     int x0=1;
+     284        4008 :     if(ipoint==tindex) x0=0;
+     285             : 
+     286        4008 :     double X=std::abs((getTime()-time[tindex])/deltat-(double)x0);
+     287        4008 :     double X2=X*X;
+     288        4008 :     double X3=X2*X;
+     289        4008 :     double C=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*deltat;
+     290             : 
+     291        4008 :     value+=grid*C;
+     292             :   }
+     293        2004 :   return value;
+     294             : }
+     295             : 
+     296           0 : void Caliber::do_regression_zero(const std::vector<double> &mean)
+     297             : {
+     298             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+     299             :   double num = 0.0;
+     300             :   double den = 0.0;
+     301           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     302           0 :     num += mean[i] * getSpline(i);
+     303           0 :     den += mean[i] * mean[i];
+     304             :   }
+     305           0 :   if(den>0) {
+     306           0 :     scale_ = num / den;
+     307             :   } else {
+     308           0 :     scale_ = 1.0;
+     309             :   }
+     310           0 : }
+     311             : 
+     312        2004 : void Caliber::calculate()
+     313             : {
+     314        2004 :   const unsigned narg = getNumberOfArguments();
+     315        2004 :   const double dnrep = static_cast<double>(nrep_);
+     316        2004 :   const double fact = 1.0/dnrep;
+     317             : 
+     318        2004 :   std::vector<double> mean(narg,0);
+     319        2004 :   std::vector<double> dmean_x(narg,fact);
+     320        2004 :   replica_averaging(fact, mean);
+     321        2004 :   if(optsigmamean_stride_>0) get_sigma_mean(fact, mean);
+     322             : 
+     323             :   // in case of regression with zero intercept, calculate scale
+     324        2004 :   if(doregres_zero_ && getStep()%nregres_zero_==0) do_regression_zero(mean);
+     325             : 
+     326             :   double ene=0;
+     327        4008 :   for(unsigned i=0; i<narg; ++i) {
+     328        2004 :     const double x0 = getSpline(i);
+     329        2004 :     const double kappa = mult*dnrep/sigma_mean2_[i];
+     330        2004 :     const double cv=difference(i,x0,scale_*mean[i]);
+     331        2004 :     const double f=-kappa*cv*dmean_x[i]/scale_;
+     332             :     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.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func-sort-c.html b/coverage/isdb/EMMI.cpp.func-sort-c.html new file mode 100644 index 0000000000..c1748411e8 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func-sort-c.html @@ -0,0 +1,240 @@ + + + + + + + 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-05-27 13:05:14Functions:324276.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe3846createERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI9get_GMM_dENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384D2Ev4168
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func.html b/coverage/isdb/EMMI.cpp.func.html new file mode 100644 index 0000000000..bb3a76117a --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func.html @@ -0,0 +1,240 @@ + + + + + + + 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-05-27 13:05:14Functions:324276.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe3846createERKNS_13ActionOptionsE20
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117EMMIRegisterMe384D2Ev4168
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI9get_GMM_dENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.gcov.html b/coverage/isdb/EMMI.cpp.gcov.html new file mode 100644 index 0000000000..837d25df32 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.gcov.html @@ -0,0 +1,1826 @@ + + + + + + + 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-05-27 13:05: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 long int step);
+     212             : // get median of std::vector
+     213             :   double get_median(std::vector<double> &v);
+     214             : // annealing
+     215             :   double get_annealing(long 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 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(const std::string & errfile);
+     228             : // read experimental overlaps
+     229             :   std::vector<double> read_exp_overlaps(const 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       12544 : PLUMED_REGISTER_ACTION(EMMI,"EMMI")
+     385             : 
+     386          22 : void EMMI::registerKeywords( Keywords& keys ) {
+     387          22 :   Action::registerKeywords( keys );
+     388          22 :   ActionAtomistic::registerKeywords( keys );
+     389          22 :   ActionWithValue::registerKeywords( keys );
+     390          22 :   ActionWithArguments::registerKeywords( keys );
+     391          22 :   keys.use("ARG");
+     392          44 :   keys.add("atoms","ATOMS","atoms for which we calculate the density map, typically all heavy atoms");
+     393          44 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     394          44 :   keys.add("compulsory","GMM_FILE","file with the parameters of the GMM components");
+     395          44 :   keys.add("compulsory","NL_CUTOFF","The cutoff in overlap for the neighbor list");
+     396          44 :   keys.add("compulsory","NL_STRIDE","The frequency with which we are updating the neighbor list");
+     397          44 :   keys.add("compulsory","SIGMA_MIN","minimum uncertainty");
+     398          44 :   keys.add("compulsory","RESOLUTION", "Cryo-EM map resolution");
+     399          44 :   keys.add("compulsory","NOISETYPE","functional form of the noise (GAUSS, OUTLIERS, MARGINAL)");
+     400          44 :   keys.add("optional","SIGMA0","initial value of the uncertainty");
+     401          44 :   keys.add("optional","DSIGMA","MC step for uncertainties");
+     402          44 :   keys.add("optional","MC_STRIDE", "Monte Carlo stride");
+     403          44 :   keys.add("optional","ERR_FILE","file with experimental or GMM fit errors");
+     404          44 :   keys.add("optional","OV_FILE","file with experimental overlaps");
+     405          44 :   keys.add("optional","NORM_DENSITY","integral of the experimental density");
+     406          44 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart");
+     407          44 :   keys.add("optional","WRITE_STRIDE","write the status to a file every N steps, this can be used for restart");
+     408          44 :   keys.add("optional","REGRESSION","regression stride");
+     409          44 :   keys.add("optional","REG_SCALE_MIN","regression minimum scale");
+     410          44 :   keys.add("optional","REG_SCALE_MAX","regression maximum scale");
+     411          44 :   keys.add("optional","REG_DSCALE","regression maximum scale MC move");
+     412          44 :   keys.add("optional","SCALE","scale factor");
+     413          44 :   keys.add("optional","ANNEAL", "Length of annealing cycle");
+     414          44 :   keys.add("optional","ANNEAL_FACT", "Annealing temperature factor");
+     415          44 :   keys.add("optional","TEMP","temperature");
+     416          44 :   keys.add("optional","PRIOR", "exponent of uncertainty prior");
+     417          44 :   keys.add("optional","WRITE_OV_STRIDE","write model overlaps every N steps");
+     418          44 :   keys.add("optional","WRITE_OV","write a file with model overlaps");
+     419          44 :   keys.add("optional","AVERAGING", "Averaging window for weights");
+     420          44 :   keys.addFlag("NO_AVER",false,"don't do ensemble averaging in multi-replica mode");
+     421          44 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+     422          22 :   componentsAreNotOptional(keys);
+     423          44 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     424          44 :   keys.addOutputComponent("acc",   "NOISETYPE","MC acceptance for uncertainty");
+     425          44 :   keys.addOutputComponent("scale", "REGRESSION","scale factor");
+     426          44 :   keys.addOutputComponent("accscale", "REGRESSION","MC acceptance for scale regression");
+     427          44 :   keys.addOutputComponent("enescale", "REGRESSION","MC energy for scale regression");
+     428          44 :   keys.addOutputComponent("anneal","ANNEAL","annealing factor");
+     429          44 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     430          44 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     431          44 :   keys.addOutputComponent("sigma",      "NOISETYPE",     "uncertainty in the forward models and experiment");
+     432          44 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     433          22 : }
+     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          22 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     756          22 :   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 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 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::log1p( 0.5 * dev * dev * old_inv_s2);
+     907           0 :       new_ene += std::log1p( 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(const 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(const 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 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 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::log1p( 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.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func-sort-c.html b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html new file mode 100644 index 0000000000..eb5cf797ef --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe936createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func.html b/coverage/isdb/FretEfficiency.cpp.func.html new file mode 100644 index 0000000000..9926e5044b --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe936createERKNS_13ActionOptionsE14
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_126FretEfficiencyRegisterMe93D2Ev4168
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.gcov.html b/coverage/isdb/FretEfficiency.cpp.gcov.html new file mode 100644 index 0000000000..ed7dbc3b7f --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + 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-05-27 13:05: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       12532 : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET")
+      94             : 
+      95          16 : void FretEfficiency::registerKeywords( Keywords& keys ) {
+      96          16 :   Colvar::registerKeywords( keys );
+      97          32 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+      98          32 :   keys.add("compulsory","R0","The value of the Forster radius.");
+      99          16 : }
+     100             : 
+     101          14 : FretEfficiency::FretEfficiency(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          14 :   pbc(true)
+     104             : {
+     105             :   std::vector<AtomNumber> atoms;
+     106          28 :   parseAtomList("ATOMS",atoms);
+     107          14 :   if(atoms.size()!=2)
+     108           0 :     error("Number of specified atoms should be 2");
+     109          14 :   parse("R0",R0_);
+     110          14 :   bool nopbc=!pbc;
+     111          14 :   parseFlag("NOPBC",nopbc);
+     112          14 :   pbc=!nopbc;
+     113          14 :   checkRead();
+     114             : 
+     115          14 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     116          14 :   log.printf("  with Forster radius set to %lf\n",R0_);
+     117             : 
+     118          14 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     119           0 :   else    log.printf("  without periodic boundary conditions\n");
+     120             : 
+     121          28 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     122             : 
+     123          14 :   addValueWithDerivatives();
+     124          14 :   setNotPeriodic();
+     125             : 
+     126          14 :   requestAtoms(atoms);
+     127          14 : }
+     128             : 
+     129             : 
+     130             : // calculator
+     131         238 : void FretEfficiency::calculate() {
+     132             : 
+     133         238 :   if(pbc) makeWhole();
+     134             : 
+     135         238 :   Vector distance=delta(getPosition(0),getPosition(1));
+     136         238 :   const double dist_mod=distance.modulo();
+     137         238 :   const double inv_dist_mod=1.0/dist_mod;
+     138             : 
+     139         238 :   const double ratiosix=std::pow(dist_mod/R0_,6);
+     140         238 :   const double fret_eff = 1.0/(1.0+ratiosix);
+     141             : 
+     142         238 :   const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod;
+     143             : 
+     144         238 :   setAtomsDerivatives(0,-inv_dist_mod*der*distance);
+     145         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.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func-sort-c.html b/coverage/isdb/Jcoupling.cpp.func-sort-c.html new file mode 100644 index 0000000000..e7dc2a39b7 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe1066createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func.html b/coverage/isdb/Jcoupling.cpp.func.html new file mode 100644 index 0000000000..6f48170be0 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe1066createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_122JCouplingRegisterMe106D2Ev4168
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.gcov.html b/coverage/isdb/Jcoupling.cpp.gcov.html new file mode 100644 index 0000000000..80ecd7d76c --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.gcov.html @@ -0,0 +1,470 @@ + + + + + + + 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-05-27 13:05: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 3J 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       12516 : PLUMED_REGISTER_ACTION(JCoupling, "JCOUPLING")
+     107             : 
+     108           8 : void JCoupling::registerKeywords(Keywords& keys) {
+     109           8 :   componentsAreNotOptional(keys);
+     110           8 :   MetainferenceBase::registerKeywords(keys);
+     111          16 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     112          16 :   keys.add("numbered", "ATOMS", "the 4 atoms involved in each of the bonds for which you wish to calculate the J-coupling. "
+     113             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one J-coupling will be "
+     114             :            "calculated for each ATOMS keyword you specify.");
+     115          16 :   keys.reset_style("ATOMS", "atoms");
+     116          16 :   keys.add("compulsory", "TYPE", "Type of J-coupling to compute (HAN,HAHN,CCG,NCG,CUSTOM)");
+     117          16 :   keys.add("optional", "A", "Karplus parameter A");
+     118          16 :   keys.add("optional", "B", "Karplus parameter B");
+     119          16 :   keys.add("optional", "C", "Karplus parameter C");
+     120          16 :   keys.add("optional", "SHIFT", "Angle shift in radians");
+     121          16 :   keys.add("numbered", "COUPLING", "Add an experimental value for each coupling");
+     122          16 :   keys.addOutputComponent("j", "default", "the calculated J-coupling");
+     123          16 :   keys.addOutputComponent("exp", "COUPLING", "the experimental J-coupling");
+     124           8 : }
+     125             : 
+     126           6 : JCoupling::JCoupling(const ActionOptions&ao):
+     127             :   PLUMED_METAINF_INIT(ao),
+     128           6 :   pbc(true)
+     129             : {
+     130           6 :   bool nopbc = !pbc;
+     131           6 :   parseFlag("NOPBC", nopbc);
+     132           6 :   pbc =! nopbc;
+     133             : 
+     134             :   // Read in the atoms
+     135             :   std::vector<AtomNumber> t, atoms;
+     136           6 :   for (int i = 1; ; ++i) {
+     137          68 :     parseAtomList("ATOMS", i, t );
+     138          34 :     if (t.empty()) {
+     139             :       break;
+     140             :     }
+     141             : 
+     142          28 :     if (t.size() != 4) {
+     143             :       std::string ss;
+     144           0 :       Tools::convert(i, ss);
+     145           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     146             :     }
+     147             : 
+     148             :     // This makes the distance calculation easier later on (see Torsion implementation)
+     149          28 :     atoms.push_back(t[0]);
+     150          28 :     atoms.push_back(t[1]);
+     151          28 :     atoms.push_back(t[1]);
+     152          28 :     atoms.push_back(t[2]);
+     153          28 :     atoms.push_back(t[2]);
+     154          28 :     atoms.push_back(t[3]);
+     155          28 :     t.resize(0);
+     156          28 :   }
+     157             : 
+     158             :   // We now have 6 atoms per datapoint
+     159           6 :   ncoupl_ = atoms.size()/6;
+     160             : 
+     161             :   // Parse J-Coupling type, this will determine the Karplus parameters
+     162             :   unsigned jtype_ = CUSTOM;
+     163             :   std::string string_type;
+     164          12 :   parse("TYPE", string_type);
+     165           6 :   if(string_type == "HAN") {
+     166             :     jtype_ = HAN;
+     167           5 :   } else if(string_type == "HAHN") {
+     168             :     jtype_ = HAHN;
+     169           2 :   } else if(string_type == "CCG") {
+     170             :     jtype_ = CCG;
+     171           1 :   } else if(string_type == "NCG") {
+     172             :     jtype_ = NCG;
+     173           0 :   } else if(string_type == "CUSTOM") {
+     174             :     jtype_ = CUSTOM;
+     175             :   } else {
+     176           0 :     error("Unknown J-coupling type!");
+     177             :   }
+     178             : 
+     179             :   // Optionally add an experimental value (like with RDCs)
+     180             :   std::vector<double> coupl;
+     181           6 :   coupl.resize( ncoupl_ );
+     182             :   unsigned ntarget=0;
+     183          13 :   for(unsigned i=0; i<ncoupl_; ++i) {
+     184          24 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     185           7 :     ntarget++;
+     186             :   }
+     187             :   bool addcoupling=false;
+     188           6 :   if(ntarget!=ncoupl_ && ntarget!=0) error("found wrong number of COUPLING values");
+     189           6 :   if(ntarget==ncoupl_) addcoupling=true;
+     190           6 :   if(getDoScore()&&!addcoupling) error("with DOSCORE you need to set the COUPLING values");
+     191             : 
+     192             :   // For custom types we allow use of custom Karplus parameters
+     193           6 :   if (jtype_ == CUSTOM) {
+     194           0 :     parse("A", ka_);
+     195           0 :     parse("B", kb_);
+     196           0 :     parse("C", kc_);
+     197           0 :     parse("SHIFT", kshift_);
+     198             :   }
+     199             : 
+     200           6 :   log << "  Bibliography ";
+     201          12 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     202             : 
+     203             :   // Set Karplus parameters
+     204           6 :   switch (jtype_) {
+     205           1 :   case HAN:
+     206           1 :     ka_ = -0.88;
+     207           1 :     kb_ = -0.61;
+     208           1 :     kc_ = -0.27;
+     209           1 :     kshift_ = pi / 3.0;
+     210           2 :     log << plumed.cite("Wang A C, Bax A, J. Am. Chem. Soc. 117, 1810 (1995)");
+     211           1 :     log<<"\n";
+     212           1 :     log.printf("  J-coupling type is HAN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     213             :     break;
+     214           3 :   case HAHN:
+     215           3 :     ka_ = 7.09;
+     216           3 :     kb_ = -1.42;
+     217           3 :     kc_ = 1.55;
+     218           3 :     kshift_ = -pi / 3.0;
+     219           6 :     log << plumed.cite("Hu J-S, Bax A, J. Am. Chem. Soc. 119, 6360 (1997)");
+     220           3 :     log<<"\n";
+     221           3 :     log.printf("  J-coupling type is HAHN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     222             :     break;
+     223           1 :   case CCG:
+     224           1 :     ka_ = 2.31;
+     225           1 :     kb_ = -0.87;
+     226           1 :     kc_ = 0.55;
+     227           1 :     kshift_ = (2.0 * pi) / 3.0;
+     228           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     229           1 :     log<<"\n";
+     230           1 :     log.printf("  J-coupling type is CCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     231             :     break;
+     232           1 :   case NCG:
+     233           1 :     ka_ = 1.29;
+     234           1 :     kb_ = -0.49;
+     235           1 :     kc_ = 0.37;
+     236           1 :     kshift_ = 0.0;
+     237           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     238           1 :     log<<"\n";
+     239           1 :     log.printf("  J-coupling type is NCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     240             :     break;
+     241           0 :   case CUSTOM:
+     242           0 :     log<<"\n";
+     243           0 :     log.printf("  J-coupling type is custom, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     244             :     break;
+     245             :   }
+     246             : 
+     247          34 :   for (unsigned i = 0; i < ncoupl_; ++i) {
+     248          28 :     log.printf("  The %uth J-Coupling is calculated from atoms : %d %d %d %d.",
+     249          28 :                i+1, atoms[6*i].serial(), atoms[6*i+1].serial(), atoms[6*i+3].serial(), atoms[6*i+5].serial());
+     250          28 :     if (addcoupling) {
+     251           7 :       log.printf(" Experimental J-Coupling is %f.", coupl[i]);
+     252             :     }
+     253          28 :     log.printf("\n");
+     254             :   }
+     255             : 
+     256           6 :   if (pbc) {
+     257           0 :     log.printf("  using periodic boundary conditions\n");
+     258             :   } else {
+     259           6 :     log.printf("  without periodic boundary conditions\n");
+     260             :   }
+     261             : 
+     262           6 :   if(!getDoScore()) {
+     263          26 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     264          21 :       std::string num; Tools::convert(i, num);
+     265          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.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func-sort-c.html b/coverage/isdb/Metainference.cpp.func-sort-c.html new file mode 100644 index 0000000000..91b0ca1b66 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func-sort-c.html @@ -0,0 +1,192 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE21
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func.html b/coverage/isdb/Metainference.cpp.func.html new file mode 100644 index 0000000000..74ca957d2b --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func.html @@ -0,0 +1,192 @@ + + + + + + + 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-05-27 13:05:14Functions:273090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe2856createERKNS_13ActionOptionsE19
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_126MetainferenceRegisterMe285D2Ev4168
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13MetainferenceD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.gcov.html b/coverage/isdb/Metainference.cpp.gcov.html new file mode 100644 index 0000000000..3fd52ddc46 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.gcov.html @@ -0,0 +1,1881 @@ + + + + + + + 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-05-27 13:05: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 long unsigned MCaccept_;
+     206             :   long long unsigned MCacceptScale_;
+     207             :   long long unsigned MCacceptFT_;
+     208             :   long long unsigned MCtrial_;
+     209             :   unsigned MCchunksize_;
+     210             : 
+     211             :   // output
+     212             :   Value*   valueScale;
+     213             :   Value*   valueOffset;
+     214             :   Value*   valueAccept;
+     215             :   Value*   valueAcceptScale;
+     216             :   Value*   valueAcceptFT;
+     217             :   std::vector<Value*> valueSigma;
+     218             :   std::vector<Value*> valueSigmaMean;
+     219             :   std::vector<Value*> valueFtilde;
+     220             : 
+     221             :   // restart
+     222             :   unsigned write_stride_;
+     223             :   OFile    sfile_;
+     224             : 
+     225             :   // others
+     226             :   bool         firstTime;
+     227             :   std::vector<bool> firstTimeW;
+     228             :   bool     master;
+     229             :   bool     do_reweight_;
+     230             :   unsigned do_optsigmamean_;
+     231             :   unsigned nrep_;
+     232             :   unsigned replica_;
+     233             :   unsigned narg;
+     234             : 
+     235             :   // selector
+     236             :   std::string selector_;
+     237             : 
+     238             :   // optimize sigma mean
+     239             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
+     240             :   unsigned optsigmamean_stride_;
+     241             :   // optimize sigma max
+     242             :   unsigned N_optimized_step_;
+     243             :   unsigned optimized_step_;
+     244             :   bool sigmamax_opt_done_;
+     245             :   std::vector<double> sigma_max_est_;
+     246             : 
+     247             :   // average weights
+     248             :   unsigned                   average_weights_stride_;
+     249             :   std::vector< std::vector <double> >  average_weights_;
+     250             : 
+     251             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     252             :                         const double scale, const double offset);
+     253             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     254             :                      const double scale, const double offset);
+     255             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     256             :                       const double scale, const double offset);
+     257             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     258             :                      const double scale, const double offset);
+     259             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     260             :                       const double scale, const double offset);
+     261             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
+     262             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
+     263             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
+     264             :   double doMonteCarlo(const std::vector<double> &mean);
+     265             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     266             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     267             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     268             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     269             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     270             :   void get_weights(const unsigned iselect, double &weight, double &norm, double &neff);
+     271             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
+     272             :   void get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean);
+     273             :   void writeStatus();
+     274             :   void do_regression_zero(const std::vector<double> &mean);
+     275             : 
+     276             : public:
+     277             :   explicit Metainference(const ActionOptions&);
+     278             :   ~Metainference();
+     279             :   void calculate() override;
+     280             :   void update() override;
+     281             :   static void registerKeywords(Keywords& keys);
+     282             : };
+     283             : 
+     284             : 
+     285       12542 : PLUMED_REGISTER_ACTION(Metainference,"METAINFERENCE")
+     286             : 
+     287          21 : void Metainference::registerKeywords(Keywords& keys) {
+     288          21 :   Bias::registerKeywords(keys);
+     289          21 :   keys.use("ARG");
+     290          42 :   keys.add("optional","PARARG","reference values for the experimental data, these can be provided as arguments without derivatives");
+     291          42 :   keys.add("optional","PARAMETERS","reference values for the experimental data");
+     292          42 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     293          42 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+     294          42 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+     295          42 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+     296          42 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+     297          42 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+     298          42 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+     299          42 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+     300          42 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     301          42 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+     302          42 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+     303          42 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+     304          42 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+     305          42 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+     306          42 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     307          42 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+     308          42 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+     309          42 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+     310          42 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     311          42 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+     312          42 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+     313          42 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+     314          42 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+     315          42 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+     316          42 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+     317          42 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+     318          42 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+     319          42 :   keys.add("optional","MC_STEPS","number of MC steps");
+     320          42 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+     321          42 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+     322          42 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+     323          42 :   keys.add("optional","SELECTOR","name of selector");
+     324          42 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+     325          21 :   keys.use("RESTART");
+     326          42 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+     327          42 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+     328          42 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     329          42 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+     330          42 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+     331          42 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+     332          42 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     333          42 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     334          42 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+     335          42 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+     336          42 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+     337          21 : }
+     338             : 
+     339          19 : Metainference::Metainference(const ActionOptions&ao):
+     340             :   PLUMED_BIAS_INIT(ao),
+     341          19 :   doscale_(false),
+     342          19 :   scale_(1.),
+     343          19 :   scale_mu_(0),
+     344          19 :   scale_min_(1),
+     345          19 :   scale_max_(-1),
+     346          19 :   Dscale_(-1),
+     347          19 :   dooffset_(false),
+     348          19 :   offset_(0.),
+     349          19 :   offset_mu_(0),
+     350          19 :   offset_min_(1),
+     351          19 :   offset_max_(-1),
+     352          19 :   Doffset_(-1),
+     353          19 :   doregres_zero_(false),
+     354          19 :   nregres_zero_(0),
+     355          19 :   Dftilde_(0.1),
+     356          19 :   random(3),
+     357          19 :   MCsteps_(1),
+     358          19 :   MCaccept_(0),
+     359          19 :   MCacceptScale_(0),
+     360          19 :   MCacceptFT_(0),
+     361          19 :   MCtrial_(0),
+     362          19 :   MCchunksize_(0),
+     363          19 :   write_stride_(0),
+     364          19 :   firstTime(true),
+     365          19 :   do_reweight_(false),
+     366          19 :   do_optsigmamean_(0),
+     367          19 :   optsigmamean_stride_(0),
+     368          19 :   N_optimized_step_(0),
+     369          19 :   optimized_step_(0),
+     370          19 :   sigmamax_opt_done_(false),
+     371          19 :   average_weights_stride_(1)
+     372             : {
+     373          19 :   bool noensemble = false;
+     374          19 :   parseFlag("NOENSEMBLE", noensemble);
+     375             : 
+     376             :   // set up replica stuff
+     377          19 :   master = (comm.Get_rank()==0);
+     378          19 :   if(master) {
+     379          11 :     nrep_    = multi_sim_comm.Get_size();
+     380          11 :     replica_ = multi_sim_comm.Get_rank();
+     381          11 :     if(noensemble) nrep_ = 1;
+     382             :   } else {
+     383           8 :     nrep_    = 0;
+     384           8 :     replica_ = 0;
+     385             :   }
+     386          19 :   comm.Sum(&nrep_,1);
+     387          19 :   comm.Sum(&replica_,1);
+     388             : 
+     389          19 :   unsigned nsel = 1;
+     390          19 :   parse("SELECTOR", selector_);
+     391          38 :   parse("NSELECT", nsel);
+     392             :   // do checks
+     393          19 :   if(selector_.length()>0 && nsel<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     394          19 :   if(selector_.length()==0 && nsel>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     395             : 
+     396             :   // initialise firstTimeW
+     397          19 :   firstTimeW.resize(nsel, true);
+     398             : 
+     399             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     400          19 :   parseFlag("REWEIGHT", do_reweight_);
+     401          19 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     402          34 :   if(!getRestart()) average_weights_.resize(nsel, std::vector<double> (nrep_, 1./static_cast<double>(nrep_)));
+     403           8 :   else average_weights_.resize(nsel, std::vector<double> (nrep_, 0.));
+     404          19 :   narg = getNumberOfArguments();
+     405          19 :   if(do_reweight_) narg--;
+     406             : 
+     407          19 :   unsigned averaging=0;
+     408          19 :   parse("AVERAGING", averaging);
+     409          19 :   if(averaging>0) {
+     410           0 :     average_weights_stride_ = averaging;
+     411           0 :     optsigmamean_stride_    = averaging;
+     412             :   }
+     413             : 
+     414          38 :   parseVector("PARAMETERS",parameters);
+     415          19 :   if(parameters.size()!=static_cast<unsigned>(narg)&&!parameters.empty())
+     416           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+     417             : 
+     418             :   std::vector<Value*> arg2;
+     419          38 :   parseArgumentList("PARARG",arg2);
+     420          19 :   if(!arg2.empty()) {
+     421           4 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     422           4 :     if(arg2.size()!=narg) error("Size of PARARG array should be the same as number for arguments in ARG");
+     423        2360 :     for(unsigned i=0; i<arg2.size(); i++) {
+     424        2356 :       parameters.push_back(arg2[i]->get());
+     425        2356 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     426             :     }
+     427             :   }
+     428             : 
+     429          19 :   if(parameters.size()!=narg)
+     430           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     431             : 
+     432             :   std::string stringa_noise;
+     433          38 :   parse("NOISETYPE",stringa_noise);
+     434          19 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     435          18 :   else if(stringa_noise=="MGAUSS")     noise_type_ = MGAUSS;
+     436          10 :   else if(stringa_noise=="OUTLIERS")   noise_type_ = OUTLIERS;
+     437           5 :   else if(stringa_noise=="MOUTLIERS")  noise_type_ = MOUTLIERS;
+     438           1 :   else if(stringa_noise=="GENERIC")    noise_type_ = GENERIC;
+     439           0 :   else error("Unknown noise type!");
+     440             : 
+     441          19 :   if(noise_type_== GENERIC) {
+     442             :     std::string stringa_like;
+     443           2 :     parse("LIKELIHOOD",stringa_like);
+     444           1 :     if(stringa_like=="GAUSS") gen_likelihood_ = LIKE_GAUSS;
+     445           0 :     else if(stringa_like=="LOGN") gen_likelihood_ = LIKE_LOGN;
+     446           0 :     else error("Unknown likelihood type!");
+     447             : 
+     448           2 :     parse("DFTILDE",Dftilde_);
+     449             :   }
+     450             : 
+     451          38 :   parse("WRITE_STRIDE",write_stride_);
+     452             :   std::string status_file_name_;
+     453          38 :   parse("STATUS_FILE",status_file_name_);
+     454          38 :   if(status_file_name_=="") status_file_name_ = "MISTATUS"+getLabel();
+     455           0 :   else                      status_file_name_ = status_file_name_+getLabel();
+     456             : 
+     457             :   std::string stringa_optsigma;
+     458          38 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     459          19 :   if(stringa_optsigma=="NONE")      do_optsigmamean_=0;
+     460           0 :   else if(stringa_optsigma=="SEM")  do_optsigmamean_=1;
+     461           0 :   else if(stringa_optsigma=="SEM_MAX")  do_optsigmamean_=2;
+     462             : 
+     463          19 :   unsigned aver_max_steps=0;
+     464          19 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     465          19 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     466          19 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     467          19 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     468          19 :   if(aver_max_steps>0&&aver_max_steps<averaging) error("SIGMA_MAX_STEPS must be greater than AVERAGING");
+     469             : 
+     470             :   // resize std::vector for sigma_mean history
+     471          19 :   sigma_mean2_last_.resize(nsel);
+     472          38 :   for(unsigned i=0; i<nsel; i++) sigma_mean2_last_[i].resize(narg);
+     473             : 
+     474             :   std::vector<double> read_sigma_mean_;
+     475          19 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     476          19 :   if(do_optsigmamean_==0 && read_sigma_mean_.size()==0 && !getRestart())
+     477           0 :     error("If you don't use OPTSIGMAMEAN and you are not RESTARTING then you MUST SET SIGMA_MEAN0");
+     478             : 
+     479          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     480          13 :     if(read_sigma_mean_.size()==narg) {
+     481           0 :       sigma_mean2_.resize(narg);
+     482           0 :       for(unsigned i=0; i<narg; i++) sigma_mean2_[i]=read_sigma_mean_[i]*read_sigma_mean_[i];
+     483          13 :     } else if(read_sigma_mean_.size()==1) {
+     484          13 :       sigma_mean2_.resize(narg,read_sigma_mean_[0]*read_sigma_mean_[0]);
+     485           0 :     } else if(read_sigma_mean_.size()==0) {
+     486           0 :       sigma_mean2_.resize(narg,0.000001);
+     487             :     } else {
+     488           0 :       error("SIGMA_MEAN0 can accept either one single value or as many values as the arguments (with NOISETYPE=MGAUSS|MOUTLIERS)");
+     489             :     }
+     490             :     // set the initial value for the history
+     491        2416 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[j]);
+     492             :   } else {
+     493           6 :     if(read_sigma_mean_.size()==1) {
+     494           6 :       sigma_mean2_.resize(1, read_sigma_mean_[0]*read_sigma_mean_[0]);
+     495           0 :     } else if(read_sigma_mean_.size()==0) {
+     496           0 :       sigma_mean2_.resize(1, 0.000001);
+     497             :     } else {
+     498           0 :       error("If you want to use more than one SIGMA_MEAN0 you should use NOISETYPE=MGAUSS|MOUTLIERS");
+     499             :     }
+     500             :     // set the initial value for the history
+     501          37 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[0]);
+     502             :   }
+     503             : 
+     504          19 :   parseFlag("SCALEDATA", doscale_);
+     505          19 :   if(doscale_) {
+     506             :     std::string stringa_noise;
+     507          24 :     parse("SCALE_PRIOR",stringa_noise);
+     508          12 :     if(stringa_noise=="GAUSSIAN")  scale_prior_ = SC_GAUSS;
+     509          12 :     else if(stringa_noise=="FLAT") scale_prior_ = SC_FLAT;
+     510           0 :     else error("Unknown SCALE_PRIOR type!");
+     511          12 :     parse("SCALE0",scale_);
+     512          12 :     parse("DSCALE",Dscale_);
+     513          12 :     if(Dscale_<0.) error("DSCALE must be set when using SCALEDATA");
+     514          12 :     if(scale_prior_==SC_GAUSS) {
+     515           0 :       scale_mu_=scale_;
+     516             :     } else {
+     517          12 :       parse("SCALE_MIN",scale_min_);
+     518          12 :       parse("SCALE_MAX",scale_max_);
+     519          12 :       if(scale_max_<scale_min_) error("SCALE_MAX and SCALE_MIN must be set when using SCALE_PRIOR=FLAT");
+     520             :     }
+     521             :   }
+     522             : 
+     523          19 :   parseFlag("ADDOFFSET", dooffset_);
+     524          19 :   if(dooffset_) {
+     525             :     std::string stringa_noise;
+     526           4 :     parse("OFFSET_PRIOR",stringa_noise);
+     527           2 :     if(stringa_noise=="GAUSSIAN")  offset_prior_ = SC_GAUSS;
+     528           2 :     else if(stringa_noise=="FLAT") offset_prior_ = SC_FLAT;
+     529           0 :     else error("Unknown OFFSET_PRIOR type!");
+     530           2 :     parse("OFFSET0",offset_);
+     531           2 :     parse("DOFFSET",Doffset_);
+     532           2 :     if(offset_prior_==SC_GAUSS) {
+     533           0 :       offset_mu_=offset_;
+     534           0 :       if(Doffset_<0.) error("DOFFSET must be set when using OFFSET_PRIOR=GAUSS");
+     535             :     } else {
+     536           2 :       parse("OFFSET_MIN",offset_min_);
+     537           2 :       parse("OFFSET_MAX",offset_max_);
+     538           2 :       if(Doffset_<0) Doffset_ = 0.05*(offset_max_ - offset_min_);
+     539           2 :       if(offset_max_<offset_min_) error("OFFSET_MAX and OFFSET_MIN must be set when using OFFSET_PRIOR=FLAT");
+     540             :     }
+     541             :   }
+     542             : 
+     543             :   // regression with zero intercept
+     544          19 :   parse("REGRES_ZERO", nregres_zero_);
+     545          19 :   if(nregres_zero_>0) {
+     546             :     // set flag
+     547           0 :     doregres_zero_=true;
+     548             :     // check if already sampling scale and offset
+     549           0 :     if(doscale_)  error("REGRES_ZERO and SCALEDATA are mutually exclusive");
+     550           0 :     if(dooffset_) error("REGRES_ZERO and ADDOFFSET are mutually exclusive");
+     551             :   }
+     552             : 
+     553             :   std::vector<double> readsigma;
+     554          19 :   parseVector("SIGMA0",readsigma);
+     555          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma.size()>1)
+     556           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     557          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     558          13 :     sigma_.resize(readsigma.size());
+     559          13 :     sigma_=readsigma;
+     560           6 :   } else sigma_.resize(1, readsigma[0]);
+     561             : 
+     562             :   std::vector<double> readsigma_min;
+     563          19 :   parseVector("SIGMA_MIN",readsigma_min);
+     564          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_min.size()>1)
+     565           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     566          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     567          13 :     sigma_min_.resize(readsigma_min.size());
+     568          13 :     sigma_min_=readsigma_min;
+     569           6 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     570             : 
+     571             :   std::vector<double> readsigma_max;
+     572          19 :   parseVector("SIGMA_MAX",readsigma_max);
+     573          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     574           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     575          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     576          13 :     sigma_max_.resize(readsigma_max.size());
+     577          13 :     sigma_max_=readsigma_max;
+     578           6 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     579             : 
+     580          19 :   if(sigma_max_.size()!=sigma_min_.size()) error("The number of values for SIGMA_MIN and SIGMA_MAX must be the same");
+     581             : 
+     582             :   std::vector<double> read_dsigma;
+     583          19 :   parseVector("DSIGMA",read_dsigma);
+     584          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     585           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     586          19 :   if(read_dsigma.size()>0) {
+     587          19 :     Dsigma_.resize(read_dsigma.size());
+     588          19 :     Dsigma_=read_dsigma;
+     589             :   } else {
+     590           0 :     Dsigma_.resize(sigma_max_.size(), -1.);
+     591             :     /* in this case Dsigma is initialised after reading the restart file if present */
+     592             :   }
+     593             : 
+     594             :   // monte carlo stuff
+     595          19 :   parse("MC_STEPS",MCsteps_);
+     596          19 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     597             :   // get temperature
+     598          19 :   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          35 :   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 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        7170 :         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          50 :         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.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..60e43eaa96 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv96
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE96
_ZN4PLMD4isdb17MetainferenceBaseD2Ev96
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE112
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func.html b/coverage/isdb/MetainferenceBase.cpp.func.html new file mode 100644 index 0000000000..4445dd5e53 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv96
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE112
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE96
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBaseD2Ev96
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.gcov.html b/coverage/isdb/MetainferenceBase.cpp.gcov.html new file mode 100644 index 0000000000..4edae1deb2 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.gcov.html @@ -0,0 +1,1639 @@ + + + + + + + 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-05-27 13:05: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         112 : void MetainferenceBase::registerKeywords( Keywords& keys ) {
+      35         112 :   Action::registerKeywords(keys);
+      36         112 :   ActionAtomistic::registerKeywords(keys);
+      37         112 :   ActionWithValue::registerKeywords(keys);
+      38         112 :   ActionWithArguments::registerKeywords(keys);
+      39         112 :   componentsAreNotOptional(keys);
+      40         112 :   keys.use("ARG");
+      41         224 :   keys.addFlag("DOSCORE",false,"activate metainference");
+      42         224 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+      43         224 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+      44         224 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+      45         224 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+      46         224 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+      47         224 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+      48         224 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+      49         224 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+      50         224 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      51         224 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+      52         224 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+      53         224 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+      54         224 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+      55         224 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+      56         224 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      57         224 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+      58         224 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+      59         224 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+      60         224 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+      61         224 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+      62         224 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+      63         224 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+      64         224 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+      65         224 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+      66         224 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+      67         224 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+      68         224 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+      69         224 :   keys.add("optional","MC_STEPS","number of MC steps");
+      70         224 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+      71         224 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+      72         224 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+      73         224 :   keys.add("optional","SELECTOR","name of selector");
+      74         224 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+      75         112 :   keys.use("RESTART");
+      76         224 :   keys.addOutputComponent("score",        "default",      "the Metainference score");
+      77         224 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+      78         224 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+      79         224 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+      80         224 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+      81         224 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+      82         224 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+      83         224 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+      84         224 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+      85         224 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+      86         224 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+      87         224 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+      88         112 : }
+      89             : 
+      90          96 : MetainferenceBase::MetainferenceBase(const ActionOptions&ao):
+      91             :   Action(ao),
+      92             :   ActionAtomistic(ao),
+      93             :   ActionWithArguments(ao),
+      94             :   ActionWithValue(ao),
+      95          96 :   doscore_(false),
+      96          96 :   write_stride_(0),
+      97          96 :   narg(0),
+      98          96 :   doscale_(false),
+      99          96 :   scale_(1.),
+     100          96 :   scale_mu_(0),
+     101          96 :   scale_min_(1),
+     102          96 :   scale_max_(-1),
+     103          96 :   Dscale_(-1),
+     104          96 :   dooffset_(false),
+     105          96 :   offset_(0.),
+     106          96 :   offset_mu_(0),
+     107          96 :   offset_min_(1),
+     108          96 :   offset_max_(-1),
+     109          96 :   Doffset_(-1),
+     110          96 :   doregres_zero_(false),
+     111          96 :   nregres_zero_(0),
+     112          96 :   Dftilde_(0.1),
+     113          96 :   random(3),
+     114          96 :   MCsteps_(1),
+     115          96 :   MCaccept_(0),
+     116          96 :   MCacceptScale_(0),
+     117          96 :   MCacceptFT_(0),
+     118          96 :   MCtrial_(0),
+     119          96 :   MCchunksize_(0),
+     120          96 :   firstTime(true),
+     121          96 :   do_reweight_(false),
+     122          96 :   do_optsigmamean_(0),
+     123          96 :   nsel_(1),
+     124          96 :   iselect(0),
+     125          96 :   optsigmamean_stride_(0),
+     126          96 :   N_optimized_step_(0),
+     127          96 :   optimized_step_(0),
+     128          96 :   sigmamax_opt_done_(false),
+     129          96 :   decay_w_(1.)
+     130             : {
+     131          96 :   parseFlag("DOSCORE", doscore_);
+     132             : 
+     133          96 :   bool noensemble = false;
+     134          96 :   parseFlag("NOENSEMBLE", noensemble);
+     135             : 
+     136             :   // set up replica stuff
+     137          96 :   master = (comm.Get_rank()==0);
+     138          96 :   if(master) {
+     139          61 :     nrep_    = multi_sim_comm.Get_size();
+     140          61 :     replica_ = multi_sim_comm.Get_rank();
+     141          61 :     if(noensemble) nrep_ = 1;
+     142             :   } else {
+     143          35 :     nrep_    = 0;
+     144          35 :     replica_ = 0;
+     145             :   }
+     146          96 :   comm.Sum(&nrep_,1);
+     147          96 :   comm.Sum(&replica_,1);
+     148             : 
+     149          96 :   parse("SELECTOR", selector_);
+     150         192 :   parse("NSELECT", nsel_);
+     151             :   // do checks
+     152          96 :   if(selector_.length()>0 && nsel_<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     153          96 :   if(selector_.length()==0 && nsel_>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     154             : 
+     155             :   // initialise firstTimeW
+     156          96 :   firstTimeW.resize(nsel_, true);
+     157             : 
+     158             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     159          96 :   parseFlag("REWEIGHT", do_reweight_);
+     160          96 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     161          96 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     162         191 :   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          96 :   unsigned averaging=0;
+     166          96 :   parse("AVERAGING", averaging);
+     167          96 :   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         192 :   parse("NOISETYPE",stringa_noise);
+     174          96 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     175          89 :   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          96 :   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          96 :   parse("WRITE_STRIDE",write_stride_);
+     192         192 :   parse("STATUS_FILE",status_file_name_);
+     193         192 :   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         192 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     198          96 :   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          96 :   unsigned aver_max_steps=0;
+     203          96 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     204          96 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     205          96 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     206          96 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     207          96 :   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          96 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     211          96 :   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          96 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     215          88 :     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          65 :       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          96 :   parseFlag("SCALEDATA", doscale_);
+     232          96 :   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          96 :   parseFlag("ADDOFFSET", dooffset_);
+     251          96 :   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          96 :   parse("REGRES_ZERO", nregres_zero_);
+     272          96 :   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          96 :   parseVector("SIGMA0",readsigma);
+     282          96 :   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          96 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     285          88 :     sigma_.resize(readsigma.size());
+     286          88 :     sigma_=readsigma;
+     287           8 :   } else sigma_.resize(1, readsigma[0]);
+     288             : 
+     289             :   std::vector<double> readsigma_min;
+     290          96 :   parseVector("SIGMA_MIN",readsigma_min);
+     291          96 :   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          96 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     294          88 :     sigma_min_.resize(readsigma_min.size());
+     295          88 :     sigma_min_=readsigma_min;
+     296           8 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     297             : 
+     298             :   std::vector<double> readsigma_max;
+     299          96 :   parseVector("SIGMA_MAX",readsigma_max);
+     300          96 :   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          96 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     303          88 :     sigma_max_.resize(readsigma_max.size());
+     304          88 :     sigma_max_=readsigma_max;
+     305           8 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     306             : 
+     307          96 :   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          96 :   parseVector("DSIGMA",read_dsigma);
+     311          96 :   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          96 :   if(read_dsigma.size()>0) {
+     314          31 :     Dsigma_.resize(read_dsigma.size());
+     315          31 :     Dsigma_=read_dsigma;
+     316             :   } else {
+     317          65 :     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          96 :   parse("MC_STEPS",MCsteps_);
+     323          96 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     324             :   // get temperature
+     325          96 :   double temp=0.0;
+     326          96 :   parse("TEMP",temp);
+     327          96 :   if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp;
+     328          65 :   else kbt_=plumed.getAtoms().getKbT();
+     329          96 :   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          96 :   if(master) {
+     334          61 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     335          61 :     iseed = static_cast<unsigned>(ts)+replica_;
+     336             :   } else {
+     337          35 :     iseed = 0;
+     338             :   }
+     339          96 :   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          96 :   random[0].setSeed(-iseed);
+     343          96 :   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          96 :   if(master) {
+     354          61 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     355          61 :     iseed = static_cast<unsigned>(ts)+replica_;
+     356             :   } else {
+     357          35 :     iseed = 0;
+     358             :   }
+     359          96 :   comm.Sum(&iseed, 1);
+     360          96 :   random[2].setSeed(-iseed);
+     361             : 
+     362             :   // outfile stuff
+     363          96 :   if(write_stride_>0&&doscore_) {
+     364          31 :     sfile_.link(*this);
+     365          31 :     sfile_.open(status_file_name_);
+     366             :   }
+     367             : 
+     368          96 : }
+     369             : 
+     370          96 : MetainferenceBase::~MetainferenceBase()
+     371             : {
+     372          96 :   if(sfile_.isOpen()) sfile_.close();
+     373         480 : }
+     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          53 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     679          35 :   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          96 : void MetainferenceBase::writeStatus()
+    1505             : {
+    1506          96 :   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        7410 :         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          54 :         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.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func-sort-c.html b/coverage/isdb/MetainferenceBase.h.func-sort-c.html new file mode 100644 index 0000000000..942a18f8a0 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv96
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv701
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv701
_ZN4PLMD4isdb17MetainferenceBase5applyEv701
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11848
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2375432
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480147
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099241332
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func.html b/coverage/isdb/MetainferenceBase.h.func.html new file mode 100644 index 0000000000..91fed794b8 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv701
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv96
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv701
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11848
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480147
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2375432
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099241332
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase5applyEv701
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.gcov.html b/coverage/isdb/MetainferenceBase.h.gcov.html new file mode 100644 index 0000000000..9bb2d09aab --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.gcov.html @@ -0,0 +1,461 @@ + + + + + + + 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-05-27 13:05: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 long unsigned MCaccept_;
+     107             :   long long unsigned MCacceptScale_;
+     108             :   long long unsigned MCacceptFT_;
+     109             :   long 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       22234 :   return doscore_;
+     220             : }
+     221             : 
+     222             : inline
+     223             : unsigned MetainferenceBase::getWstride()
+     224             : {
+     225        1402 :   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          96 : void MetainferenceBase::setDerivatives() {
+     281             :   // Get appropriate number of derivatives
+     282             :   // Derivatives are first for arguments and then for atoms
+     283             :   unsigned nder;
+     284          96 :   if( getNumberOfAtoms()>0 ) {
+     285          96 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     286             :   } else {
+     287           0 :     nder = getNumberOfArguments();
+     288             :   }
+     289             : 
+     290             :   // Resize all derivative arrays
+     291          96 :   forces.resize( nder ); forcesToApply.resize( nder );
+     292       21216 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     293          96 : }
+     294             : 
+     295             : inline
+     296     3480147 : void MetainferenceBase::turnOnDerivatives() {
+     297     3480147 :   ActionWithValue::turnOnDerivatives();
+     298     3480147 : }
+     299             : 
+     300             : inline
+     301  4099241332 : unsigned MetainferenceBase::getNumberOfDerivatives() {
+     302  4099241332 :   if( getNumberOfAtoms()>0 ) {
+     303  4099241332 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     304             :   }
+     305           0 :   return getNumberOfArguments();
+     306             : }
+     307             : 
+     308             : inline
+     309         701 : void MetainferenceBase::lockRequests() {
+     310             :   ActionAtomistic::lockRequests();
+     311             :   ActionWithArguments::lockRequests();
+     312         701 : }
+     313             : 
+     314             : inline
+     315         701 : void MetainferenceBase::unlockRequests() {
+     316             :   ActionAtomistic::unlockRequests();
+     317             :   ActionWithArguments::unlockRequests();
+     318         701 : }
+     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         701 : void MetainferenceBase::apply() {
+     339         701 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     340       32738 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     341       32037 :     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         701 :   if( wasforced ) {
+     347         350 :     addForcesOnArguments( forcesToApply );
+     348         350 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     349             :   }
+     350         701 : }
+     351             : 
+     352             : inline
+     353             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
+     354         160 :   v->addDerivative(0,d);
+     355             : }
+     356             : 
+     357             : inline
+     358     2375432 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     359     2375432 :   const unsigned noa=getNumberOfArguments();
+     360     2375432 :   v->addDerivative(noa+3*i+0,d[0]);
+     361     2375432 :   v->addDerivative(noa+3*i+1,d[1]);
+     362     2375432 :   v->addDerivative(noa+3*i+2,d[2]);
+     363     2375432 : }
+     364             : 
+     365             : inline
+     366       11848 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
+     367       11848 :   const unsigned noa=getNumberOfArguments();
+     368             :   const unsigned nat=getNumberOfAtoms();
+     369       11848 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     370       11848 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     371       11848 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     372       11848 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     373       11848 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     374       11848 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     375       11848 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     376       11848 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     377       11848 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     378       11848 : }
+     379             : 
+     380             : 
+     381             : }
+     382             : }
+     383             : 
+     384             : #endif
+     385             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func-sort-c.html b/coverage/isdb/NOE.cpp.func-sort-c.html new file mode 100644 index 0000000000..c07acac7e7 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe826createERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func.html b/coverage/isdb/NOE.cpp.func.html new file mode 100644 index 0000000000..4890060c28 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe826createERKNS_13ActionOptionsE11
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_115NOERegisterMe82D2Ev4168
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.gcov.html b/coverage/isdb/NOE.cpp.gcov.html new file mode 100644 index 0000000000..e5569d4d90 --- /dev/null +++ b/coverage/isdb/NOE.cpp.gcov.html @@ -0,0 +1,350 @@ + + + + + + + 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-05-27 13:05: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       12526 : PLUMED_REGISTER_ACTION(NOE,"NOE")
+      83             : 
+      84          13 : void NOE::registerKeywords( Keywords& keys ) {
+      85          13 :   componentsAreNotOptional(keys);
+      86          13 :   MetainferenceBase::registerKeywords(keys);
+      87          26 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      88          26 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+      89             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+      90             :            "calculated for each ATOM keyword you specify.");
+      91          26 :   keys.add("numbered","GROUPB","the atoms involved in each of the contacts you wish to calculate. "
+      92             :            "Keywords like GROUPB1, GROUPB2, GROUPB3,... should be listed and one contact will be "
+      93             :            "calculated for each ATOM keyword you specify.");
+      94          26 :   keys.reset_style("GROUPA","atoms");
+      95          26 :   keys.reset_style("GROUPB","atoms");
+      96          26 :   keys.add("numbered","NOEDIST","Add an experimental value for each NOE.");
+      97          26 :   keys.addOutputComponent("noe","default","the # NOE");
+      98          26 :   keys.addOutputComponent("exp","NOEDIST","the # NOE experimental distance");
+      99          13 : }
+     100             : 
+     101          11 : NOE::NOE(const ActionOptions&ao):
+     102             :   PLUMED_METAINF_INIT(ao),
+     103          11 :   pbc(true)
+     104             : {
+     105          11 :   bool nopbc=!pbc;
+     106          11 :   parseFlag("NOPBC",nopbc);
+     107          11 :   pbc=!nopbc;
+     108             : 
+     109             :   // Read in the atoms
+     110             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     111          22 :   for(int i=1;; ++i ) {
+     112          66 :     parseAtomList("GROUPA", i, t );
+     113          33 :     if( t.empty() ) break;
+     114          55 :     for(unsigned j=0; j<t.size(); j++) ga_lista.push_back(t[j]);
+     115          22 :     nga.push_back(t.size());
+     116          22 :     t.resize(0);
+     117          22 :   }
+     118             :   std::vector<unsigned> ngb;
+     119          22 :   for(int i=1;; ++i ) {
+     120          66 :     parseAtomList("GROUPB", i, t );
+     121          33 :     if( t.empty() ) break;
+     122          55 :     for(unsigned j=0; j<t.size(); j++) gb_lista.push_back(t[j]);
+     123          22 :     ngb.push_back(t.size());
+     124          22 :     if(ngb[i-1]!=nga[i-1]) error("The same number of atoms is expected for the same GROUPA-GROUPB couple");
+     125          22 :     t.resize(0);
+     126          22 :   }
+     127          11 :   if(nga.size()!=ngb.size()) error("There should be the same number of GROUPA and GROUPB keywords");
+     128             :   // Create neighbour lists
+     129          22 :   nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,false,true,pbc,getPbc(),comm);
+     130             : 
+     131             :   // Optionally add an experimental value (like with RDCs)
+     132             :   std::vector<double> noedist;
+     133          11 :   noedist.resize( nga.size() );
+     134             :   unsigned ntarget=0;
+     135          29 :   for(unsigned i=0; i<nga.size(); ++i) {
+     136          40 :     if( !parseNumbered( "NOEDIST", i+1, noedist[i] ) ) break;
+     137          18 :     ntarget++;
+     138             :   }
+     139             :   bool addexp=false;
+     140          11 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of NOEDIST values");
+     141          11 :   if(ntarget==nga.size()) addexp=true;
+     142          11 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the NOEDIST values");
+     143             : 
+     144             :   // Output details of all contacts
+     145             :   unsigned index=0;
+     146          33 :   for(unsigned i=0; i<nga.size(); ++i) {
+     147          22 :     log.printf("  The %uth NOE is calculated using %u equivalent couples of atoms\n", i, nga[i]);
+     148          55 :     for(unsigned j=0; j<nga[i]; j++) {
+     149          33 :       log.printf("    couple %u is %d %d.\n", j, ga_lista[index].serial(), gb_lista[index].serial() );
+     150          33 :       index++;
+     151             :     }
+     152             :   }
+     153          11 :   tot_size = index;
+     154             : 
+     155          11 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     156           0 :   else         log.printf("  without periodic boundary conditions\n");
+     157             : 
+     158          22 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     159             : 
+     160          11 :   if(!getDoScore()) {
+     161          21 :     for(unsigned i=0; i<nga.size(); i++) {
+     162          14 :       std::string num; Tools::convert(i,num);
+     163          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.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func-sort-c.html b/coverage/isdb/PRE.cpp.func-sort-c.html new file mode 100644 index 0000000000..788cea1611 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe896createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func.html b/coverage/isdb/PRE.cpp.func.html new file mode 100644 index 0000000000..237afa9f66 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe896createERKNS_13ActionOptionsE4
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_115PRERegisterMe89D2Ev4168
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.gcov.html b/coverage/isdb/PRE.cpp.gcov.html new file mode 100644 index 0000000000..b131d9ebc0 --- /dev/null +++ b/coverage/isdb/PRE.cpp.gcov.html @@ -0,0 +1,416 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(PRE,"PRE")
+      90             : 
+      91           6 : void PRE::registerKeywords( Keywords& keys ) {
+      92           6 :   componentsAreNotOptional(keys);
+      93           6 :   MetainferenceBase::registerKeywords(keys);
+      94          12 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      95          12 :   keys.addFlag("NORATIO",false,"Set to TRUE if you want to compute PRE without Intensity Ratio");
+      96          12 :   keys.add("compulsory","INEPT","is the INEPT time (in ms).");
+      97          12 :   keys.add("compulsory","TAUC","is the correlation time (in ns) for this electron-nuclear interaction.");
+      98          12 :   keys.add("compulsory","OMEGA","is the Larmor frequency of the nuclear spin (in MHz).");
+      99          12 :   keys.add("atoms","SPINLABEL","The atom to be used as the paramagnetic center.");
+     100          12 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+     101             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+     102             :            "calculated for each ATOM keyword you specify.");
+     103          12 :   keys.reset_style("GROUPA","atoms");
+     104          12 :   keys.add("numbered","RTWO","The relaxation of the atom/atoms in the corresponding GROUPA of atoms. "
+     105             :            "Keywords like RTWO1, RTWO2, RTWO3,... should be listed.");
+     106          12 :   keys.add("numbered","PREINT","Add an experimental value for each PRE.");
+     107          12 :   keys.addOutputComponent("pre","default","the # PRE");
+     108          12 :   keys.addOutputComponent("exp","PREINT","the # PRE experimental intensity");
+     109           6 : }
+     110             : 
+     111           4 : PRE::PRE(const ActionOptions&ao):
+     112             :   PLUMED_METAINF_INIT(ao),
+     113           4 :   pbc(true),
+     114           4 :   doratio(true)
+     115             : {
+     116           4 :   bool nopbc=!pbc;
+     117           4 :   parseFlag("NOPBC",nopbc);
+     118           4 :   pbc=!nopbc;
+     119             : 
+     120           4 :   bool noratio=!doratio;
+     121           4 :   parseFlag("NORATIO",noratio);
+     122           4 :   doratio=!noratio;
+     123             : 
+     124             :   std::vector<AtomNumber> atom;
+     125           8 :   parseAtomList("SPINLABEL",atom);
+     126           4 :   if(atom.size()!=1) error("Number of specified atom should be 1");
+     127             : 
+     128             :   // Read in the atoms
+     129             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     130          12 :   for(int i=1;; ++i ) {
+     131          32 :     parseAtomList("GROUPA", i, t );
+     132          16 :     if( t.empty() ) break;
+     133          28 :     for(unsigned j=0; j<t.size(); j++) {ga_lista.push_back(t[j]); gb_lista.push_back(atom[0]);}
+     134          12 :     nga.push_back(t.size());
+     135          12 :     t.resize(0);
+     136          12 :   }
+     137             : 
+     138             :   // Read in reference values
+     139           4 :   rtwo.resize( nga.size() );
+     140           4 :   if(doratio) {
+     141             :     unsigned ntarget=0;
+     142           4 :     for(unsigned i=0; i<nga.size(); ++i) {
+     143           8 :       if( !parseNumbered( "RTWO", i+1, rtwo[i] ) ) break;
+     144           0 :       ntarget++;
+     145             :     }
+     146           4 :     if( ntarget==0 ) {
+     147           4 :       parse("RTWO",rtwo[0]);
+     148          12 :       for(unsigned i=1; i<nga.size(); ++i) rtwo[i]=rtwo[0];
+     149           0 :     } else if( ntarget!=nga.size() ) error("found wrong number of RTWO values");
+     150             :   }
+     151             : 
+     152           4 :   double tauc=0.;
+     153           4 :   parse("TAUC",tauc);
+     154           4 :   if(tauc==0.) error("TAUC must be set");
+     155             : 
+     156           4 :   double omega=0.;
+     157           4 :   parse("OMEGA",omega);
+     158           4 :   if(omega==0.) error("OMEGA must be set");
+     159             : 
+     160           4 :   inept=0.;
+     161           4 :   if(doratio) {
+     162           4 :     parse("INEPT",inept);
+     163           4 :     if(inept==0.) error("INEPT must be set");
+     164           4 :     inept *= 0.001; // ms2s
+     165             :   }
+     166             : 
+     167             :   const double ns2s   = 0.000000001;
+     168             :   const double MHz2Hz = 1000000.;
+     169             :   const double Kappa  = 12300000000.00; // this is 1/15*S*(S+1)*gamma^2*g^2*beta^2
+     170             :   // where gamma is the nuclear gyromagnetic ratio,
+     171             :   // g is the electronic g factor, and beta is the Bohr magneton
+     172             :   // in nm^6/s^2
+     173           4 :   constant = (4.*tauc*ns2s+(3.*tauc*ns2s)/(1+omega*omega*MHz2Hz*MHz2Hz*tauc*tauc*ns2s*ns2s))*Kappa;
+     174             : 
+     175             :   // Optionally add an experimental value (like with RDCs)
+     176             :   std::vector<double> exppre;
+     177           4 :   exppre.resize( nga.size() );
+     178             :   unsigned ntarget=0;
+     179          10 :   for(unsigned i=0; i<nga.size(); ++i) {
+     180          16 :     if( !parseNumbered( "PREINT", i+1, exppre[i] ) ) break;
+     181           6 :     ntarget++;
+     182             :   }
+     183             :   bool addexp=false;
+     184           4 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of PREINT values");
+     185           4 :   if(ntarget==nga.size()) addexp=true;
+     186           4 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the PREINT values");
+     187             : 
+     188             :   // Create neighbour lists
+     189           8 :   nl=Tools::make_unique<NeighborList>(gb_lista,ga_lista,false,true,pbc,getPbc(),comm);
+     190             : 
+     191             :   // Output details of all contacts
+     192             :   unsigned index=0;
+     193          16 :   for(unsigned i=0; i<nga.size(); ++i) {
+     194          12 :     log.printf("  The %uth PRE is calculated using %u equivalent atoms:\n", i, nga[i]);
+     195          12 :     log.printf("    %d", ga_lista[index].serial());
+     196          12 :     index++;
+     197          16 :     for(unsigned j=1; j<nga[i]; j++) {
+     198           4 :       log.printf(" %d", ga_lista[index].serial());
+     199           4 :       index++;
+     200             :     }
+     201          12 :     log.printf("\n");
+     202             :   }
+     203           4 :   tot_size = index;
+     204             : 
+     205           4 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     206           0 :   else         log.printf("  without periodic boundary conditions\n");
+     207             : 
+     208           8 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     209             : 
+     210           4 :   if(!getDoScore()) {
+     211           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     212           6 :       std::string num; Tools::convert(i,num);
+     213           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.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func-sort-c.html b/coverage/isdb/RDC.cpp.func-sort-c.html new file mode 100644 index 0000000000..bedea752ca --- /dev/null +++ b/coverage/isdb/RDC.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE33
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220D2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func.html b/coverage/isdb/RDC.cpp.func.html new file mode 100644 index 0000000000..8ccc4fba7b --- /dev/null +++ b/coverage/isdb/RDC.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2206createERKNS_13ActionOptionsE29
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe220D2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe2216createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_116RDCRegisterMe221D2Ev4168
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.gcov.html b/coverage/isdb/RDC.cpp.gcov.html new file mode 100644 index 0000000000..1756d8f851 --- /dev/null +++ b/coverage/isdb/RDC.cpp.gcov.html @@ -0,0 +1,597 @@ + + + + + + + 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-05-27 13:05: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       12562 : PLUMED_REGISTER_ACTION(RDC,"RDC")
+     221       12504 : PLUMED_REGISTER_ACTION(RDC,"PCS")
+     222             : 
+     223          33 : void RDC::registerKeywords( Keywords& keys ) {
+     224          33 :   componentsAreNotOptional(keys);
+     225          33 :   MetainferenceBase::registerKeywords(keys);
+     226          66 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     227          66 :   keys.add("numbered","ATOMS","the couple of atoms involved in each of the bonds for which you wish to calculate the RDC. "
+     228             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dipolar coupling will be "
+     229             :            "calculated for each ATOMS keyword you specify.");
+     230          66 :   keys.reset_style("ATOMS","atoms");
+     231          66 :   keys.add("compulsory","GYROM","1.","Add the product of the gyromagnetic constants for the bond. ");
+     232          66 :   keys.add("compulsory","SCALE","1.","Add the scaling factor to take into account concentration and other effects. ");
+     233          66 :   keys.addFlag("SVD",false,"Set to TRUE if you want to back calculate using Single Value Decomposition (need GSL at compilation time).");
+     234          66 :   keys.add("numbered","COUPLING","Add an experimental value for each coupling (needed by SVD and useful for \\ref STATS).");
+     235          66 :   keys.addOutputComponent("rdc","default","the calculated # RDC");
+     236          66 :   keys.addOutputComponent("exp","SVD/COUPLING","the experimental # RDC");
+     237          66 :   keys.addOutputComponent("Sxx","SVD","Tensor component");
+     238          66 :   keys.addOutputComponent("Syy","SVD","Tensor component");
+     239          66 :   keys.addOutputComponent("Szz","SVD","Tensor component");
+     240          66 :   keys.addOutputComponent("Sxy","SVD","Tensor component");
+     241          66 :   keys.addOutputComponent("Sxz","SVD","Tensor component");
+     242          66 :   keys.addOutputComponent("Syz","SVD","Tensor component");
+     243          33 : }
+     244             : 
+     245          29 : RDC::RDC(const ActionOptions&ao):
+     246             :   PLUMED_METAINF_INIT(ao),
+     247          29 :   Const(1.),
+     248          29 :   mu_s(1.),
+     249          29 :   scale(1.),
+     250          29 :   pbc(true)
+     251             : {
+     252          29 :   bool nopbc=!pbc;
+     253          29 :   parseFlag("NOPBC",nopbc);
+     254          29 :   pbc=!nopbc;
+     255             : 
+     256             :   const double RDCConst = 0.3356806;
+     257             :   const double PCSConst = 1.0;
+     258             : 
+     259          29 :   if( getName().find("RDC")!=std::string::npos) { Const *= RDCConst; }
+     260           0 :   else if( getName().find("PCS")!=std::string::npos) { Const *= PCSConst; }
+     261             : 
+     262             :   // Read in the atoms
+     263             :   std::vector<AtomNumber> t, atoms;
+     264          29 :   for(int i=1;; ++i ) {
+     265         292 :     parseAtomList("ATOMS", i, t );
+     266         146 :     if( t.empty() ) break;
+     267         117 :     if( t.size()!=2 ) {
+     268           0 :       std::string ss; Tools::convert(i,ss);
+     269           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     270             :     }
+     271         117 :     atoms.push_back(t[0]);
+     272         117 :     atoms.push_back(t[1]);
+     273         117 :     t.resize(0);
+     274         117 :   }
+     275             : 
+     276          29 :   const unsigned ndata = atoms.size()/2;
+     277             : 
+     278             :   // Read in GYROMAGNETIC constants
+     279          29 :   parse("GYROM", mu_s);
+     280          29 :   if(mu_s==0.) error("GYROM cannot be 0");
+     281             : 
+     282             :   // Read in SCALING factors
+     283          29 :   parse("SCALE", scale);
+     284          29 :   if(scale==0.) error("SCALE cannot be 0");
+     285             : 
+     286          29 :   svd=false;
+     287          29 :   parseFlag("SVD",svd);
+     288             : #ifndef __PLUMED_HAS_GSL
+     289             :   if(svd) error("You CANNOT use SVD without GSL. Recompile PLUMED with GSL!\n");
+     290             : #endif
+     291          29 :   if(svd&&getDoScore()) error("It is not possible to use SVD and METAINFERENCE together");
+     292             : 
+     293             :   // Optionally add an experimental value
+     294          29 :   coupl.resize( ndata );
+     295             :   unsigned ntarget=0;
+     296          82 :   for(unsigned i=0; i<ndata; ++i) {
+     297         138 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     298          53 :     ntarget++;
+     299             :   }
+     300             :   bool addexp=false;
+     301          29 :   if(ntarget!=ndata && ntarget!=0) error("found wrong number of COUPLING values");
+     302          29 :   if(ntarget==ndata) addexp=true;
+     303          29 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the COUPLING values");
+     304          29 :   if(svd&&!addexp) error("with SVD you need to set the COUPLING values");
+     305             : 
+     306             : 
+     307             :   // Output details of all contacts
+     308          29 :   log.printf("  Gyromagnetic moment is %f. Scaling factor is %f.",mu_s,scale);
+     309         146 :   for(unsigned i=0; i<ndata; ++i) {
+     310         117 :     log.printf("  The %uth Bond Dipolar Coupling is calculated from atoms : %d %d.", i+1, atoms[2*i].serial(), atoms[2*i+1].serial());
+     311         117 :     if(addexp) log.printf(" Experimental coupling is %f.", coupl[i]);
+     312         117 :     log.printf("\n");
+     313             :   }
+     314             : 
+     315          29 :   log<<"  Bibliography "
+     316          58 :      <<plumed.cite("Camilloni C, Vendruscolo M, J. Phys. Chem. B 119, 653 (2015)")
+     317          87 :      <<plumed.cite("Camilloni C, Vendruscolo M, Biochemistry 54, 7470 (2015)");
+     318          58 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     319             : 
+     320             : 
+     321          29 :   if(!getDoScore()&&!svd) {
+     322          80 :     for(unsigned i=0; i<ndata; i++) {
+     323          64 :       std::string num; Tools::convert(i,num);
+     324          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.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func-sort-c.html b/coverage/isdb/Rescale.cpp.func-sort-c.html new file mode 100644 index 0000000000..0dada2403a --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:31520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe1626createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdSt6vectorIdSaIdEES4_0
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func.html b/coverage/isdb/Rescale.cpp.func.html new file mode 100644 index 0000000000..6a0bfc3a84 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:31520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe1626createERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_120RescaleRegisterMe162D2Ev4168
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdSt6vectorIdSaIdEES4_0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.gcov.html b/coverage/isdb/Rescale.cpp.gcov.html new file mode 100644 index 0000000000..3e31f9d180 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.gcov.html @@ -0,0 +1,592 @@ + + + + + + + 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-05-27 13:05: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 long int MCfirst_;
+     139             :   long long unsigned MCaccgamma_;
+     140             :   // replica stuff
+     141             :   unsigned nrep_;
+     142             :   unsigned replica_;
+     143             :   // selector
+     144             :   std::string selector_;
+     145             : 
+     146             :   // Monte Carlo
+     147             :   void doMonteCarlo(unsigned igamma, double oldE, 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 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       12504 : PLUMED_REGISTER_ACTION(Rescale,"RESCALE")
+     163             : 
+     164           2 : void Rescale::registerKeywords(Keywords& keys) {
+     165           2 :   Bias::registerKeywords(keys);
+     166           2 :   keys.use("ARG");
+     167           4 :   keys.add("compulsory","TEMP","temperature");
+     168           4 :   keys.add("compulsory","SELECTOR", "name of the SELECTOR used for rescaling");
+     169           4 :   keys.add("compulsory","MAX_RESCALE","maximum values for rescaling");
+     170           4 :   keys.add("compulsory","NBIN","number of bins for gamma grid");
+     171           4 :   keys.add("compulsory","W0", "initial bias height");
+     172           4 :   keys.add("compulsory","BIASFACTOR", "bias factor");
+     173           4 :   keys.add("compulsory","BSTRIDE", "stride for writing bias");
+     174           4 :   keys.add("compulsory","BFILE", "file name for bias");
+     175           4 :   keys.add("optional","NOT_SHARED",   "list of arguments (from 1 to N) not summed across replicas");
+     176           4 :   keys.add("optional","NOT_RESCALED", "these last N arguments will not be scaled");
+     177           4 :   keys.add("optional","MC_STEPS","number of MC steps");
+     178           4 :   keys.add("optional","MC_STRIDE","MC stride");
+     179           4 :   keys.add("optional","PACE", "Pace for adding bias, in MC stride unit");
+     180           2 :   componentsAreNotOptional(keys);
+     181           4 :   keys.addOutputComponent("igamma",  "default","gamma parameter");
+     182           4 :   keys.addOutputComponent("accgamma","default","MC acceptance for gamma");
+     183           4 :   keys.addOutputComponent("wtbias",  "default","well-tempered bias");
+     184           2 : }
+     185             : 
+     186           0 : Rescale::Rescale(const ActionOptions&ao):
+     187             :   PLUMED_BIAS_INIT(ao),
+     188           0 :   nores_(0), Biaspace_(1), first_bias_(true),
+     189           0 :   MCsteps_(1), MCstride_(1), MCfirst_(-1), MCaccgamma_(0)
+     190             : {
+     191             :   // set up replica stuff
+     192           0 :   if(comm.Get_rank()==0) {
+     193           0 :     nrep_    = multi_sim_comm.Get_size();
+     194           0 :     replica_ = multi_sim_comm.Get_rank();
+     195             :   } else {
+     196           0 :     nrep_    = 0;
+     197           0 :     replica_ = 0;
+     198             :   }
+     199           0 :   comm.Sum(&nrep_,1);
+     200           0 :   comm.Sum(&replica_,1);
+     201             : 
+     202             :   // wt-parameters
+     203           0 :   parse("W0", w0_);
+     204           0 :   parse("BIASFACTOR", biasf_);
+     205             : 
+     206             :   // selector name
+     207           0 :   parse("SELECTOR", selector_);
+     208             : 
+     209             :   // number of bins for gamma ladder
+     210             :   unsigned nbin;
+     211           0 :   parse("NBIN", nbin);
+     212             : 
+     213             :   // number of bias
+     214           0 :   parse("NOT_RESCALED", nores_);
+     215           0 :   if(nores_>0 && nores_!=nbin) error("The number of non scaled arguments must be equal to either 0 or the number of bins");
+     216             : 
+     217             :   // maximum value of rescale
+     218             :   std::vector<double> max_rescale;
+     219           0 :   parseVector("MAX_RESCALE", max_rescale);
+     220             :   // check dimension of max_rescale
+     221           0 :   if(max_rescale.size()!=(getNumberOfArguments()-nores_))
+     222           0 :     error("Size of MAX_RESCALE array must be equal to the number of arguments that will to be scaled");
+     223             : 
+     224             :   // calculate exponents
+     225           0 :   double igamma_max = static_cast<double>(nbin);
+     226           0 :   for(unsigned i=0; i<max_rescale.size(); ++i)
+     227           0 :     expo_.push_back(std::log(max_rescale[i])/std::log(igamma_max));
+     228             : 
+     229             :   // allocate gamma grid and set bias to zero
+     230           0 :   for(unsigned i=0; i<nbin; ++i) {
+     231             :     // bias grid
+     232           0 :     bias_.push_back(0.0);
+     233             :     // gamma ladder
+     234           0 :     double gamma = std::exp( static_cast<double>(i) / static_cast<double>(nbin-1) * std::log(igamma_max) );
+     235           0 :     gamma_.push_back(gamma);
+     236             :   }
+     237             :   // print bias to file
+     238           0 :   parse("BSTRIDE", Biasstride_);
+     239           0 :   parse("BFILE",   Biasfilename_);
+     240             : 
+     241             :   // create vectors of shared arguments
+     242             :   // by default they are all shared
+     243           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) shared_.push_back(1);
+     244             :   // share across replicas or not
+     245             :   std::vector<unsigned> not_shared;
+     246           0 :   parseVector("NOT_SHARED", not_shared);
+     247             :   // and change the non-shared
+     248           0 :   for(unsigned i=0; i<not_shared.size(); ++i) {
+     249           0 :     if((not_shared[i]-1)>=(getNumberOfArguments()-nores_) && nrep_>1)
+     250           0 :       error("NOT_RESCALED args must always be shared when using multiple replicas");
+     251           0 :     if((not_shared[i]-1)>=getNumberOfArguments())
+     252           0 :       error("NOT_SHARED args should be lower than total number of arguments");
+     253           0 :     shared_[not_shared[i]-1] = 0;
+     254             :   }
+     255             : 
+     256             :   // monte carlo stuff
+     257           0 :   parse("MC_STEPS",MCsteps_);
+     258           0 :   parse("MC_STRIDE",MCstride_);
+     259             :   // adjust for multiple-time steps
+     260           0 :   MCstride_ *= getStride();
+     261             :   // read bias deposition pace
+     262           0 :   parse("PACE", Biaspace_);
+     263             :   // multiply by MCstride
+     264           0 :   Biaspace_ *= MCstride_;
+     265             : 
+     266             :   // get temperature
+     267           0 :   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 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 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.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func-sort-c.html b/coverage/isdb/SAXS.cpp.func-sort-c.html new file mode 100644 index 0000000000..c232f499d8 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func-sort-c.html @@ -0,0 +1,168 @@ + + + + + + + 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:4808600580.1 %
Date:2024-05-27 13:05:14Functions:222491.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe3176createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_S5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe3166createERKNS_13ActionOptionsE22
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE28
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_188
_ZN4PLMD4isdb4SAXS6updateEv188
_ZN4PLMD4isdb4SAXS9calculateEv188
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe316C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe316D2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe317C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe317D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func.html b/coverage/isdb/SAXS.cpp.func.html new file mode 100644 index 0000000000..54c59ac87c --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func.html @@ -0,0 +1,168 @@ + + + + + + + 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:4808600580.1 %
Date:2024-05-27 13:05:14Functions:222491.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe3166createERKNS_13ActionOptionsE22
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe316C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe316D2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe3176createERKNS_13ActionOptionsE6
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe317C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_117SAXSRegisterMe317D2Ev4168
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_188
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_S5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb4SAXS6updateEv188
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS9calculateEv188
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE28
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.gcov.html b/coverage/isdb/SAXS.cpp.gcov.html new file mode 100644 index 0000000000..4e3933b599 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.gcov.html @@ -0,0 +1,7532 @@ + + + + + + + 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:4808600580.1 %
Date:2024-05-27 13:05:14Functions:222491.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             :  This class was originally written by Alexander Jussupow
+      24             :  Arrayfire implementation by Alexander Jussupow and CC
+      25             :  Extension for the middleman algorithm (now removed) by Max Muehlbauer
+      26             :  Refactoring for hySAXS Martini form factors for Nucleic Acids by Cristina Paissoni
+      27             :  Refactoring for hySAS OneBead form factors with solvent correction by Federico Ballabio and Riccardo Capelli
+      28             : */
+      29             : 
+      30             : #include "MetainferenceBase.h"
+      31             : #include "core/ActionRegister.h"
+      32             : #include "core/ActionSet.h"
+      33             : #include "core/GenericMolInfo.h"
+      34             : #include "tools/MolDataClass.h"
+      35             : #include "tools/Communicator.h"
+      36             : #include "tools/Pbc.h"
+      37             : #include "tools/PDB.h"
+      38             : 
+      39             : #include <map>
+      40             : #include <iterator>
+      41             : #include <iostream>
+      42             : #include <algorithm>
+      43             : #include <cctype>
+      44             : 
+      45             : #ifdef __PLUMED_HAS_ARRAYFIRE
+      46             : #include <arrayfire.h>
+      47             : #include <af/util.h>
+      48             : #ifdef __PLUMED_HAS_ARRAYFIRE_CUDA
+      49             : #include <cuda_runtime.h>
+      50             : #include <cublas_v2.h>
+      51             : #include <af/cuda.h>
+      52             : #elif __PLUMED_HAS_ARRAYFIRE_OCL
+      53             : #include <af/opencl.h>
+      54             : #endif
+      55             : #endif
+      56             : 
+      57             : #ifndef M_PI
+      58             : #define M_PI           3.14159265358979323846
+      59             : #endif
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace isdb {
+      63             : 
+      64             : //+PLUMEDOC ISDB_COLVAR SAXS
+      65             : /*
+      66             : Calculates SAXS intensity.
+      67             : 
+      68             : SAXS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+      69             : Form factors can be assigned either by polynomial expansion of any order by using the PARAMETERS keywords, or
+      70             : automatically matched to atoms using the ATOMISTIC flag by reading a PDB file. Alternatively to the atomistic
+      71             : representation, two types of coarse-grained mapping are available:
+      72             : - MARTINI.
+      73             : - ONEBEAD.
+      74             : 
+      75             : Whether for PARAMETERS, ATOMISTIC, and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the
+      76             : SAXS instruction. MARTINI requires a mapping scheme consisting of a PDB file that contains both the all-atom
+      77             : and MARTINI representations, and a bead position file (e.g., bead1: CENTER ATOMS=1,5,7,11,12 WEIGHTS=14,12,12,
+      78             : 12,16).
+      79             : 
+      80             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+      81             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+      82             : the SAXS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+      83             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+      84             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+      85             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+      86             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+      87             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+      88             : SOLVATION_STRIDE, which is set to 100 steps by default.
+      89             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+      90             : keyword. This PDB file should only include the atoms for which the SAXS intensity will be computed.
+      91             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+      92             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+      93             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by
+      94             : "5", e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+      95             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by
+      96             : "3", e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+      97             : 
+      98             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+      99             : to the SAXS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     100             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     101             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     102             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     103             : using the SOLVDENS keyword.
+     104             : 
+     105             : By default SAXS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on
+     106             : a GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     107             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     108             : 
+     109             : \par Examples
+     110             : in the following example the SAXS intensities are calculated using single-bead per residue approximation, with a
+     111             : SASA threshold of 1 square nanometer and a solvation term of 0.04. Each experimental intensity is divided by
+     112             : 1.4002, which is the corresponding theoretical intensity value at q = 0. The form factors are selected according
+     113             : to the PDB file specified by TEMPLATE keyword.
+     114             : 
+     115             : \plumedfile
+     116             : MOLINFO STRUCTURE=template_AA.pdb
+     117             : 
+     118             : SAXS ...
+     119             : LABEL=SAXS
+     120             : ATOMS=1-355
+     121             : ONEBEAD
+     122             : TEMPLATE=template_AA.pdb
+     123             : SOLVDENS=0.334
+     124             : SOLVATION_CORRECTION=0.04
+     125             : SOLVATION_STRIDE=1
+     126             : SASA_CUTOFF=1.0
+     127             : SCALE_EXPINT=1.4002
+     128             : QVALUE1=0.03 EXPINT1=1.0902
+     129             : QVALUE2=0.06 EXPINT2=0.790632
+     130             : QVALUE3=0.09 EXPINT3=0.453808
+     131             : QVALUE4=0.12 EXPINT4=0.254737
+     132             : QVALUE5=0.15 EXPINT5=0.154928
+     133             : QVALUE6=0.18 EXPINT6=0.0921503
+     134             : QVALUE7=0.21 EXPINT7=0.052633
+     135             : QVALUE8=0.24 EXPINT8=0.0276557
+     136             : QVALUE9=0.27 EXPINT9=0.0122775
+     137             : QVALUE10=0.30 EXPINT10=0.00880634
+     138             : ... SAXS
+     139             : 
+     140             : PRINT ARG=(SAXS\.q-.*),(SAXS\.exp-.*) FILE=saxsdata STRIDE=1
+     141             : 
+     142             : \endplumedfile
+     143             : 
+     144             : */
+     145             : //+ENDPLUMEDOC
+     146             : 
+     147             : //+PLUMEDOC ISDB_COLVAR SANS
+     148             : /*
+     149             : Calculates SANS intensity.
+     150             : 
+     151             : SANS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+     152             : Form factors are automatically assigned to atoms using the ATOMISTIC flag by reading a PDB file or, alternatively,
+     153             : a ONEBEAD coarse-grained implementation is available.
+     154             : 
+     155             : Both for ATOMISTIC and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the SANS instruction.
+     156             : 
+     157             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+     158             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+     159             : the SANS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+     160             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+     161             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+     162             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+     163             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+     164             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+     165             : SOLVATION_STRIDE, which is set to 100 steps by default. The deuteration of the solvent-exposed residues is chosen
+     166             : with a probability equal to the deuterium concentration in the buffer. The deuterated residues are updated with a
+     167             : stride equal to SOLVATION_STRIDE. The fraction of deuterated water can be set with DEUTER_CONC, the default value
+     168             : is 0.
+     169             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+     170             : keyword. This PDB file should only include the atoms for which the SANS intensity will be computed.
+     171             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+     172             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+     173             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by "5",
+     174             : e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+     175             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by "3",
+     176             : e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     177             : 
+     178             : PLEASE NOTE: at the moment, we DO NOT explicitly take into account deuterated residues in the ATOMISTIC
+     179             : representation, but we correct the solvent contribution via the DEUTER_CONC keyword.
+     180             : 
+     181             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     182             : to the SANS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     183             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     184             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     185             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     186             : using the SOLVDENS keyword.
+     187             : 
+     188             : By default SANS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on a
+     189             : GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     190             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     191             : 
+     192             : \par Examples
+     193             : in the following example the SANS intensities are calculated at atomistic resolution. The form factors are assigned
+     194             : according to the PDB file specified in the MOLINFO. Each experimental intensity is divided by 1.4002, which is the
+     195             : corresponding theoretical intensity value at q = 0. The deuterated water fraction is set to 48%.
+     196             : 
+     197             : \plumedfile
+     198             : MOLINFO STRUCTURE=template_AA.pdb
+     199             : 
+     200             : SANS ...
+     201             : LABEL=SANS
+     202             : ATOMS=1-355
+     203             : ATOMISTIC
+     204             : SCALE_EXPINT=1.4002
+     205             : DEUTER_CONC=0.48
+     206             : QVALUE1=0.03 EXPINT1=1.0902
+     207             : QVALUE2=0.06 EXPINT2=0.790632
+     208             : QVALUE3=0.09 EXPINT3=0.453808
+     209             : QVALUE4=0.12 EXPINT4=0.254737
+     210             : QVALUE5=0.15 EXPINT5=0.154928
+     211             : QVALUE6=0.18 EXPINT6=0.0921503
+     212             : QVALUE7=0.21 EXPINT7=0.052633
+     213             : QVALUE8=0.24 EXPINT8=0.0276557
+     214             : QVALUE9=0.27 EXPINT9=0.0122775
+     215             : QVALUE10=0.30 EXPINT10=0.00880634
+     216             : ... SANS
+     217             : 
+     218             : PRINT ARG=(SANS\.q-.*),(SANS\.exp-.*) FILE=sansdata STRIDE=1
+     219             : 
+     220             : \endplumedfile
+     221             : 
+     222             : */
+     223             : //+ENDPLUMEDOC
+     224             : 
+     225             : class SAXS :
+     226             :   public MetainferenceBase
+     227             : {
+     228             : private:
+     229             :   enum { H, C, N, O, P, S, NTT };
+     230             :   enum { ALA_BB, ARG_BB, ARG_SC1, ARG_SC2, ASN_BB, ASN_SC1, ASP_BB, ASP_SC1, CYS_BB, CYS_SC1,
+     231             :          GLN_BB, GLN_SC1, GLU_BB, GLU_SC1, GLY_BB, HIS_BB, HIS_SC1, HIS_SC2, HIS_SC3, ILE_BB,
+     232             :          ILE_SC1, LEU_BB, LEU_SC1, LYS_BB, LYS_SC1, LYS_SC2, MET_BB, MET_SC1, PHE_BB, PHE_SC1,
+     233             :          PHE_SC2, PHE_SC3, PRO_BB, PRO_SC1, SER_BB, SER_SC1, THR_BB, THR_SC1, TRP_BB, TRP_SC1,
+     234             :          TRP_SC2, TRP_SC3, TRP_SC4, TYR_BB, TYR_SC1, TYR_SC2, TYR_SC3, VAL_BB, VAL_SC1, A_BB1,
+     235             :          A_BB2, A_BB3, A_SC1, A_SC2, A_SC3, A_SC4, A_3TE, A_5TE, A_TE3, A_TE5, C_BB1, C_BB2,
+     236             :          C_BB3, C_SC1, C_SC2, C_SC3, C_3TE, C_5TE, C_TE3, C_TE5, G_BB1, G_BB2, G_BB3, G_SC1,
+     237             :          G_SC2, G_SC3, G_SC4, G_3TE, G_5TE, G_TE3, G_TE5, U_BB1, U_BB2, U_BB3, U_SC1, U_SC2,
+     238             :          U_SC3, U_3TE, U_5TE, U_TE3, U_TE5, DA_BB1, DA_BB2, DA_BB3, DA_SC1, DA_SC2, DA_SC3,
+     239             :          DA_SC4, DA_3TE, DA_5TE, DA_TE3, DA_TE5, DC_BB1, DC_BB2, DC_BB3, DC_SC1, DC_SC2, DC_SC3,
+     240             :          DC_3TE, DC_5TE, DC_TE3, DC_TE5, DG_BB1, DG_BB2, DG_BB3, DG_SC1, DG_SC2, DG_SC3, DG_SC4,
+     241             :          DG_3TE, DG_5TE, DG_TE3, DG_TE5, DT_BB1, DT_BB2, DT_BB3, DT_SC1, DT_SC2, DT_SC3, DT_3TE,
+     242             :          DT_5TE, DT_TE3, DT_TE5, NMARTINI
+     243             :        };
+     244             :   enum { TRP, TYR, PHE, HIS, HIP, ARG, LYS, CYS, ASP, GLU, ILE, LEU, MET, ASN, PRO, GLN, SER, THR, VAL, ALA, GLY,
+     245             :          BASE_A, BASE_C, BASE_T, BASE_G, BASE_U,
+     246             :          BB_DNA, BB_DNA_5, BB_DNA_3,
+     247             :          BB_RNA, BB_RNA_5, BB_RNA_3,
+     248             :          BB_PO2,
+     249             :          NONEBEAD
+     250             :        };
+     251             :   bool saxs;
+     252             :   bool pbc;
+     253             :   bool serial;
+     254             :   bool gpu;
+     255             :   bool onebead;
+     256             :   bool isFirstStep;
+     257             :   int  deviceid;
+     258             :   unsigned nres;
+     259             :   std::vector<unsigned> atoi;
+     260             :   std::vector<unsigned> atoms_per_bead;
+     261             :   std::vector<double>   atoms_masses;
+     262             :   std::vector<double>   q_list;
+     263             :   std::vector<double>   FF_rank;
+     264             :   std::vector<std::vector<double> > FF_value_vacuum;
+     265             :   std::vector<std::vector<double> > FF_value_solv;
+     266             :   std::vector<std::vector<double> > FF_value_mixed;
+     267             :   std::vector<std::vector<double> > FF_value;
+     268             :   std::vector<std::vector<float> >  FFf_value;
+     269             :   // SANS:
+     270             :   std::vector<std::vector<double> > FF_value_vacuum_H;
+     271             :   std::vector<std::vector<double> > FF_value_solv_H;
+     272             :   std::vector<std::vector<double> > FF_value_mixed_H;
+     273             :   std::vector<std::vector<double> > FF_value_vacuum_D;
+     274             :   std::vector<std::vector<double> > FF_value_mixed_D;
+     275             : 
+     276             :   std::vector<std::vector<double> > LCPOparam;
+     277             :   std::vector<unsigned> residue_atom;
+     278             : 
+     279             :   double rho, rho_corr, sasa_cutoff;
+     280             :   double deuter_conc;
+     281             :   unsigned solv_stride;
+     282             :   std::vector<double> Iq0_vac;
+     283             :   std::vector<double> Iq0_solv;
+     284             :   std::vector<double> Iq0_mix;
+     285             :   double Iq0;
+     286             : 
+     287             :   // SANS:
+     288             :   std::vector<double> Iq0_vac_H;
+     289             :   std::vector<double> Iq0_solv_H;
+     290             :   std::vector<double> Iq0_mix_H;
+     291             :   std::vector<double> Iq0_vac_D;
+     292             :   std::vector<double> Iq0_mix_D;
+     293             : 
+     294             :   void calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     295             :   void calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     296             :   void getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter);
+     297             :   void getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, std::vector<unsigned> residue_atom);
+     298             :   unsigned getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms);
+     299             :   double calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho);
+     300             :   std::map<std::string, std::vector<double> > setupLCPOparam();
+     301             :   void readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms);
+     302             :   void calcNlist(std::vector<std::vector<int> > &Nlist);
+     303             :   void sasa_calculate(std::vector<bool> &solv_res);
+     304             :   // SANS:
+     305             :   void getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H);
+     306             :   void getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D);
+     307             :   double calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc);
+     308             : 
+     309             : public:
+     310             :   static void registerKeywords( Keywords& keys );
+     311             :   explicit SAXS(const ActionOptions&);
+     312             :   void calculate() override;
+     313             :   void update() override;
+     314             : };
+     315             : 
+     316       12548 : PLUMED_REGISTER_ACTION(SAXS,"SAXS")
+     317       12516 : PLUMED_REGISTER_ACTION(SAXS,"SANS")
+     318             : 
+     319          32 : void SAXS::registerKeywords(Keywords& keys) {
+     320          32 :   componentsAreNotOptional(keys);
+     321          32 :   MetainferenceBase::registerKeywords(keys);
+     322          64 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     323          64 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     324          64 :   keys.add("compulsory","DEVICEID","-1","Identifier of the GPU to be used");
+     325          64 :   keys.addFlag("GPU",false,"calculate SAXS using ARRAYFIRE on an accelerator device");
+     326          64 :   keys.addFlag("ATOMISTIC",false,"calculate SAXS for an atomistic model");
+     327          64 :   keys.addFlag("MARTINI",false,"calculate SAXS for a Martini model");
+     328          64 :   keys.addFlag("ONEBEAD",false,"calculate SAXS for a single bead model");
+     329          64 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file is required for ONEBEAD mapping");
+     330          64 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein");
+     331          64 :   keys.add("numbered","QVALUE","Selected scattering lengths in inverse angstroms are given as QVALUE1, QVALUE2, ...");
+     332          64 :   keys.add("numbered","PARAMETERS","Used parameter Keywords like PARAMETERS1, PARAMETERS2. These are used to calculate the form factor for the \\f$i\\f$th atom/bead");
+     333          64 :   keys.add("compulsory","DEUTER_CONC","0.","Fraction of deuterated solvent");
+     334          64 :   keys.add("compulsory","SOLVDENS","0.334","Density of the solvent to be used for the correction of atomistic form factors");
+     335          64 :   keys.add("compulsory","SOLVATION_CORRECTION","0.0","Hydration layer electron density correction (ONEBEAD only)");
+     336          64 :   keys.add("compulsory","SASA_CUTOFF","1.0","SASA value to consider a residue as exposed to the solvent (ONEBEAD only)");
+     337          64 :   keys.add("numbered","EXPINT","Add an experimental value for each q value");
+     338          64 :   keys.add("compulsory","SOLVATION_STRIDE","100","Number of steps between every new residues solvation estimation via LCPO (ONEBEAD only)");
+     339          64 :   keys.add("compulsory","SCALE_EXPINT","1.0","Scaling value for experimental data normalization");
+     340          64 :   keys.addOutputComponent("q","default","the # SAXS of q");
+     341          64 :   keys.addOutputComponent("exp","EXPINT","the # experimental intensity");
+     342          32 : }
+     343             : 
+     344          28 : SAXS::SAXS(const ActionOptions&ao):
+     345             :   PLUMED_METAINF_INIT(ao),
+     346          28 :   saxs(true),
+     347          28 :   pbc(true),
+     348          28 :   serial(false),
+     349          28 :   gpu(false),
+     350          28 :   onebead(false),
+     351          28 :   isFirstStep(true),
+     352          28 :   deviceid(-1)
+     353             : {
+     354          28 :   if( getName().find("SAXS")!=std::string::npos) { saxs=true; }
+     355           6 :   else if( getName().find("SANS")!=std::string::npos) { saxs=false; }
+     356             : 
+     357             :   std::vector<AtomNumber> atoms;
+     358          56 :   parseAtomList("ATOMS",atoms);
+     359          28 :   unsigned size = atoms.size();
+     360             : 
+     361          28 :   parseFlag("SERIAL",serial);
+     362             : 
+     363          28 :   bool nopbc=!pbc;
+     364          28 :   parseFlag("NOPBC",nopbc);
+     365          28 :   pbc=!nopbc;
+     366          28 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     367          16 :   else         log.printf("  without periodic boundary conditions\n");
+     368             : 
+     369          28 :   parseFlag("GPU",gpu);
+     370             : #ifndef  __PLUMED_HAS_ARRAYFIRE
+     371          28 :   if(gpu) error("To use the GPU mode PLUMED must be compiled with ARRAYFIRE");
+     372             : #endif
+     373             : 
+     374          28 :   parse("DEVICEID",deviceid);
+     375             : #ifdef  __PLUMED_HAS_ARRAYFIRE
+     376             :   if(gpu&&comm.Get_rank()==0) {
+     377             :     // if not set try to check the one set by the API
+     378             :     if(deviceid==-1) deviceid=plumed.getGpuDeviceId();
+     379             :     // if still not set use 0
+     380             :     if(deviceid==-1) deviceid=0;
+     381             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+     382             :     af::setDevice(afcu::getNativeId(deviceid));
+     383             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+     384             :     af::setDevice(afcl::getNativeId(deviceid));
+     385             : #else
+     386             :     af::setDevice(deviceid);
+     387             : #endif
+     388             :     af::info();
+     389             :   }
+     390             : #endif
+     391             : 
+     392          28 :   bool atomistic=false;
+     393          28 :   parseFlag("ATOMISTIC",atomistic);
+     394          28 :   if(atomistic) log.printf("  using ATOMISTIC form factors\n");
+     395          28 :   bool martini=false;
+     396          28 :   parseFlag("MARTINI",martini);
+     397          28 :   if(martini) log.printf("  using MARTINI form factors\n");
+     398          28 :   onebead=false;
+     399          28 :   parseFlag("ONEBEAD",onebead);
+     400          28 :   if(onebead) log.printf("  using ONEBEAD form factors\n");
+     401             : 
+     402          28 :   if(martini&&atomistic) error("You cannot use MARTINI and ATOMISTIC at the same time");
+     403          28 :   if(martini&&onebead) error("You cannot use MARTINI and ONEBEAD at the same time");
+     404          28 :   if(onebead&&atomistic) error("You cannot use ONEBEAD and ATOMISTIC at the same time");
+     405          28 :   if((martini)&&(!saxs)) error("MARTINI cannot be used with SANS");
+     406          28 :   if((!atomistic)&&(!martini)&&(!onebead)&&(!saxs)) error("External PARAMETERS cannot be used with SANS");
+     407             : 
+     408             :   unsigned ntarget=0;
+     409             :   for(unsigned i=0;; ++i) {
+     410             :     double t_list;
+     411         608 :     if( !parseNumbered( "QVALUE", i+1, t_list) ) break;
+     412         276 :     if(t_list<=0.) error("QVALUE cannot be less or equal to zero!\n");
+     413         276 :     if(onebead&&t_list>0.3) error("ONEBEAD mapping QVALUE must be smaller or equal to 0.3");
+     414         276 :     q_list.push_back(t_list);
+     415         276 :     ntarget++;
+     416         276 :   }
+     417             :   const unsigned numq = ntarget;
+     418             : 
+     419         304 :   for(unsigned i=0; i<numq; ++i) {
+     420         276 :     if(q_list[i]==0.) error("it is not possible to set q=0\n");
+     421         276 :     if(i>0&&q_list[i]<q_list[i-1]) error("QVALUE must be in ascending order");
+     422         276 :     log.printf("  my q: %lf \n",q_list[i]);
+     423             :   }
+     424             : 
+     425          28 :   rho = 0.334;
+     426          28 :   parse("SOLVDENS", rho);
+     427          28 :   log.printf("  Solvent density: %lf\n", rho);
+     428             : 
+     429          28 :   double scale_expint=1.;
+     430          28 :   parse("SCALE_EXPINT",scale_expint);
+     431             : 
+     432          28 :   double correction = 0.00;
+     433          28 :   parse("SOLVATION_CORRECTION", correction);
+     434          28 :   rho_corr=rho-correction;
+     435          28 :   if(onebead) log.printf("  Solvation density contribution: %lf\n", correction);
+     436          28 :   if((atomistic||martini)&&(rho_corr!=rho)) log.printf("  Solvation density contribution is taken into account in ONEBEAD only\n");
+     437             : 
+     438          28 :   solv_stride = 100;
+     439          28 :   parse("SOLVATION_STRIDE", solv_stride);
+     440          28 :   if(solv_stride < 1.) error("SOLVATION_STRIDE must be greater than 0");
+     441          28 :   if(onebead&&(rho_corr!=rho)) log.printf("  SASA calculation stride: %u\n", solv_stride);
+     442             : 
+     443          28 :   sasa_cutoff = 1.0;
+     444          28 :   parse("SASA_CUTOFF", sasa_cutoff);
+     445          28 :   if(sasa_cutoff <= 0.) error("SASA_CUTOFF must be greater than 0");
+     446             : 
+     447          28 :   deuter_conc = 0.;
+     448          28 :   parse("DEUTER_CONC", deuter_conc);
+     449          28 :   if(deuter_conc < 0. || deuter_conc > 1.) error("DEUTER_CONC must be in 0-1 range");
+     450          28 :   if ((atomistic||onebead)&&(!saxs)) log.printf("  Solvent deuterium fraction: %lf/1.000000\n", deuter_conc);
+     451             : 
+     452          28 :   PDB pdb;
+     453          28 :   if(onebead) {
+     454             :     std::string template_name;
+     455          10 :     parse("TEMPLATE",template_name);
+     456          10 :     log.printf("  Template for ONEBEAD mapping conversion: %s\n", template_name.c_str());
+     457          20 :     if( !pdb.read(template_name,plumed.getAtoms().usingNaturalUnits(),1.) ) plumed_merror("missing input file " + template_name);
+     458             :   }
+     459             : 
+     460             :   // Here we perform the preliminary mapping for onebead representation
+     461          28 :   if(onebead) {
+     462          10 :     LCPOparam.resize(size);
+     463          10 :     nres = getOnebeadMapping(pdb, atoms);
+     464          10 :     if(saxs) {
+     465           6 :       Iq0_vac.resize(nres);
+     466           6 :       Iq0_solv.resize(nres);
+     467           6 :       Iq0_mix.resize(nres);
+     468             :     } else { // SANS
+     469           4 :       Iq0_vac_H.resize(nres);
+     470           4 :       Iq0_solv_H.resize(nres);
+     471           4 :       Iq0_mix_H.resize(nres);
+     472           4 :       Iq0_vac_D.resize(nres);
+     473           4 :       Iq0_mix_D.resize(nres);
+     474             :     }
+     475          10 :     atoi.resize(nres);
+     476             :   } else {
+     477          18 :     atoi.resize(size);
+     478             :   }
+     479             : 
+     480          28 :   Iq0=0;
+     481             :   std::vector<std::vector<long double> > FF_tmp;
+     482             :   std::vector<std::vector<long double> > FF_tmp_vac;
+     483             :   std::vector<std::vector<long double> > FF_tmp_mix;
+     484             :   std::vector<std::vector<long double> > FF_tmp_solv;
+     485             :   std::vector<std::vector<long double> > parameter;
+     486             :   // SANS
+     487             :   std::vector<std::vector<long double> > FF_tmp_vac_H;
+     488             :   std::vector<std::vector<long double> > FF_tmp_mix_H;
+     489             :   std::vector<std::vector<long double> > FF_tmp_solv_H;
+     490             :   std::vector<std::vector<long double> > FF_tmp_vac_D;
+     491             :   std::vector<std::vector<long double> > FF_tmp_mix_D;
+     492             :   std::vector<std::vector<long double> > parameter_H;
+     493             :   std::vector<std::vector<long double> > parameter_D;
+     494             : 
+     495          28 :   if(!atomistic&&!martini&&!onebead) {
+     496             :     // read in parameter std::vector
+     497           4 :     parameter.resize(size);
+     498             :     ntarget=0;
+     499          36 :     for(unsigned i=0; i<size; ++i) {
+     500          64 :       if( !parseNumberedVector( "PARAMETERS", i+1, parameter[i]) ) break;
+     501          32 :       ntarget++;
+     502             :     }
+     503           4 :     if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     504           4 :     FF_tmp.resize(numq,std::vector<long double>(size));
+     505          36 :     for(unsigned i=0; i<size; ++i) {
+     506          32 :       atoi[i]=i;
+     507         128 :       for(unsigned k=0; k<numq; ++k) {
+     508         480 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     509         384 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     510             :         }
+     511             :       }
+     512             :     }
+     513          36 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     514           4 :     Iq0 *= Iq0;
+     515          28 :   } else if(onebead) {
+     516          10 :     if(saxs) {
+     517             :       // read in parameter std::vector
+     518           6 :       FF_tmp_vac.resize(numq,std::vector<long double>(NONEBEAD));
+     519           6 :       FF_tmp_mix.resize(numq,std::vector<long double>(NONEBEAD));
+     520           6 :       FF_tmp_solv.resize(numq,std::vector<long double>(NONEBEAD));
+     521           6 :       std::vector<std::vector<long double> > parameter_vac(NONEBEAD);
+     522           6 :       std::vector<std::vector<long double> > parameter_mix(NONEBEAD);
+     523           6 :       std::vector<std::vector<long double> > parameter_solv(NONEBEAD);
+     524           6 :       getOnebeadparam(pdb, atoms, parameter_vac, parameter_mix, parameter_solv,residue_atom);
+     525         204 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     526        1980 :         for(unsigned k=0; k<numq; ++k) {
+     527       14256 :           for(unsigned j=0; j<parameter_vac[i].size(); ++j) {
+     528       12474 :             FF_tmp_vac[k][i]+= parameter_vac[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     529             :           }
+     530       14256 :           for(unsigned j=0; j<parameter_mix[i].size(); ++j) {
+     531       12474 :             FF_tmp_mix[k][i]+= parameter_mix[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     532             :           }
+     533       14256 :           for(unsigned j=0; j<parameter_solv[i].size(); ++j) {
+     534       12474 :             FF_tmp_solv[k][i]+= parameter_solv[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     535             :           }
+     536             :         }
+     537             :       }
+     538        1294 :       for(unsigned i=0; i<nres; ++i) {
+     539        1288 :         Iq0_vac[i]=parameter_vac[atoi[i]][0];
+     540        1288 :         Iq0_mix[i]=parameter_mix[atoi[i]][0];
+     541        1288 :         Iq0_solv[i]=parameter_solv[atoi[i]][0];
+     542             :       }
+     543           6 :     } else { // SANS
+     544             :       // read in parameter std::vector
+     545           4 :       FF_tmp_vac_H.resize(numq,std::vector<long double>(NONEBEAD));
+     546           4 :       FF_tmp_mix_H.resize(numq,std::vector<long double>(NONEBEAD));
+     547           4 :       FF_tmp_solv_H.resize(numq,std::vector<long double>(NONEBEAD));
+     548           4 :       FF_tmp_vac_D.resize(numq,std::vector<long double>(NONEBEAD));
+     549           4 :       FF_tmp_mix_D.resize(numq,std::vector<long double>(NONEBEAD));
+     550           4 :       std::vector<std::vector<long double> > parameter_vac_H(NONEBEAD);
+     551           4 :       std::vector<std::vector<long double> > parameter_mix_H(NONEBEAD);
+     552           4 :       std::vector<std::vector<long double> > parameter_solv_H(NONEBEAD);
+     553           4 :       std::vector<std::vector<long double> > parameter_vac_D(NONEBEAD);
+     554           4 :       std::vector<std::vector<long double> > parameter_mix_D(NONEBEAD);
+     555           4 :       getOnebeadparam_sansH(pdb, atoms, parameter_vac_H, parameter_mix_H, parameter_solv_H);
+     556           4 :       getOnebeadparam_sansD(pdb, atoms, parameter_vac_D, parameter_mix_D);
+     557         136 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     558        1320 :         for(unsigned k=0; k<numq; ++k) {
+     559        9504 :           for(unsigned j=0; j<parameter_vac_H[i].size(); ++j) { // same number of parameters
+     560        8316 :             FF_tmp_vac_H[k][i]+= parameter_vac_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     561        8316 :             FF_tmp_vac_D[k][i]+= parameter_vac_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     562             :           }
+     563        9504 :           for(unsigned j=0; j<parameter_mix_H[i].size(); ++j) {
+     564        8316 :             FF_tmp_mix_H[k][i]+= parameter_mix_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     565        8316 :             FF_tmp_mix_D[k][i]+= parameter_mix_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     566             :           }
+     567        9504 :           for(unsigned j=0; j<parameter_solv_H[i].size(); ++j) {
+     568        8316 :             FF_tmp_solv_H[k][i]+= parameter_solv_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     569             :           }
+     570             :         }
+     571             :       }
+     572         880 :       for(unsigned i=0; i<nres; ++i) {
+     573         876 :         Iq0_vac_H[i]=parameter_vac_H[atoi[i]][0];
+     574         876 :         Iq0_mix_H[i]=parameter_mix_H[atoi[i]][0];
+     575         876 :         Iq0_solv_H[i]=parameter_solv_H[atoi[i]][0];
+     576         876 :         Iq0_vac_D[i]=parameter_vac_D[atoi[i]][0];
+     577         876 :         Iq0_mix_D[i]=parameter_mix_D[atoi[i]][0];
+     578             :       }
+     579           4 :     }
+     580          14 :   } else if(martini) {
+     581             :     // read in parameter std::vector
+     582           8 :     FF_tmp.resize(numq,std::vector<long double>(NMARTINI));
+     583           8 :     parameter.resize(NMARTINI);
+     584           8 :     getMartiniFFparam(atoms, parameter);
+     585        1072 :     for(unsigned i=0; i<NMARTINI; ++i) {
+     586       17024 :       for(unsigned k=0; k<numq; ++k) {
+     587      127680 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     588      111720 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     589             :         }
+     590             :       }
+     591             :     }
+     592        8400 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[atoi[i]][0];
+     593           8 :     Iq0 *= Iq0;
+     594           6 :   } else if(atomistic) {
+     595           6 :     FF_tmp.resize(numq,std::vector<long double>(NTT));
+     596           6 :     if(saxs) Iq0=calculateAFF(atoms, FF_tmp, rho);
+     597           2 :     else Iq0=calculateAFFsans(atoms, FF_tmp, deuter_conc);
+     598           6 :     Iq0 *= Iq0;
+     599             :   }
+     600             : 
+     601             :   std::vector<double> expint;
+     602          28 :   expint.resize( numq );
+     603             :   ntarget=0;
+     604         160 :   for(unsigned i=0; i<numq; ++i) {
+     605         296 :     if( !parseNumbered( "EXPINT", i+1, expint[i] ) ) break;
+     606         132 :     ntarget++;
+     607             :   }
+     608         160 :   std::transform(expint.begin(), expint.begin() + ntarget, expint.begin(), [scale_expint](double x) { return x / scale_expint; });
+     609             :   bool exp=false;
+     610          28 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of EXPINT values");
+     611          28 :   if(ntarget==numq) exp=true;
+     612          28 :   if(getDoScore()&&!exp) error("with DOSCORE you need to set the EXPINT values");
+     613             : 
+     614          28 :   if(!gpu) {
+     615          28 :     FF_rank.resize(numq);
+     616             :     unsigned n_atom_types;
+     617          28 :     if(onebead) {
+     618          10 :       FF_value.resize(nres,std::vector<double>(numq));
+     619             :       n_atom_types=NONEBEAD;
+     620          10 :       if(saxs) {
+     621           6 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     622           6 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     623          12 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     624             :       } else {
+     625           4 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     626           4 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     627           4 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     628           4 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     629           8 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     630             :       }
+     631             :     } else {
+     632          36 :       FF_value.resize(size,std::vector<double>(numq));
+     633             :     }
+     634         304 :     for(unsigned k=0; k<numq; ++k) {
+     635         276 :       if(!onebead) {
+     636      316710 :         for(unsigned i=0; i<size; ++i) FF_value[i][k] = static_cast<double>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     637      316710 :         for(unsigned i=0; i<size; ++i) FF_rank[k] += FF_value[i][k]*FF_value[i][k];
+     638             :       } else {
+     639          90 :         if(saxs) {
+     640        1836 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     641        1782 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     642        1782 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     643        1782 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     644             :           }
+     645             :         } else { // SANS
+     646        1224 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     647        1188 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     648        1188 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     649        1188 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     650        1188 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     651        1188 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     652             :           }
+     653             :         }
+     654             :       }
+     655             :     }
+     656             :   } else {
+     657             :     unsigned n_atom_types;
+     658           0 :     if(onebead) {
+     659           0 :       FFf_value.resize(numq,std::vector<float>(nres));
+     660             :       n_atom_types=NONEBEAD;
+     661           0 :       if(saxs) {
+     662           0 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     663           0 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     664           0 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     665             :       } else { // SANS
+     666           0 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     667           0 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     668           0 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     669           0 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     670           0 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     671             :       }
+     672             :     } else {
+     673           0 :       FFf_value.resize(numq,std::vector<float>(size));
+     674             :     }
+     675           0 :     for(unsigned k=0; k<numq; ++k) {
+     676           0 :       if(!onebead) {
+     677           0 :         for(unsigned i=0; i<size; ++i) {
+     678           0 :           FFf_value[k][i] = static_cast<float>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     679             :         }
+     680             :       } else {
+     681           0 :         if(saxs) {
+     682           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     683           0 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     684           0 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     685           0 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     686             :           }
+     687             :         } else { // SANS
+     688           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     689           0 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     690           0 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     691           0 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     692           0 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     693           0 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     694             :           }
+     695             :         }
+     696             :       }
+     697             :     }
+     698             :   }
+     699             : 
+     700          28 :   if(!getDoScore()) {
+     701         224 :     for(unsigned i=0; i<numq; ++i) {
+     702         204 :       std::string num; Tools::convert(i,num);
+     703         204 :       addComponentWithDerivatives("q-"+num);
+     704         408 :       componentIsNotPeriodic("q-"+num);
+     705             :     }
+     706          20 :     if(exp) {
+     707          64 :       for(unsigned i=0; i<numq; ++i) {
+     708          60 :         std::string num; Tools::convert(i,num);
+     709          60 :         addComponent("exp-"+num);
+     710          60 :         componentIsNotPeriodic("exp-"+num);
+     711          60 :         Value* comp=getPntrToComponent("exp-"+num);
+     712          60 :         comp->set(expint[i]);
+     713             :       }
+     714             :     }
+     715             :   } else {
+     716          80 :     for(unsigned i=0; i<numq; ++i) {
+     717          72 :       std::string num; Tools::convert(i,num);
+     718          72 :       addComponent("q-"+num);
+     719         144 :       componentIsNotPeriodic("q-"+num);
+     720             :     }
+     721          80 :     for(unsigned i=0; i<numq; ++i) {
+     722          72 :       std::string num; Tools::convert(i,num);
+     723          72 :       addComponent("exp-"+num);
+     724          72 :       componentIsNotPeriodic("exp-"+num);
+     725          72 :       Value* comp=getPntrToComponent("exp-"+num);
+     726          72 :       comp->set(expint[i]);
+     727             :     }
+     728             :   }
+     729             : 
+     730             :   // convert units to nm^-1
+     731         304 :   for(unsigned i=0; i<numq; ++i) {
+     732         276 :     q_list[i]=q_list[i]*10.0;    // factor 10 to convert from A^-1 to nm^-1
+     733             :   }
+     734          28 :   log<<"  Bibliography ";
+     735          28 :   if(martini) {
+     736          16 :     log<<plumed.cite("Niebling, Björling, Westenhoff, J Appl Crystallogr 47, 1190–1198 (2014).");
+     737          16 :     log<<plumed.cite("Paissoni, Jussupow, Camilloni, J Appl Crystallogr 52, 394-402 (2019).");
+     738             :   }
+     739          28 :   if(atomistic) {
+     740          12 :     log<<plumed.cite("Fraser, MacRae, Suzuki, J. Appl. Crystallogr., 11, 693–694 (1978).");
+     741          12 :     log<<plumed.cite("Brown, Fox, Maslen, O'Keefe, Willis, International Tables for Crystallography C, 554–595 (International Union of Crystallography, 2006).");
+     742             :   }
+     743             : 
+     744          56 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     745          28 :   log<<"\n";
+     746             : 
+     747          28 :   requestAtoms(atoms, false);
+     748             : 
+     749          28 :   if(getDoScore()) {
+     750           8 :     setParameters(expint);
+     751           8 :     Initialise(numq);
+     752             :   }
+     753          28 :   setDerivatives();
+     754          28 :   checkRead();
+     755          56 : }
+     756             : 
+     757             : // calculates SASA neighbor list
+     758           8 : void SAXS::calcNlist(std::vector<std::vector<int> > &Nlist)
+     759             : {
+     760             :   unsigned natoms = getNumberOfAtoms();
+     761       28596 :   for(unsigned i = 0; i < natoms; ++i) {
+     762       28588 :     if (LCPOparam[i].size()>0) {
+     763    24279400 :       for (unsigned j = 0; j < i; ++j) {
+     764    24266020 :         if (LCPOparam[j].size()>0) {
+     765    11213664 :           double Delta_ij_mod = modulo(delta(getPosition(i), getPosition(j)))*10.;
+     766    11213664 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     767    11213664 :           if(Delta_ij_mod < overlapD) {
+     768      259140 :             Nlist.at(i).push_back(j);
+     769      259140 :             Nlist.at(j).push_back(i);
+     770             :           }
+     771             :         }
+     772             :       }
+     773             :     }
+     774             :   }
+     775             : 
+     776           8 : }
+     777             : 
+     778             : // calculates SASA according to LCPO algorithm
+     779           8 : void SAXS::sasa_calculate(std::vector<bool> &solv_res)
+     780             : {
+     781             :   unsigned natoms = getNumberOfAtoms();
+     782           8 :   std::vector<std::vector<int> > Nlist(natoms);
+     783           8 :   calcNlist(Nlist);
+     784           8 :   std::vector<double> sasares(nres, 0.);
+     785       28596 :   for(unsigned i = 0; i < natoms; ++i) {
+     786       28588 :     if(LCPOparam[i].size()>1) {
+     787       13380 :       if(LCPOparam[i][1]>0.0) {
+     788             :         double Aij = 0.0;
+     789             :         double Aijk = 0.0;
+     790             :         double Ajk = 0.0;
+     791       13380 :         double ri = LCPOparam[i][0];
+     792       13380 :         double S1 = 4.*M_PI*ri*ri;
+     793      531660 :         for (unsigned j = 0; j < Nlist[i].size(); ++j) {
+     794      518280 :           double d_ij = modulo(delta( getPosition(i), getPosition(Nlist[i][j]) ))*10.;
+     795      518280 :           double rj = LCPOparam[Nlist[i][j]][0];
+     796      518280 :           double Aijt = (2.*M_PI*ri*(ri-d_ij/2.-((ri*ri-rj*rj)/(2.*d_ij))));
+     797             :           double Ajkt = 0.0;
+     798    22258568 :           for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); ++k) {
+     799    21740288 :             if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     800    11186016 :               double d_jk = modulo(delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) ))*10.;
+     801    11186016 :               double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     802    11186016 :               double sjk =  (2.*M_PI*rj*(rj-d_jk/2.-((rj*rj-rk*rk)/(2.*d_jk))));
+     803    11186016 :               Ajkt += sjk;
+     804             :             }
+     805             :           }
+     806      518280 :           Aijk += (Aijt * Ajkt);
+     807      518280 :           Aij += Aijt;
+     808      518280 :           Ajk += Ajkt;
+     809             :         }
+     810       13380 :         double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     811       13380 :         if (sasai > 0 ) {
+     812       10420 :           sasares[residue_atom[i]] += sasai/100.;
+     813             :         }
+     814             :       }
+     815             :     }
+     816             :   }
+     817        1760 :   for(unsigned i=0; i<nres; ++i) {
+     818        1752 :     if(sasares[i]>sasa_cutoff) solv_res[i] = 1;
+     819             :     else solv_res[i] = 0;
+     820             :   }
+     821           8 : }
+     822             : 
+     823           0 : void SAXS::calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+     824             : {
+     825             : #ifdef __PLUMED_HAS_ARRAYFIRE
+     826             :   unsigned size;
+     827             :   if(onebead) size = nres;
+     828             :   else size = getNumberOfAtoms();
+     829             :   const unsigned numq = q_list.size();
+     830             : 
+     831             :   std::vector<float> sum;
+     832             :   sum.resize(numq);
+     833             : 
+     834             :   std::vector<float> dd;
+     835             :   dd.resize(size*3*numq);
+     836             : 
+     837             :   // on gpu only the master rank run the calculation
+     838             :   if(comm.Get_rank()==0) {
+     839             :     std::vector<float> posi;
+     840             :     posi.resize(3*size);
+     841             :     #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     842             :     for (unsigned i=0; i<size; ++i) {
+     843             :       const Vector tmp = pos[i];
+     844             :       posi[3*i]   = static_cast<float>(tmp[0]);
+     845             :       posi[3*i+1] = static_cast<float>(tmp[1]);
+     846             :       posi[3*i+2] = static_cast<float>(tmp[2]);
+     847             :     }
+     848             : 
+     849             :     // create array a and b containing atomic coordinates
+     850             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+     851             :     af::setDevice(afcu::getNativeId(deviceid));
+     852             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+     853             :     af::setDevice(afcl::getNativeId(deviceid));
+     854             : #else
+     855             :     af::setDevice(deviceid);
+     856             : #endif
+     857             :     // 3,size,1,1
+     858             :     af::array pos_a = af::array(3, size, &posi.front());
+     859             :     // size,3,1,1
+     860             :     pos_a = af::moddims(pos_a.T(), size, 3, 1);
+     861             :     // size,3,1,1
+     862             :     af::array pos_b = pos_a(af::span, af::span);
+     863             :     // size,1,3,1
+     864             :     pos_a = af::moddims(pos_a, size, 1, 3);
+     865             :     // 1,size,3,1
+     866             :     pos_b = af::moddims(pos_b, 1, size, 3);
+     867             : 
+     868             :     // size,size,3,1
+     869             :     af::array pos_a_t = af::tile(pos_a, 1, size, 1);
+     870             :     // size,size,3,1: for some reason we need this
+     871             :     pos_a_t = af::moddims(pos_a_t, size, size, 3);
+     872             :     // size,size,3,1
+     873             :     af::array pos_b_t = af::tile(pos_b, size, 1, 1);
+     874             :     // size,size,3,1: for some reason we need this
+     875             :     pos_b_t = af::moddims(pos_b_t, size, size, 3);
+     876             :     // size,size,3,1
+     877             :     af::array xyz_dist = pos_a_t - pos_b_t;
+     878             :     // size,size,1,1
+     879             :     af::array square = af::sum(xyz_dist*xyz_dist,2);
+     880             :     // size,size,1,1
+     881             :     af::array dist_sqrt = af::sqrt(square);
+     882             :     // replace the zero of square with one to avoid nan in the derivatives (the number does not matter because this are multiplied by zero)
+     883             :     af::replace(square,!(af::iszero(square)),1.);
+     884             :     // size,size,3,1
+     885             :     xyz_dist = xyz_dist / af::tile(square, 1, 1, 3);
+     886             :     // numq,1,1,1
+     887             :     af::array sum_device   = af::constant(0, numq, f32);
+     888             :     // numq,size,3,1
+     889             :     af::array deriv_device = af::constant(0, numq, size, 3, f32);
+     890             : 
+     891             :     for (unsigned k=0; k<numq; ++k) {
+     892             :       // calculate FF matrix
+     893             :       // size,1,1,1
+     894             :       af::array AFF_value(size, &FFf_value[k].front());
+     895             :       // size,size,1,1
+     896             :       af::array FFdist_mod = af::tile(AFF_value(af::span), 1, size)*af::transpose(af::tile(AFF_value(af::span), 1, size));
+     897             : 
+     898             :       // get q
+     899             :       const float qvalue = static_cast<float>(q_list[k]);
+     900             :       // size,size,1,1
+     901             :       af::array dist_q = qvalue*dist_sqrt;
+     902             :       // size,size,1
+     903             :       af::array dist_sin = af::sin(dist_q)/dist_q;
+     904             :       af::replace(dist_sin,!(af::isNaN(dist_sin)),1.);
+     905             :       // 1,1,1,1
+     906             :       sum_device(k) = af::sum(af::flat(dist_sin)*af::flat(FFdist_mod));
+     907             : 
+     908             :       // size,size,1,1
+     909             :       af::array tmp = FFdist_mod*(dist_sin - af::cos(dist_q));
+     910             :       // size,size,3,1
+     911             :       af::array dd_all = af::tile(tmp, 1, 1, 3)*xyz_dist;
+     912             :       // it should become 1,size,3
+     913             :       deriv_device(k, af::span, af::span) = af::sum(dd_all,0);
+     914             :     }
+     915             : 
+     916             :     // read out results
+     917             :     sum_device.host(&sum.front());
+     918             : 
+     919             :     deriv_device = af::reorder(deriv_device, 2, 1, 0);
+     920             :     deriv_device = af::flat(deriv_device);
+     921             :     deriv_device.host(&dd.front());
+     922             :   }
+     923             : 
+     924             :   comm.Bcast(dd, 0);
+     925             :   comm.Bcast(sum, 0);
+     926             : 
+     927             :   for(unsigned k=0; k<numq; ++k) {
+     928             :     std::string num; Tools::convert(k,num);
+     929             :     Value* val=getPntrToComponent("q-"+num);
+     930             :     val->set(sum[k]);
+     931             :     if(getDoScore()) setCalcData(k, sum[k]);
+     932             :     for(unsigned i=0; i<size; ++i) {
+     933             :       const unsigned di = k*size*3+i*3;
+     934             :       deriv[k*size+i] = Vector(2.*dd[di+0],2.*dd[di+1],2.*dd[di+2]);
+     935             :     }
+     936             :   }
+     937             : #endif
+     938           0 : }
+     939             : 
+     940         188 : void SAXS::calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+     941             : {
+     942             :   unsigned size;
+     943         188 :   if(onebead) size = nres;
+     944             :   else size = getNumberOfAtoms();
+     945         188 :   const unsigned numq = q_list.size();
+     946             : 
+     947         188 :   unsigned stride = comm.Get_size();
+     948         188 :   unsigned rank   = comm.Get_rank();
+     949         188 :   if(serial) {
+     950             :     stride = 1;
+     951             :     rank   = 0;
+     952             :   }
+     953         188 :   std::vector<double> sum(numq,0);
+     954         188 :   unsigned nt=OpenMP::getNumThreads();
+     955         188 :   #pragma omp parallel num_threads(nt)
+     956             :   {
+     957             :     std::vector<Vector> omp_deriv(deriv.size());
+     958             :     std::vector<double> omp_sum(numq,0);
+     959             :     #pragma omp for nowait
+     960             :     for (unsigned i=rank; i<size-1; i+=stride) {
+     961             :       Vector posi = pos[i];
+     962             :       for (unsigned j=i+1; j<size ; ++j) {
+     963             :         Vector c_distances = delta(posi,pos[j]);
+     964             :         double m_distances = c_distances.modulo();
+     965             :         c_distances = c_distances/m_distances/m_distances;
+     966             :         for (unsigned k=0; k<numq; ++k) {
+     967             :           unsigned kdx=k*size;
+     968             :           double qdist = q_list[k]*m_distances;
+     969             :           double FFF = 2.*FF_value[i][k]*FF_value[j][k];
+     970             :           double tsq = std::sin(qdist)/qdist;
+     971             :           double tcq = std::cos(qdist);
+     972             :           double tmp = FFF*(tcq-tsq);
+     973             :           Vector dd  = c_distances*tmp;
+     974             :           if(nt>1) {
+     975             :             omp_deriv[kdx+i] -=dd;
+     976             :             omp_deriv[kdx+j] +=dd;
+     977             :             omp_sum[k] += FFF*tsq;
+     978             :           } else {
+     979             :             deriv[kdx+i] -= dd;
+     980             :             deriv[kdx+j] += dd;
+     981             :             sum[k] += FFF*tsq;
+     982             :           }
+     983             :         }
+     984             :       }
+     985             :     }
+     986             :     #pragma omp critical
+     987             :     if(nt>1) {
+     988             :       for(unsigned i=0; i<deriv.size(); ++i) deriv[i]+=omp_deriv[i];
+     989             :       for(unsigned k=0; k<numq; ++k) sum[k]+=omp_sum[k];
+     990             :     }
+     991             :   }
+     992             : 
+     993         188 :   if(!serial) {
+     994         186 :     comm.Sum(&deriv[0][0], 3*deriv.size());
+     995         186 :     comm.Sum(&sum[0], numq);
+     996             :   }
+     997             : 
+     998        1904 :   for (unsigned k=0; k<numq; ++k) {
+     999        1716 :     sum[k]+=FF_rank[k];
+    1000        1716 :     std::string num; Tools::convert(k,num);
+    1001        1716 :     Value* val=getPntrToComponent("q-"+num);
+    1002        1716 :     val->set(sum[k]);
+    1003        1716 :     if(getDoScore()) setCalcData(k, sum[k]);
+    1004             :   }
+    1005         188 : }
+    1006             : 
+    1007         188 : void SAXS::calculate()
+    1008             : {
+    1009         188 :   if(pbc) makeWhole();
+    1010             : 
+    1011         188 :   const size_t size = getNumberOfAtoms();
+    1012             :   const size_t numq = q_list.size();
+    1013             : 
+    1014             :   // these are the derivatives associated to the coarse graining
+    1015         188 :   std::vector<Vector> aa_deriv(size);
+    1016             : 
+    1017             :   size_t beads_size = size;
+    1018         188 :   if(onebead) beads_size = nres;
+    1019             :   // these are the derivatives particle,q
+    1020         188 :   std::vector<Vector> bd_deriv(numq*beads_size);
+    1021             : 
+    1022         188 :   std::vector<Vector> beads_pos(beads_size);
+    1023         188 :   if(onebead) {
+    1024        2174 :     for(unsigned resid=0; resid<nres; resid++) {
+    1025             :       double sum_mass = 0.;
+    1026        2164 :       Vector sum_pos = Vector(0,0,0);
+    1027     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1028     7691628 :         if(residue_atom[atom_id] == resid) {
+    1029       35466 :           aa_deriv[atom_id] = Vector(atoms_masses[atom_id],atoms_masses[atom_id],atoms_masses[atom_id]);
+    1030       35466 :           sum_pos += atoms_masses[atom_id] * getPosition(atom_id); // getPosition(first_atom+atom_id)
+    1031       35466 :           sum_mass += atoms_masses[atom_id];
+    1032             :         }
+    1033             :       }
+    1034        2164 :       beads_pos[resid] = sum_pos/sum_mass;
+    1035     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1036     7691628 :         if(residue_atom[atom_id] == resid) {
+    1037       35466 :           aa_deriv[atom_id] /= sum_mass;
+    1038             :         }
+    1039             :       }
+    1040             :     }
+    1041             :     // SASA
+    1042          10 :     std::vector<bool> solv_res(nres, 0);
+    1043          10 :     if(saxs) {
+    1044           6 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1045           6 :         isFirstStep = 0;
+    1046           6 :         if(rho_corr!=rho) sasa_calculate(solv_res);
+    1047           6 :         Iq0=0.;
+    1048        1294 :         for(unsigned i=0; i<nres; ++i) {
+    1049        1288 :           if(solv_res[i] == 1 ) {
+    1050         182 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho_corr*rho_corr)*Iq0_solv[i]-rho_corr*Iq0_mix[i]));
+    1051             :           } else {
+    1052        1106 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho*rho)*Iq0_solv[i]-rho*Iq0_mix[i]));
+    1053             :           }
+    1054             :         }
+    1055             :         // Form Factors
+    1056          60 :         for(unsigned k=0; k<numq; ++k) {
+    1057       11646 :           for(unsigned i=0; i<nres; ++i) {
+    1058       11592 :             if(!gpu) {
+    1059       11592 :               if(solv_res[i] == 0) { // buried
+    1060        9954 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1061             :               } else { // surface
+    1062        1638 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1063             :               }
+    1064             :             } else {
+    1065           0 :               if(solv_res[i] == 0) { // buried
+    1066           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1067             :               } else { // surface
+    1068           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1069             :               }
+    1070             :             }
+    1071             :           }
+    1072             :         }
+    1073           6 :         if(!gpu) {
+    1074          60 :           for(unsigned k=0; k<numq; ++k) {
+    1075          54 :             FF_rank[k]=0.;
+    1076       11646 :             for(unsigned i=0; i<nres; ++i) {
+    1077       11592 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1078             :             }
+    1079             :           }
+    1080             :         }
+    1081             :       }
+    1082             :     } else { // SANS
+    1083           4 :       std::vector<bool> deut_res(nres, 0);
+    1084           4 :       double solv_sc_length = 0.1*(0.580 + 2.*((1. - deuter_conc) * (-0.374) + deuter_conc * 0.667)); // per water electron (10 electrons)
+    1085           4 :       double rho_sans = rho * solv_sc_length;
+    1086           4 :       double rho_sans_corr = rho_corr * solv_sc_length;
+    1087           4 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1088           4 :         isFirstStep = 0;
+    1089           4 :         if(deuter_conc!=0.||rho != rho_corr) sasa_calculate(solv_res);
+    1090           4 :         Iq0=0.;
+    1091         880 :         for(unsigned i=0; i<nres; ++i) {
+    1092         876 :           if(solv_res[i] == 1 ) {
+    1093         182 :             if(rand()/RAND_MAX<deuter_conc) {
+    1094           0 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_D[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_D[i]));
+    1095             :               deut_res[i] = 1;
+    1096             :             } else {
+    1097         182 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_H[i]));
+    1098             :             }
+    1099             :           } else {
+    1100         694 :             Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans*rho_sans*Iq0_solv_H[i] - rho_sans*Iq0_mix_H[i]));
+    1101             :           }
+    1102             :         }
+    1103             :         // Form Factors
+    1104          40 :         for(unsigned k=0; k<numq; ++k) {
+    1105        7920 :           for(unsigned i=0; i<nres; ++i) {
+    1106        7884 :             if(!gpu) {
+    1107        7884 :               if(solv_res[i] == 0) { // hydrogen
+    1108        6246 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1109             :               } else {
+    1110        1638 :                 if(deut_res[i] == 0) {
+    1111        1638 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1112             :                 } else {
+    1113           0 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0;
+    1114             :                 }
+    1115             :               }
+    1116             :             } else {
+    1117           0 :               if(solv_res[i] == 0) { // hydrogen
+    1118           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1119             :               } else {
+    1120           0 :                 if(deut_res[i] == 0) {
+    1121           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1122             :                 } else {
+    1123           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0);
+    1124             :                 }
+    1125             :               }
+    1126             :             }
+    1127             :           }
+    1128             :         }
+    1129           4 :         if(!gpu) {
+    1130          40 :           for(unsigned k=0; k<numq; ++k) {
+    1131          36 :             FF_rank[k]=0.;
+    1132        7920 :             for(unsigned i=0; i<nres; ++i) {
+    1133        7884 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1134             :             }
+    1135             :           }
+    1136             :         }
+    1137             :       }
+    1138             :     }
+    1139             :     // not ONEBEAD
+    1140             :   } else {
+    1141       58814 :     for(unsigned i=0; i<size; ++i) {
+    1142       58636 :       beads_pos[i] = getPosition(i);
+    1143             :     }
+    1144         356 :     aa_deriv = std::vector<Vector>(size,(Vector(1,1,1)));
+    1145             :   }
+    1146             : 
+    1147         188 :   if(gpu) calculate_gpu(beads_pos, bd_deriv);
+    1148         188 :   else calculate_cpu(beads_pos, bd_deriv);
+    1149             : 
+    1150         188 :   if(getDoScore()) {
+    1151             :     /* Metainference */
+    1152         168 :     double score = getScore();
+    1153             :     setScore(score);
+    1154             :   }
+    1155             : 
+    1156        1904 :   for (unsigned k=0; k<numq; ++k) {
+    1157        1716 :     const unsigned kdx=k*beads_size;
+    1158        1716 :     Tensor deriv_box;
+    1159             :     Value* val;
+    1160        1716 :     if(!getDoScore()) {
+    1161         204 :       std::string num; Tools::convert(k,num);
+    1162         204 :       val=getPntrToComponent("q-"+num);
+    1163             : 
+    1164         204 :       if(onebead) {
+    1165             :         unsigned atom_id=0;
+    1166       19566 :         for(unsigned i=0; i<beads_size; ++i) {
+    1167      338670 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1168      319194 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1169      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1170      319194 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1171      319194 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1172      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1173      638388 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1174      319194 :             atom_id++;
+    1175             :           }
+    1176             :         }
+    1177             :       } else {
+    1178      295242 :         for(unsigned i=0; i<beads_size; ++i) {
+    1179      295128 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0], \
+    1180      295128 :                                              bd_deriv[kdx+i][1], \
+    1181      295128 :                                              bd_deriv[kdx+i][2]) );
+    1182      590256 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0], \
+    1183      295128 :                               bd_deriv[kdx+i][1], \
+    1184      590256 :                               bd_deriv[kdx+i][2]) );
+    1185             :         }
+    1186             :       }
+    1187             :     } else {
+    1188        1512 :       val=getPntrToComponent("score");
+    1189        1512 :       if(onebead) {
+    1190             :         unsigned atom_id=0;
+    1191           0 :         for(unsigned i=0; i<beads_size; ++i) {
+    1192           0 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1193           0 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1194           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1195           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1196           0 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1197           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1198           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1199           0 :             atom_id++;
+    1200             :           }
+    1201             :         }
+    1202             :       } else {
+    1203      450828 :         for(unsigned i=0; i<beads_size; ++i) {
+    1204      449316 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1205      449316 :                                              bd_deriv[kdx+i][1]*getMetaDer(k),
+    1206      449316 :                                              bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1207      898632 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1208      449316 :                               bd_deriv[kdx+i][1]*getMetaDer(k),
+    1209      898632 :                               bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1210             :         }
+    1211             :       }
+    1212             :     }
+    1213        1716 :     setBoxDerivatives(val, -deriv_box);
+    1214             :   }
+    1215         188 : }
+    1216             : 
+    1217         188 : void SAXS::update() {
+    1218             :   // write status file
+    1219         188 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1220         188 : }
+    1221             : 
+    1222          10 : unsigned SAXS::getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms) {
+    1223          10 :   std::vector<std::string> chains; pdb.getChainNames( chains );
+    1224             :   std::vector<std::vector<std::string> > AtomResidueName;
+    1225             : 
+    1226          10 :   atoms_masses.resize(atoms.size());
+    1227          10 :   residue_atom.resize(atoms.size());
+    1228             : 
+    1229             :   // cycle over chains
+    1230          24 :   for(unsigned i=0; i<chains.size(); ++i) {
+    1231             :     unsigned start, end;
+    1232             :     std::string errmsg;
+    1233          14 :     pdb.getResidueRange(chains[i], start, end, errmsg);
+    1234          14 :     AtomResidueName.resize(2);
+    1235             :     // cycle over residues
+    1236        2110 :     for(unsigned res=start; res<=end; res++) {
+    1237        2096 :       std::string Rname = pdb.getResidueName(res, chains[i]);
+    1238        2096 :       Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    1239        2096 :       std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(res, chains[i]);
+    1240             :       unsigned first_time=1;
+    1241        2096 :       std::vector<std::vector<unsigned> > tmp_residue_atom; tmp_residue_atom.resize(3);
+    1242             :       // cycle over atoms
+    1243       37562 :       for(unsigned a=0; a<res_atoms.size(); a++) {
+    1244             :         // operations shared among all beads
+    1245       35466 :         std::string Aname=pdb.getAtomName(res_atoms[a]);
+    1246       35466 :         AtomResidueName[0].push_back(Aname);
+    1247       35466 :         AtomResidueName[1].push_back(Rname);
+    1248             :         char type;
+    1249       35466 :         char first = Aname.at(0);
+    1250             :         // We assume that element symbol is first letter, if not a number
+    1251       35466 :         if (!isdigit(first)) {
+    1252             :           type = first;
+    1253             :           // otherwise is the second
+    1254             :         } else {
+    1255           0 :           type = Aname.at(1);
+    1256             :         }
+    1257       35466 :         if (type == 'H') atoms_masses[res_atoms[a].index()] = 1.008;
+    1258       10384 :         else if(type == 'C') atoms_masses[res_atoms[a].index()] = 12.011;
+    1259        2772 :         else if(type == 'N') atoms_masses[res_atoms[a].index()] = 14.007;
+    1260        3270 :         else if(type == 'O') atoms_masses[res_atoms[a].index()] = 15.999;
+    1261          90 :         else if(type == 'S') atoms_masses[res_atoms[a].index()] = 32.065;
+    1262          32 :         else if(type == 'P') atoms_masses[res_atoms[a].index()] = 30.974;
+    1263             :         else {
+    1264           0 :           error("Unknown element in mass extraction\n");
+    1265             :         }
+    1266       70932 :         if(pdb.allowedResidue("protein",Rname)) {
+    1267       34390 :           if(first_time) {
+    1268        2060 :             atoms_per_bead.push_back(res_atoms.size());
+    1269             :             first_time = 0;
+    1270             :           }
+    1271       34390 :           residue_atom[res_atoms[a].index()] = atoms_per_bead.size()-1;
+    1272             :         } else {
+    1273             :           // check for nucleic acids
+    1274             :           // Pentose bead
+    1275        4840 :           if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  || Aname=="O3'"  ||
+    1276        3940 :               Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  || Aname=="C1'"  || Aname=="H5'"  ||
+    1277        3076 :               Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  || Aname=="H2'"  || Aname=="H2''" ||
+    1278        2660 :               Aname=="H2'2" || Aname=="H1'"  || Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" ||
+    1279        3536 :               Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T"  ||
+    1280             :               Aname=="H3T" ) {
+    1281         584 :             tmp_residue_atom[0].push_back(res_atoms[a].index());
+    1282             :           }
+    1283             :           // Nucleobase bead
+    1284        2172 :           else if(Aname=="N1"  || Aname=="N2"  || Aname=="N3"  || Aname=="N4"  || Aname=="N6"  ||
+    1285        1884 :                   Aname=="N7"  || Aname=="N9"  || Aname=="C2"  || Aname=="C4"  || Aname=="C5"  ||
+    1286        1272 :                   Aname=="C6"  || Aname=="C7"  || Aname=="C8"  || Aname=="O2"  || Aname=="O4"  ||
+    1287         912 :                   Aname=="O6"  || Aname=="H1"  || Aname=="H2"  || Aname=="H3"  || Aname=="H5"  ||
+    1288         480 :                   Aname=="H6"  || Aname=="H8"  || Aname=="H21" || Aname=="H22" || Aname=="H41" ||
+    1289         972 :                   Aname=="H42" || Aname=="H61" || Aname=="H62" || Aname=="H71" || Aname=="H72" ||
+    1290             :                   Aname=="H73" ) {
+    1291         396 :             tmp_residue_atom[1].push_back(res_atoms[a].index());
+    1292             :           }
+    1293             :           // PO2 bead
+    1294          96 :           else if(Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" || Aname=="O1P" ||
+    1295          96 :                   Aname=="O2P" || Aname=="O3P" ) {
+    1296          96 :             tmp_residue_atom[2].push_back(res_atoms[a].index());
+    1297             :           }
+    1298             :           // error
+    1299           0 :           else error("Atom name "+Aname+" cannot be indexed to any bead. Check the PDB.");
+    1300             :         }
+    1301             :       }
+    1302        4192 :       if(!pdb.allowedResidue("protein",Rname)) {
+    1303          36 :         atoms_per_bead.push_back(tmp_residue_atom[0].size());
+    1304         620 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[0].size(); tmp_i++) residue_atom[tmp_residue_atom[0][tmp_i]]=atoms_per_bead.size()-1;
+    1305          36 :         atoms_per_bead.push_back(tmp_residue_atom[1].size());
+    1306         432 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[1].size(); tmp_i++) residue_atom[tmp_residue_atom[1][tmp_i]]=atoms_per_bead.size()-1;
+    1307          36 :         if(tmp_residue_atom[2].size()>0) {
+    1308          32 :           atoms_per_bead.push_back(tmp_residue_atom[2].size());
+    1309         128 :           for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[2].size(); tmp_i++) residue_atom[tmp_residue_atom[2][tmp_i]]=atoms_per_bead.size()-1;
+    1310             :         }
+    1311             :       }
+    1312        2096 :     }
+    1313             :   }
+    1314          10 :   readLCPOparam(AtomResidueName, atoms.size());
+    1315          10 :   return atoms_per_bead.size();
+    1316          10 : }
+    1317             : 
+    1318           8 : void SAXS::getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter)
+    1319             : {
+    1320           8 :   parameter[ALA_BB].push_back(9.045);
+    1321           8 :   parameter[ALA_BB].push_back(-0.098114);
+    1322           8 :   parameter[ALA_BB].push_back(7.54281);
+    1323           8 :   parameter[ALA_BB].push_back(-1.97438);
+    1324           8 :   parameter[ALA_BB].push_back(-8.32689);
+    1325           8 :   parameter[ALA_BB].push_back(6.09318);
+    1326           8 :   parameter[ALA_BB].push_back(-1.18913);
+    1327             : 
+    1328           8 :   parameter[ARG_BB].push_back(10.729);
+    1329           8 :   parameter[ARG_BB].push_back(-0.0392574);
+    1330           8 :   parameter[ARG_BB].push_back(1.15382);
+    1331           8 :   parameter[ARG_BB].push_back(-0.155999);
+    1332           8 :   parameter[ARG_BB].push_back(-2.43619);
+    1333           8 :   parameter[ARG_BB].push_back(1.72922);
+    1334           8 :   parameter[ARG_BB].push_back(-0.33799);
+    1335             : 
+    1336           8 :   parameter[ARG_SC1].push_back(-2.796);
+    1337           8 :   parameter[ARG_SC1].push_back(0.472403);
+    1338           8 :   parameter[ARG_SC1].push_back(8.07424);
+    1339           8 :   parameter[ARG_SC1].push_back(4.37299);
+    1340           8 :   parameter[ARG_SC1].push_back(-10.7398);
+    1341           8 :   parameter[ARG_SC1].push_back(4.95677);
+    1342           8 :   parameter[ARG_SC1].push_back(-0.725797);
+    1343             : 
+    1344           8 :   parameter[ARG_SC2].push_back(15.396);
+    1345           8 :   parameter[ARG_SC2].push_back(0.0636736);
+    1346           8 :   parameter[ARG_SC2].push_back(-1.258);
+    1347           8 :   parameter[ARG_SC2].push_back(1.93135);
+    1348           8 :   parameter[ARG_SC2].push_back(-4.45031);
+    1349           8 :   parameter[ARG_SC2].push_back(2.49356);
+    1350           8 :   parameter[ARG_SC2].push_back(-0.410721);
+    1351             : 
+    1352           8 :   parameter[ASN_BB].push_back(10.738);
+    1353           8 :   parameter[ASN_BB].push_back(-0.0402162);
+    1354           8 :   parameter[ASN_BB].push_back(1.03007);
+    1355           8 :   parameter[ASN_BB].push_back(-0.254174);
+    1356           8 :   parameter[ASN_BB].push_back(-2.12015);
+    1357           8 :   parameter[ASN_BB].push_back(1.55535);
+    1358           8 :   parameter[ASN_BB].push_back(-0.30963);
+    1359             : 
+    1360           8 :   parameter[ASN_SC1].push_back(9.249);
+    1361           8 :   parameter[ASN_SC1].push_back(-0.0148678);
+    1362           8 :   parameter[ASN_SC1].push_back(5.52169);
+    1363           8 :   parameter[ASN_SC1].push_back(0.00853212);
+    1364           8 :   parameter[ASN_SC1].push_back(-6.71992);
+    1365           8 :   parameter[ASN_SC1].push_back(3.93622);
+    1366           8 :   parameter[ASN_SC1].push_back(-0.64973);
+    1367             : 
+    1368           8 :   parameter[ASP_BB].push_back(10.695);
+    1369           8 :   parameter[ASP_BB].push_back(-0.0410247);
+    1370           8 :   parameter[ASP_BB].push_back(1.03656);
+    1371           8 :   parameter[ASP_BB].push_back(-0.298558);
+    1372           8 :   parameter[ASP_BB].push_back(-2.06064);
+    1373           8 :   parameter[ASP_BB].push_back(1.53495);
+    1374           8 :   parameter[ASP_BB].push_back(-0.308365);
+    1375             : 
+    1376           8 :   parameter[ASP_SC1].push_back(9.476);
+    1377           8 :   parameter[ASP_SC1].push_back(-0.0254664);
+    1378           8 :   parameter[ASP_SC1].push_back(5.57899);
+    1379           8 :   parameter[ASP_SC1].push_back(-0.395027);
+    1380           8 :   parameter[ASP_SC1].push_back(-5.9407);
+    1381           8 :   parameter[ASP_SC1].push_back(3.48836);
+    1382           8 :   parameter[ASP_SC1].push_back(-0.569402);
+    1383             : 
+    1384           8 :   parameter[CYS_BB].push_back(10.698);
+    1385           8 :   parameter[CYS_BB].push_back(-0.0233493);
+    1386           8 :   parameter[CYS_BB].push_back(1.18257);
+    1387           8 :   parameter[CYS_BB].push_back(0.0684464);
+    1388           8 :   parameter[CYS_BB].push_back(-2.792);
+    1389           8 :   parameter[CYS_BB].push_back(1.88995);
+    1390           8 :   parameter[CYS_BB].push_back(-0.360229);
+    1391             : 
+    1392           8 :   parameter[CYS_SC1].push_back(8.199);
+    1393           8 :   parameter[CYS_SC1].push_back(-0.0261569);
+    1394           8 :   parameter[CYS_SC1].push_back(6.79677);
+    1395           8 :   parameter[CYS_SC1].push_back(-0.343845);
+    1396           8 :   parameter[CYS_SC1].push_back(-5.03578);
+    1397           8 :   parameter[CYS_SC1].push_back(2.7076);
+    1398           8 :   parameter[CYS_SC1].push_back(-0.420714);
+    1399             : 
+    1400           8 :   parameter[GLN_BB].push_back(10.728);
+    1401           8 :   parameter[GLN_BB].push_back(-0.0391984);
+    1402           8 :   parameter[GLN_BB].push_back(1.09264);
+    1403           8 :   parameter[GLN_BB].push_back(-0.261555);
+    1404           8 :   parameter[GLN_BB].push_back(-2.21245);
+    1405           8 :   parameter[GLN_BB].push_back(1.62071);
+    1406           8 :   parameter[GLN_BB].push_back(-0.322325);
+    1407             : 
+    1408           8 :   parameter[GLN_SC1].push_back(8.317);
+    1409           8 :   parameter[GLN_SC1].push_back(-0.229045);
+    1410           8 :   parameter[GLN_SC1].push_back(12.6338);
+    1411           8 :   parameter[GLN_SC1].push_back(-7.6719);
+    1412           8 :   parameter[GLN_SC1].push_back(-5.8376);
+    1413           8 :   parameter[GLN_SC1].push_back(5.53784);
+    1414           8 :   parameter[GLN_SC1].push_back(-1.12604);
+    1415             : 
+    1416           8 :   parameter[GLU_BB].push_back(10.694);
+    1417           8 :   parameter[GLU_BB].push_back(-0.0521961);
+    1418           8 :   parameter[GLU_BB].push_back(1.11153);
+    1419           8 :   parameter[GLU_BB].push_back(-0.491995);
+    1420           8 :   parameter[GLU_BB].push_back(-1.86236);
+    1421           8 :   parameter[GLU_BB].push_back(1.45332);
+    1422           8 :   parameter[GLU_BB].push_back(-0.29708);
+    1423             : 
+    1424           8 :   parameter[GLU_SC1].push_back(8.544);
+    1425           8 :   parameter[GLU_SC1].push_back(-0.249555);
+    1426           8 :   parameter[GLU_SC1].push_back(12.8031);
+    1427           8 :   parameter[GLU_SC1].push_back(-8.42696);
+    1428           8 :   parameter[GLU_SC1].push_back(-4.66486);
+    1429           8 :   parameter[GLU_SC1].push_back(4.90004);
+    1430           8 :   parameter[GLU_SC1].push_back(-1.01204);
+    1431             : 
+    1432           8 :   parameter[GLY_BB].push_back(9.977);
+    1433           8 :   parameter[GLY_BB].push_back(-0.0285799);
+    1434           8 :   parameter[GLY_BB].push_back(1.84236);
+    1435           8 :   parameter[GLY_BB].push_back(-0.0315192);
+    1436           8 :   parameter[GLY_BB].push_back(-2.88326);
+    1437           8 :   parameter[GLY_BB].push_back(1.87323);
+    1438           8 :   parameter[GLY_BB].push_back(-0.345773);
+    1439             : 
+    1440           8 :   parameter[HIS_BB].push_back(10.721);
+    1441           8 :   parameter[HIS_BB].push_back(-0.0379337);
+    1442           8 :   parameter[HIS_BB].push_back(1.06028);
+    1443           8 :   parameter[HIS_BB].push_back(-0.236143);
+    1444           8 :   parameter[HIS_BB].push_back(-2.17819);
+    1445           8 :   parameter[HIS_BB].push_back(1.58357);
+    1446           8 :   parameter[HIS_BB].push_back(-0.31345);
+    1447             : 
+    1448           8 :   parameter[HIS_SC1].push_back(-0.424);
+    1449           8 :   parameter[HIS_SC1].push_back(0.665176);
+    1450           8 :   parameter[HIS_SC1].push_back(3.4369);
+    1451           8 :   parameter[HIS_SC1].push_back(2.93795);
+    1452           8 :   parameter[HIS_SC1].push_back(-5.18288);
+    1453           8 :   parameter[HIS_SC1].push_back(2.12381);
+    1454           8 :   parameter[HIS_SC1].push_back(-0.284224);
+    1455             : 
+    1456           8 :   parameter[HIS_SC2].push_back(5.363);
+    1457           8 :   parameter[HIS_SC2].push_back(-0.0176945);
+    1458           8 :   parameter[HIS_SC2].push_back(2.9506);
+    1459           8 :   parameter[HIS_SC2].push_back(-0.387018);
+    1460           8 :   parameter[HIS_SC2].push_back(-1.83951);
+    1461           8 :   parameter[HIS_SC2].push_back(0.9703);
+    1462           8 :   parameter[HIS_SC2].push_back(-0.1458);
+    1463             : 
+    1464           8 :   parameter[HIS_SC3].push_back(5.784);
+    1465           8 :   parameter[HIS_SC3].push_back(-0.0293129);
+    1466           8 :   parameter[HIS_SC3].push_back(2.74167);
+    1467           8 :   parameter[HIS_SC3].push_back(-0.520875);
+    1468           8 :   parameter[HIS_SC3].push_back(-1.62949);
+    1469           8 :   parameter[HIS_SC3].push_back(0.902379);
+    1470           8 :   parameter[HIS_SC3].push_back(-0.139957);
+    1471             : 
+    1472           8 :   parameter[ILE_BB].push_back(10.699);
+    1473           8 :   parameter[ILE_BB].push_back(-0.0188962);
+    1474           8 :   parameter[ILE_BB].push_back(1.217);
+    1475           8 :   parameter[ILE_BB].push_back(0.242481);
+    1476           8 :   parameter[ILE_BB].push_back(-3.13898);
+    1477           8 :   parameter[ILE_BB].push_back(2.07916);
+    1478           8 :   parameter[ILE_BB].push_back(-0.392574);
+    1479             : 
+    1480           8 :   parameter[ILE_SC1].push_back(-4.448);
+    1481           8 :   parameter[ILE_SC1].push_back(1.20996);
+    1482           8 :   parameter[ILE_SC1].push_back(11.5141);
+    1483           8 :   parameter[ILE_SC1].push_back(6.98895);
+    1484           8 :   parameter[ILE_SC1].push_back(-19.1948);
+    1485           8 :   parameter[ILE_SC1].push_back(9.89207);
+    1486           8 :   parameter[ILE_SC1].push_back(-1.60877);
+    1487             : 
+    1488           8 :   parameter[LEU_BB].push_back(10.692);
+    1489           8 :   parameter[LEU_BB].push_back(-0.0414917);
+    1490           8 :   parameter[LEU_BB].push_back(1.1077);
+    1491           8 :   parameter[LEU_BB].push_back(-0.288062);
+    1492           8 :   parameter[LEU_BB].push_back(-2.17187);
+    1493           8 :   parameter[LEU_BB].push_back(1.59879);
+    1494           8 :   parameter[LEU_BB].push_back(-0.318545);
+    1495             : 
+    1496           8 :   parameter[LEU_SC1].push_back(-4.448);
+    1497           8 :   parameter[LEU_SC1].push_back(2.1063);
+    1498           8 :   parameter[LEU_SC1].push_back(6.72381);
+    1499           8 :   parameter[LEU_SC1].push_back(14.6954);
+    1500           8 :   parameter[LEU_SC1].push_back(-23.7197);
+    1501           8 :   parameter[LEU_SC1].push_back(10.7247);
+    1502           8 :   parameter[LEU_SC1].push_back(-1.59146);
+    1503             : 
+    1504           8 :   parameter[LYS_BB].push_back(10.706);
+    1505           8 :   parameter[LYS_BB].push_back(-0.0468629);
+    1506           8 :   parameter[LYS_BB].push_back(1.09477);
+    1507           8 :   parameter[LYS_BB].push_back(-0.432751);
+    1508           8 :   parameter[LYS_BB].push_back(-1.94335);
+    1509           8 :   parameter[LYS_BB].push_back(1.49109);
+    1510           8 :   parameter[LYS_BB].push_back(-0.302589);
+    1511             : 
+    1512           8 :   parameter[LYS_SC1].push_back(-2.796);
+    1513           8 :   parameter[LYS_SC1].push_back(0.508044);
+    1514           8 :   parameter[LYS_SC1].push_back(7.91436);
+    1515           8 :   parameter[LYS_SC1].push_back(4.54097);
+    1516           8 :   parameter[LYS_SC1].push_back(-10.8051);
+    1517           8 :   parameter[LYS_SC1].push_back(4.96204);
+    1518           8 :   parameter[LYS_SC1].push_back(-0.724414);
+    1519             : 
+    1520           8 :   parameter[LYS_SC2].push_back(3.070);
+    1521           8 :   parameter[LYS_SC2].push_back(-0.0101448);
+    1522           8 :   parameter[LYS_SC2].push_back(4.67994);
+    1523           8 :   parameter[LYS_SC2].push_back(-0.792529);
+    1524           8 :   parameter[LYS_SC2].push_back(-2.09142);
+    1525           8 :   parameter[LYS_SC2].push_back(1.02933);
+    1526           8 :   parameter[LYS_SC2].push_back(-0.137787);
+    1527             : 
+    1528           8 :   parameter[MET_BB].push_back(10.671);
+    1529           8 :   parameter[MET_BB].push_back(-0.0433724);
+    1530           8 :   parameter[MET_BB].push_back(1.13784);
+    1531           8 :   parameter[MET_BB].push_back(-0.40768);
+    1532           8 :   parameter[MET_BB].push_back(-2.00555);
+    1533           8 :   parameter[MET_BB].push_back(1.51673);
+    1534           8 :   parameter[MET_BB].push_back(-0.305547);
+    1535             : 
+    1536           8 :   parameter[MET_SC1].push_back(5.85);
+    1537           8 :   parameter[MET_SC1].push_back(-0.0485798);
+    1538           8 :   parameter[MET_SC1].push_back(17.0391);
+    1539           8 :   parameter[MET_SC1].push_back(-3.65327);
+    1540           8 :   parameter[MET_SC1].push_back(-13.174);
+    1541           8 :   parameter[MET_SC1].push_back(8.68286);
+    1542           8 :   parameter[MET_SC1].push_back(-1.56095);
+    1543             : 
+    1544           8 :   parameter[PHE_BB].push_back(10.741);
+    1545           8 :   parameter[PHE_BB].push_back(-0.0317275);
+    1546           8 :   parameter[PHE_BB].push_back(1.15599);
+    1547           8 :   parameter[PHE_BB].push_back(0.0276187);
+    1548           8 :   parameter[PHE_BB].push_back(-2.74757);
+    1549           8 :   parameter[PHE_BB].push_back(1.88783);
+    1550           8 :   parameter[PHE_BB].push_back(-0.363525);
+    1551             : 
+    1552           8 :   parameter[PHE_SC1].push_back(-0.636);
+    1553           8 :   parameter[PHE_SC1].push_back(0.527882);
+    1554           8 :   parameter[PHE_SC1].push_back(6.77612);
+    1555           8 :   parameter[PHE_SC1].push_back(3.18508);
+    1556           8 :   parameter[PHE_SC1].push_back(-8.92826);
+    1557           8 :   parameter[PHE_SC1].push_back(4.29752);
+    1558           8 :   parameter[PHE_SC1].push_back(-0.65187);
+    1559             : 
+    1560           8 :   parameter[PHE_SC2].push_back(-0.424);
+    1561           8 :   parameter[PHE_SC2].push_back(0.389174);
+    1562           8 :   parameter[PHE_SC2].push_back(4.11761);
+    1563           8 :   parameter[PHE_SC2].push_back(2.29527);
+    1564           8 :   parameter[PHE_SC2].push_back(-4.7652);
+    1565           8 :   parameter[PHE_SC2].push_back(1.97023);
+    1566           8 :   parameter[PHE_SC2].push_back(-0.262318);
+    1567             : 
+    1568           8 :   parameter[PHE_SC3].push_back(-0.424);
+    1569           8 :   parameter[PHE_SC3].push_back(0.38927);
+    1570           8 :   parameter[PHE_SC3].push_back(4.11708);
+    1571           8 :   parameter[PHE_SC3].push_back(2.29623);
+    1572           8 :   parameter[PHE_SC3].push_back(-4.76592);
+    1573           8 :   parameter[PHE_SC3].push_back(1.97055);
+    1574           8 :   parameter[PHE_SC3].push_back(-0.262381);
+    1575             : 
+    1576           8 :   parameter[PRO_BB].push_back(11.434);
+    1577           8 :   parameter[PRO_BB].push_back(-0.033323);
+    1578           8 :   parameter[PRO_BB].push_back(0.472014);
+    1579           8 :   parameter[PRO_BB].push_back(-0.290854);
+    1580           8 :   parameter[PRO_BB].push_back(-1.81409);
+    1581           8 :   parameter[PRO_BB].push_back(1.39751);
+    1582           8 :   parameter[PRO_BB].push_back(-0.280407);
+    1583             : 
+    1584           8 :   parameter[PRO_SC1].push_back(-2.796);
+    1585           8 :   parameter[PRO_SC1].push_back(0.95668);
+    1586           8 :   parameter[PRO_SC1].push_back(6.84197);
+    1587           8 :   parameter[PRO_SC1].push_back(6.43774);
+    1588           8 :   parameter[PRO_SC1].push_back(-12.5068);
+    1589           8 :   parameter[PRO_SC1].push_back(5.64597);
+    1590           8 :   parameter[PRO_SC1].push_back(-0.825206);
+    1591             : 
+    1592           8 :   parameter[SER_BB].push_back(10.699);
+    1593           8 :   parameter[SER_BB].push_back(-0.0325828);
+    1594           8 :   parameter[SER_BB].push_back(1.20329);
+    1595           8 :   parameter[SER_BB].push_back(-0.0674351);
+    1596           8 :   parameter[SER_BB].push_back(-2.60749);
+    1597           8 :   parameter[SER_BB].push_back(1.80318);
+    1598           8 :   parameter[SER_BB].push_back(-0.346803);
+    1599             : 
+    1600           8 :   parameter[SER_SC1].push_back(3.298);
+    1601           8 :   parameter[SER_SC1].push_back(-0.0366801);
+    1602           8 :   parameter[SER_SC1].push_back(5.11077);
+    1603           8 :   parameter[SER_SC1].push_back(-1.46774);
+    1604           8 :   parameter[SER_SC1].push_back(-1.48421);
+    1605           8 :   parameter[SER_SC1].push_back(0.800326);
+    1606           8 :   parameter[SER_SC1].push_back(-0.108314);
+    1607             : 
+    1608           8 :   parameter[THR_BB].push_back(10.697);
+    1609           8 :   parameter[THR_BB].push_back(-0.0242955);
+    1610           8 :   parameter[THR_BB].push_back(1.24671);
+    1611           8 :   parameter[THR_BB].push_back(0.146423);
+    1612           8 :   parameter[THR_BB].push_back(-2.97429);
+    1613           8 :   parameter[THR_BB].push_back(1.97513);
+    1614           8 :   parameter[THR_BB].push_back(-0.371479);
+    1615             : 
+    1616           8 :   parameter[THR_SC1].push_back(2.366);
+    1617           8 :   parameter[THR_SC1].push_back(0.0297604);
+    1618           8 :   parameter[THR_SC1].push_back(11.9216);
+    1619           8 :   parameter[THR_SC1].push_back(-9.32503);
+    1620           8 :   parameter[THR_SC1].push_back(1.9396);
+    1621           8 :   parameter[THR_SC1].push_back(0.0804861);
+    1622           8 :   parameter[THR_SC1].push_back(-0.0302721);
+    1623             : 
+    1624           8 :   parameter[TRP_BB].push_back(10.689);
+    1625           8 :   parameter[TRP_BB].push_back(-0.0265879);
+    1626           8 :   parameter[TRP_BB].push_back(1.17819);
+    1627           8 :   parameter[TRP_BB].push_back(0.0386457);
+    1628           8 :   parameter[TRP_BB].push_back(-2.75634);
+    1629           8 :   parameter[TRP_BB].push_back(1.88065);
+    1630           8 :   parameter[TRP_BB].push_back(-0.360217);
+    1631             : 
+    1632           8 :   parameter[TRP_SC1].push_back(0.084);
+    1633           8 :   parameter[TRP_SC1].push_back(0.752407);
+    1634           8 :   parameter[TRP_SC1].push_back(5.3802);
+    1635           8 :   parameter[TRP_SC1].push_back(4.09281);
+    1636           8 :   parameter[TRP_SC1].push_back(-9.28029);
+    1637           8 :   parameter[TRP_SC1].push_back(4.45923);
+    1638           8 :   parameter[TRP_SC1].push_back(-0.689008);
+    1639             : 
+    1640           8 :   parameter[TRP_SC2].push_back(5.739);
+    1641           8 :   parameter[TRP_SC2].push_back(0.0298492);
+    1642           8 :   parameter[TRP_SC2].push_back(4.60446);
+    1643           8 :   parameter[TRP_SC2].push_back(1.34463);
+    1644           8 :   parameter[TRP_SC2].push_back(-5.69968);
+    1645           8 :   parameter[TRP_SC2].push_back(2.84924);
+    1646           8 :   parameter[TRP_SC2].push_back(-0.433781);
+    1647             : 
+    1648           8 :   parameter[TRP_SC3].push_back(-0.424);
+    1649           8 :   parameter[TRP_SC3].push_back(0.388576);
+    1650           8 :   parameter[TRP_SC3].push_back(4.11859);
+    1651           8 :   parameter[TRP_SC3].push_back(2.29485);
+    1652           8 :   parameter[TRP_SC3].push_back(-4.76255);
+    1653           8 :   parameter[TRP_SC3].push_back(1.96849);
+    1654           8 :   parameter[TRP_SC3].push_back(-0.262015);
+    1655             : 
+    1656           8 :   parameter[TRP_SC4].push_back(-0.424);
+    1657           8 :   parameter[TRP_SC4].push_back(0.387685);
+    1658           8 :   parameter[TRP_SC4].push_back(4.12153);
+    1659           8 :   parameter[TRP_SC4].push_back(2.29144);
+    1660           8 :   parameter[TRP_SC4].push_back(-4.7589);
+    1661           8 :   parameter[TRP_SC4].push_back(1.96686);
+    1662           8 :   parameter[TRP_SC4].push_back(-0.261786);
+    1663             : 
+    1664           8 :   parameter[TYR_BB].push_back(10.689);
+    1665           8 :   parameter[TYR_BB].push_back(-0.0193526);
+    1666           8 :   parameter[TYR_BB].push_back(1.18241);
+    1667           8 :   parameter[TYR_BB].push_back(0.207318);
+    1668           8 :   parameter[TYR_BB].push_back(-3.0041);
+    1669           8 :   parameter[TYR_BB].push_back(1.99335);
+    1670           8 :   parameter[TYR_BB].push_back(-0.376482);
+    1671             : 
+    1672           8 :   parameter[TYR_SC1].push_back(-0.636);
+    1673           8 :   parameter[TYR_SC1].push_back(0.528902);
+    1674           8 :   parameter[TYR_SC1].push_back(6.78168);
+    1675           8 :   parameter[TYR_SC1].push_back(3.17769);
+    1676           8 :   parameter[TYR_SC1].push_back(-8.93667);
+    1677           8 :   parameter[TYR_SC1].push_back(4.30692);
+    1678           8 :   parameter[TYR_SC1].push_back(-0.653993);
+    1679             : 
+    1680           8 :   parameter[TYR_SC2].push_back(-0.424);
+    1681           8 :   parameter[TYR_SC2].push_back(0.388811);
+    1682           8 :   parameter[TYR_SC2].push_back(4.11851);
+    1683           8 :   parameter[TYR_SC2].push_back(2.29545);
+    1684           8 :   parameter[TYR_SC2].push_back(-4.7668);
+    1685           8 :   parameter[TYR_SC2].push_back(1.97131);
+    1686           8 :   parameter[TYR_SC2].push_back(-0.262534);
+    1687             : 
+    1688           8 :   parameter[TYR_SC3].push_back(4.526);
+    1689           8 :   parameter[TYR_SC3].push_back(-0.00381305);
+    1690           8 :   parameter[TYR_SC3].push_back(5.8567);
+    1691           8 :   parameter[TYR_SC3].push_back(-0.214086);
+    1692           8 :   parameter[TYR_SC3].push_back(-4.63649);
+    1693           8 :   parameter[TYR_SC3].push_back(2.52869);
+    1694           8 :   parameter[TYR_SC3].push_back(-0.39894);
+    1695             : 
+    1696           8 :   parameter[VAL_BB].push_back(10.691);
+    1697           8 :   parameter[VAL_BB].push_back(-0.0162929);
+    1698           8 :   parameter[VAL_BB].push_back(1.24446);
+    1699           8 :   parameter[VAL_BB].push_back(0.307914);
+    1700           8 :   parameter[VAL_BB].push_back(-3.27446);
+    1701           8 :   parameter[VAL_BB].push_back(2.14788);
+    1702           8 :   parameter[VAL_BB].push_back(-0.403259);
+    1703             : 
+    1704           8 :   parameter[VAL_SC1].push_back(-3.516);
+    1705           8 :   parameter[VAL_SC1].push_back(1.62307);
+    1706           8 :   parameter[VAL_SC1].push_back(5.43064);
+    1707           8 :   parameter[VAL_SC1].push_back(9.28809);
+    1708           8 :   parameter[VAL_SC1].push_back(-14.9927);
+    1709           8 :   parameter[VAL_SC1].push_back(6.6133);
+    1710           8 :   parameter[VAL_SC1].push_back(-0.964977);
+    1711             : 
+    1712           8 :   parameter[A_BB1].push_back(32.88500000);
+    1713           8 :   parameter[A_BB1].push_back(0.08339900);
+    1714           8 :   parameter[A_BB1].push_back(-7.36054400);
+    1715           8 :   parameter[A_BB1].push_back(2.19220300);
+    1716           8 :   parameter[A_BB1].push_back(-3.56523400);
+    1717           8 :   parameter[A_BB1].push_back(2.33326900);
+    1718           8 :   parameter[A_BB1].push_back(-0.39785500);
+    1719             : 
+    1720           8 :   parameter[A_BB2].push_back(3.80600000);
+    1721           8 :   parameter[A_BB2].push_back(-0.10727600);
+    1722           8 :   parameter[A_BB2].push_back(9.58854100);
+    1723           8 :   parameter[A_BB2].push_back(-6.23740500);
+    1724           8 :   parameter[A_BB2].push_back(-0.48267300);
+    1725           8 :   parameter[A_BB2].push_back(1.14119500);
+    1726           8 :   parameter[A_BB2].push_back(-0.21385600);
+    1727             : 
+    1728           8 :   parameter[A_BB3].push_back(3.59400000);
+    1729           8 :   parameter[A_BB3].push_back(0.04537300);
+    1730           8 :   parameter[A_BB3].push_back(9.59178900);
+    1731           8 :   parameter[A_BB3].push_back(-1.29202200);
+    1732           8 :   parameter[A_BB3].push_back(-7.10851000);
+    1733           8 :   parameter[A_BB3].push_back(4.05571200);
+    1734           8 :   parameter[A_BB3].push_back(-0.63372500);
+    1735             : 
+    1736           8 :   parameter[A_SC1].push_back(6.67100000);
+    1737           8 :   parameter[A_SC1].push_back(-0.00855300);
+    1738           8 :   parameter[A_SC1].push_back(1.63222400);
+    1739           8 :   parameter[A_SC1].push_back(-0.06466200);
+    1740           8 :   parameter[A_SC1].push_back(-1.48694200);
+    1741           8 :   parameter[A_SC1].push_back(0.78544600);
+    1742           8 :   parameter[A_SC1].push_back(-0.12083500);
+    1743             : 
+    1744           8 :   parameter[A_SC2].push_back(5.95100000);
+    1745           8 :   parameter[A_SC2].push_back(-0.02606600);
+    1746           8 :   parameter[A_SC2].push_back(2.54399900);
+    1747           8 :   parameter[A_SC2].push_back(-0.48436900);
+    1748           8 :   parameter[A_SC2].push_back(-1.55357400);
+    1749           8 :   parameter[A_SC2].push_back(0.86466900);
+    1750           8 :   parameter[A_SC2].push_back(-0.13509000);
+    1751             : 
+    1752           8 :   parameter[A_SC3].push_back(11.39400000);
+    1753           8 :   parameter[A_SC3].push_back(0.00871300);
+    1754           8 :   parameter[A_SC3].push_back(-0.23891300);
+    1755           8 :   parameter[A_SC3].push_back(0.48919400);
+    1756           8 :   parameter[A_SC3].push_back(-1.75289400);
+    1757           8 :   parameter[A_SC3].push_back(0.99267500);
+    1758           8 :   parameter[A_SC3].push_back(-0.16291300);
+    1759             : 
+    1760           8 :   parameter[A_SC4].push_back(6.45900000);
+    1761           8 :   parameter[A_SC4].push_back(0.01990600);
+    1762           8 :   parameter[A_SC4].push_back(4.17970400);
+    1763           8 :   parameter[A_SC4].push_back(0.97629900);
+    1764           8 :   parameter[A_SC4].push_back(-5.03297800);
+    1765           8 :   parameter[A_SC4].push_back(2.55576700);
+    1766           8 :   parameter[A_SC4].push_back(-0.39150500);
+    1767             : 
+    1768           8 :   parameter[A_3TE].push_back(4.23000000);
+    1769           8 :   parameter[A_3TE].push_back(0.00064800);
+    1770           8 :   parameter[A_3TE].push_back(0.92124600);
+    1771           8 :   parameter[A_3TE].push_back(0.08064300);
+    1772           8 :   parameter[A_3TE].push_back(-0.39054400);
+    1773           8 :   parameter[A_3TE].push_back(0.12429100);
+    1774           8 :   parameter[A_3TE].push_back(-0.01122700);
+    1775             : 
+    1776           8 :   parameter[A_5TE].push_back(4.23000000);
+    1777           8 :   parameter[A_5TE].push_back(0.00039300);
+    1778           8 :   parameter[A_5TE].push_back(0.92305100);
+    1779           8 :   parameter[A_5TE].push_back(0.07747500);
+    1780           8 :   parameter[A_5TE].push_back(-0.38792100);
+    1781           8 :   parameter[A_5TE].push_back(0.12323800);
+    1782           8 :   parameter[A_5TE].push_back(-0.01106600);
+    1783             : 
+    1784           8 :   parameter[A_TE3].push_back(7.82400000);
+    1785           8 :   parameter[A_TE3].push_back(-0.04881000);
+    1786           8 :   parameter[A_TE3].push_back(8.21557900);
+    1787           8 :   parameter[A_TE3].push_back(-0.89491400);
+    1788           8 :   parameter[A_TE3].push_back(-9.54293700);
+    1789           8 :   parameter[A_TE3].push_back(6.33122200);
+    1790           8 :   parameter[A_TE3].push_back(-1.16672900);
+    1791             : 
+    1792           8 :   parameter[A_TE5].push_back(8.03600000);
+    1793           8 :   parameter[A_TE5].push_back(0.01641200);
+    1794           8 :   parameter[A_TE5].push_back(5.14902200);
+    1795           8 :   parameter[A_TE5].push_back(0.83419700);
+    1796           8 :   parameter[A_TE5].push_back(-7.59068300);
+    1797           8 :   parameter[A_TE5].push_back(4.52063200);
+    1798           8 :   parameter[A_TE5].push_back(-0.78260800);
+    1799             : 
+    1800           8 :   parameter[C_BB1].push_back(32.88500000);
+    1801           8 :   parameter[C_BB1].push_back(0.08311100);
+    1802           8 :   parameter[C_BB1].push_back(-7.35432100);
+    1803           8 :   parameter[C_BB1].push_back(2.18610000);
+    1804           8 :   parameter[C_BB1].push_back(-3.55788300);
+    1805           8 :   parameter[C_BB1].push_back(2.32918700);
+    1806           8 :   parameter[C_BB1].push_back(-0.39720000);
+    1807             : 
+    1808           8 :   parameter[C_BB2].push_back(3.80600000);
+    1809           8 :   parameter[C_BB2].push_back(-0.10808100);
+    1810           8 :   parameter[C_BB2].push_back(9.61612600);
+    1811           8 :   parameter[C_BB2].push_back(-6.28595400);
+    1812           8 :   parameter[C_BB2].push_back(-0.45187000);
+    1813           8 :   parameter[C_BB2].push_back(1.13326000);
+    1814           8 :   parameter[C_BB2].push_back(-0.21320300);
+    1815             : 
+    1816           8 :   parameter[C_BB3].push_back(3.59400000);
+    1817           8 :   parameter[C_BB3].push_back(0.04484200);
+    1818           8 :   parameter[C_BB3].push_back(9.61919800);
+    1819           8 :   parameter[C_BB3].push_back(-1.33582800);
+    1820           8 :   parameter[C_BB3].push_back(-7.07200400);
+    1821           8 :   parameter[C_BB3].push_back(4.03952900);
+    1822           8 :   parameter[C_BB3].push_back(-0.63098200);
+    1823             : 
+    1824           8 :   parameter[C_SC1].push_back(5.95100000);
+    1825           8 :   parameter[C_SC1].push_back(-0.02911300);
+    1826           8 :   parameter[C_SC1].push_back(2.59700400);
+    1827           8 :   parameter[C_SC1].push_back(-0.55507700);
+    1828           8 :   parameter[C_SC1].push_back(-1.56344600);
+    1829           8 :   parameter[C_SC1].push_back(0.88956200);
+    1830           8 :   parameter[C_SC1].push_back(-0.14061300);
+    1831             : 
+    1832           8 :   parameter[C_SC2].push_back(11.62100000);
+    1833           8 :   parameter[C_SC2].push_back(0.01366100);
+    1834           8 :   parameter[C_SC2].push_back(-0.25959200);
+    1835           8 :   parameter[C_SC2].push_back(0.48918300);
+    1836           8 :   parameter[C_SC2].push_back(-1.52550500);
+    1837           8 :   parameter[C_SC2].push_back(0.83644100);
+    1838           8 :   parameter[C_SC2].push_back(-0.13407300);
+    1839             : 
+    1840           8 :   parameter[C_SC3].push_back(5.01900000);
+    1841           8 :   parameter[C_SC3].push_back(-0.03276100);
+    1842           8 :   parameter[C_SC3].push_back(5.53776900);
+    1843           8 :   parameter[C_SC3].push_back(-0.95105000);
+    1844           8 :   parameter[C_SC3].push_back(-3.71130800);
+    1845           8 :   parameter[C_SC3].push_back(2.16146000);
+    1846           8 :   parameter[C_SC3].push_back(-0.34918600);
+    1847             : 
+    1848           8 :   parameter[C_3TE].push_back(4.23000000);
+    1849           8 :   parameter[C_3TE].push_back(0.00057300);
+    1850           8 :   parameter[C_3TE].push_back(0.92174800);
+    1851           8 :   parameter[C_3TE].push_back(0.07964500);
+    1852           8 :   parameter[C_3TE].push_back(-0.38965700);
+    1853           8 :   parameter[C_3TE].push_back(0.12392500);
+    1854           8 :   parameter[C_3TE].push_back(-0.01117000);
+    1855             : 
+    1856           8 :   parameter[C_5TE].push_back(4.23000000);
+    1857           8 :   parameter[C_5TE].push_back(0.00071000);
+    1858           8 :   parameter[C_5TE].push_back(0.92082800);
+    1859           8 :   parameter[C_5TE].push_back(0.08150600);
+    1860           8 :   parameter[C_5TE].push_back(-0.39127000);
+    1861           8 :   parameter[C_5TE].push_back(0.12455900);
+    1862           8 :   parameter[C_5TE].push_back(-0.01126300);
+    1863             : 
+    1864           8 :   parameter[C_TE3].push_back(7.82400000);
+    1865           8 :   parameter[C_TE3].push_back(-0.05848300);
+    1866           8 :   parameter[C_TE3].push_back(8.29319900);
+    1867           8 :   parameter[C_TE3].push_back(-1.12563800);
+    1868           8 :   parameter[C_TE3].push_back(-9.42197600);
+    1869           8 :   parameter[C_TE3].push_back(6.35441700);
+    1870           8 :   parameter[C_TE3].push_back(-1.18356900);
+    1871             : 
+    1872           8 :   parameter[C_TE5].push_back(8.03600000);
+    1873           8 :   parameter[C_TE5].push_back(0.00493500);
+    1874           8 :   parameter[C_TE5].push_back(4.92622000);
+    1875           8 :   parameter[C_TE5].push_back(0.64810700);
+    1876           8 :   parameter[C_TE5].push_back(-7.05100000);
+    1877           8 :   parameter[C_TE5].push_back(4.26064400);
+    1878           8 :   parameter[C_TE5].push_back(-0.74819100);
+    1879             : 
+    1880           8 :   parameter[G_BB1].push_back(32.88500000);
+    1881           8 :   parameter[G_BB1].push_back(0.08325400);
+    1882           8 :   parameter[G_BB1].push_back(-7.35736000);
+    1883           8 :   parameter[G_BB1].push_back(2.18914800);
+    1884           8 :   parameter[G_BB1].push_back(-3.56154800);
+    1885           8 :   parameter[G_BB1].push_back(2.33120600);
+    1886           8 :   parameter[G_BB1].push_back(-0.39752300);
+    1887             : 
+    1888           8 :   parameter[G_BB2].push_back(3.80600000);
+    1889           8 :   parameter[G_BB2].push_back(-0.10788300);
+    1890           8 :   parameter[G_BB2].push_back(9.60930800);
+    1891           8 :   parameter[G_BB2].push_back(-6.27402500);
+    1892           8 :   parameter[G_BB2].push_back(-0.46192700);
+    1893           8 :   parameter[G_BB2].push_back(1.13737000);
+    1894           8 :   parameter[G_BB2].push_back(-0.21383100);
+    1895             : 
+    1896           8 :   parameter[G_BB3].push_back(3.59400000);
+    1897           8 :   parameter[G_BB3].push_back(0.04514500);
+    1898           8 :   parameter[G_BB3].push_back(9.61234700);
+    1899           8 :   parameter[G_BB3].push_back(-1.31542100);
+    1900           8 :   parameter[G_BB3].push_back(-7.09150500);
+    1901           8 :   parameter[G_BB3].push_back(4.04706200);
+    1902           8 :   parameter[G_BB3].push_back(-0.63201000);
+    1903             : 
+    1904           8 :   parameter[G_SC1].push_back(6.67100000);
+    1905           8 :   parameter[G_SC1].push_back(-0.00863200);
+    1906           8 :   parameter[G_SC1].push_back(1.63252300);
+    1907           8 :   parameter[G_SC1].push_back(-0.06567200);
+    1908           8 :   parameter[G_SC1].push_back(-1.48680500);
+    1909           8 :   parameter[G_SC1].push_back(0.78565600);
+    1910           8 :   parameter[G_SC1].push_back(-0.12088900);
+    1911             : 
+    1912           8 :   parameter[G_SC2].push_back(11.39400000);
+    1913           8 :   parameter[G_SC2].push_back(0.00912200);
+    1914           8 :   parameter[G_SC2].push_back(-0.22869000);
+    1915           8 :   parameter[G_SC2].push_back(0.49616400);
+    1916           8 :   parameter[G_SC2].push_back(-1.75039000);
+    1917           8 :   parameter[G_SC2].push_back(0.98649200);
+    1918           8 :   parameter[G_SC2].push_back(-0.16141600);
+    1919             : 
+    1920           8 :   parameter[G_SC3].push_back(10.90100000);
+    1921           8 :   parameter[G_SC3].push_back(0.02208700);
+    1922           8 :   parameter[G_SC3].push_back(0.17032800);
+    1923           8 :   parameter[G_SC3].push_back(0.73280800);
+    1924           8 :   parameter[G_SC3].push_back(-1.95292000);
+    1925           8 :   parameter[G_SC3].push_back(0.98357600);
+    1926           8 :   parameter[G_SC3].push_back(-0.14790900);
+    1927             : 
+    1928           8 :   parameter[G_SC4].push_back(6.45900000);
+    1929           8 :   parameter[G_SC4].push_back(0.02023700);
+    1930           8 :   parameter[G_SC4].push_back(4.17655400);
+    1931           8 :   parameter[G_SC4].push_back(0.98731800);
+    1932           8 :   parameter[G_SC4].push_back(-5.04352800);
+    1933           8 :   parameter[G_SC4].push_back(2.56059400);
+    1934           8 :   parameter[G_SC4].push_back(-0.39234300);
+    1935             : 
+    1936           8 :   parameter[G_3TE].push_back(4.23000000);
+    1937           8 :   parameter[G_3TE].push_back(0.00066300);
+    1938           8 :   parameter[G_3TE].push_back(0.92118800);
+    1939           8 :   parameter[G_3TE].push_back(0.08062700);
+    1940           8 :   parameter[G_3TE].push_back(-0.39041600);
+    1941           8 :   parameter[G_3TE].push_back(0.12419400);
+    1942           8 :   parameter[G_3TE].push_back(-0.01120500);
+    1943             : 
+    1944           8 :   parameter[G_5TE].push_back(4.23000000);
+    1945           8 :   parameter[G_5TE].push_back(0.00062800);
+    1946           8 :   parameter[G_5TE].push_back(0.92133500);
+    1947           8 :   parameter[G_5TE].push_back(0.08029900);
+    1948           8 :   parameter[G_5TE].push_back(-0.39015300);
+    1949           8 :   parameter[G_5TE].push_back(0.12411600);
+    1950           8 :   parameter[G_5TE].push_back(-0.01119900);
+    1951             : 
+    1952           8 :   parameter[G_TE3].push_back(7.82400000);
+    1953           8 :   parameter[G_TE3].push_back(-0.05177400);
+    1954           8 :   parameter[G_TE3].push_back(8.34606700);
+    1955           8 :   parameter[G_TE3].push_back(-1.02936300);
+    1956           8 :   parameter[G_TE3].push_back(-9.55211900);
+    1957           8 :   parameter[G_TE3].push_back(6.37776600);
+    1958           8 :   parameter[G_TE3].push_back(-1.17898000);
+    1959             : 
+    1960           8 :   parameter[G_TE5].push_back(8.03600000);
+    1961           8 :   parameter[G_TE5].push_back(0.00525100);
+    1962           8 :   parameter[G_TE5].push_back(4.71070600);
+    1963           8 :   parameter[G_TE5].push_back(0.66746900);
+    1964           8 :   parameter[G_TE5].push_back(-6.72538700);
+    1965           8 :   parameter[G_TE5].push_back(4.03644100);
+    1966           8 :   parameter[G_TE5].push_back(-0.70605700);
+    1967             : 
+    1968           8 :   parameter[U_BB1].push_back(32.88500000);
+    1969           8 :   parameter[U_BB1].push_back(0.08321400);
+    1970           8 :   parameter[U_BB1].push_back(-7.35634900);
+    1971           8 :   parameter[U_BB1].push_back(2.18826800);
+    1972           8 :   parameter[U_BB1].push_back(-3.56047400);
+    1973           8 :   parameter[U_BB1].push_back(2.33064700);
+    1974           8 :   parameter[U_BB1].push_back(-0.39744000);
+    1975             : 
+    1976           8 :   parameter[U_BB2].push_back(3.80600000);
+    1977           8 :   parameter[U_BB2].push_back(-0.10773100);
+    1978           8 :   parameter[U_BB2].push_back(9.60099900);
+    1979           8 :   parameter[U_BB2].push_back(-6.26131900);
+    1980           8 :   parameter[U_BB2].push_back(-0.46668300);
+    1981           8 :   parameter[U_BB2].push_back(1.13698100);
+    1982           8 :   parameter[U_BB2].push_back(-0.21351600);
+    1983             : 
+    1984           8 :   parameter[U_BB3].push_back(3.59400000);
+    1985           8 :   parameter[U_BB3].push_back(0.04544300);
+    1986           8 :   parameter[U_BB3].push_back(9.59625900);
+    1987           8 :   parameter[U_BB3].push_back(-1.29222200);
+    1988           8 :   parameter[U_BB3].push_back(-7.11143200);
+    1989           8 :   parameter[U_BB3].push_back(4.05687700);
+    1990           8 :   parameter[U_BB3].push_back(-0.63382800);
+    1991             : 
+    1992           8 :   parameter[U_SC1].push_back(5.95100000);
+    1993           8 :   parameter[U_SC1].push_back(-0.02924500);
+    1994           8 :   parameter[U_SC1].push_back(2.59668700);
+    1995           8 :   parameter[U_SC1].push_back(-0.56118700);
+    1996           8 :   parameter[U_SC1].push_back(-1.56477100);
+    1997           8 :   parameter[U_SC1].push_back(0.89265100);
+    1998           8 :   parameter[U_SC1].push_back(-0.14130800);
+    1999             : 
+    2000           8 :   parameter[U_SC2].push_back(10.90100000);
+    2001           8 :   parameter[U_SC2].push_back(0.02178900);
+    2002           8 :   parameter[U_SC2].push_back(0.18839000);
+    2003           8 :   parameter[U_SC2].push_back(0.72223100);
+    2004           8 :   parameter[U_SC2].push_back(-1.92581600);
+    2005           8 :   parameter[U_SC2].push_back(0.96654300);
+    2006           8 :   parameter[U_SC2].push_back(-0.14501300);
+    2007             : 
+    2008           8 :   parameter[U_SC3].push_back(5.24600000);
+    2009           8 :   parameter[U_SC3].push_back(-0.04586500);
+    2010           8 :   parameter[U_SC3].push_back(5.89978100);
+    2011           8 :   parameter[U_SC3].push_back(-1.50664700);
+    2012           8 :   parameter[U_SC3].push_back(-3.17054400);
+    2013           8 :   parameter[U_SC3].push_back(1.93717100);
+    2014           8 :   parameter[U_SC3].push_back(-0.31701000);
+    2015             : 
+    2016           8 :   parameter[U_3TE].push_back(4.23000000);
+    2017           8 :   parameter[U_3TE].push_back(0.00067500);
+    2018           8 :   parameter[U_3TE].push_back(0.92102300);
+    2019           8 :   parameter[U_3TE].push_back(0.08100800);
+    2020           8 :   parameter[U_3TE].push_back(-0.39084300);
+    2021           8 :   parameter[U_3TE].push_back(0.12441900);
+    2022           8 :   parameter[U_3TE].push_back(-0.01124900);
+    2023             : 
+    2024           8 :   parameter[U_5TE].push_back(4.23000000);
+    2025           8 :   parameter[U_5TE].push_back(0.00059000);
+    2026           8 :   parameter[U_5TE].push_back(0.92154600);
+    2027           8 :   parameter[U_5TE].push_back(0.07968200);
+    2028           8 :   parameter[U_5TE].push_back(-0.38950100);
+    2029           8 :   parameter[U_5TE].push_back(0.12382500);
+    2030           8 :   parameter[U_5TE].push_back(-0.01115100);
+    2031             : 
+    2032           8 :   parameter[U_TE3].push_back(7.82400000);
+    2033           8 :   parameter[U_TE3].push_back(-0.02968100);
+    2034           8 :   parameter[U_TE3].push_back(7.93783200);
+    2035           8 :   parameter[U_TE3].push_back(-0.33078100);
+    2036           8 :   parameter[U_TE3].push_back(-10.14120200);
+    2037           8 :   parameter[U_TE3].push_back(6.63334700);
+    2038           8 :   parameter[U_TE3].push_back(-1.22111200);
+    2039             : 
+    2040           8 :   parameter[U_TE5].push_back(8.03600000);
+    2041           8 :   parameter[U_TE5].push_back(-0.00909700);
+    2042           8 :   parameter[U_TE5].push_back(4.33193500);
+    2043           8 :   parameter[U_TE5].push_back(0.43416500);
+    2044           8 :   parameter[U_TE5].push_back(-5.80831400);
+    2045           8 :   parameter[U_TE5].push_back(3.52438800);
+    2046           8 :   parameter[U_TE5].push_back(-0.62382400);
+    2047             : 
+    2048           8 :   parameter[DA_BB1].push_back(32.88500000);
+    2049           8 :   parameter[DA_BB1].push_back(0.08179900);
+    2050           8 :   parameter[DA_BB1].push_back(-7.31735900);
+    2051           8 :   parameter[DA_BB1].push_back(2.15614500);
+    2052           8 :   parameter[DA_BB1].push_back(-3.52263200);
+    2053           8 :   parameter[DA_BB1].push_back(2.30604700);
+    2054           8 :   parameter[DA_BB1].push_back(-0.39270100);
+    2055             : 
+    2056           8 :   parameter[DA_BB2].push_back(3.80600000);
+    2057           8 :   parameter[DA_BB2].push_back(-0.10597700);
+    2058           8 :   parameter[DA_BB2].push_back(9.52537500);
+    2059           8 :   parameter[DA_BB2].push_back(-6.12991000);
+    2060           8 :   parameter[DA_BB2].push_back(-0.54092600);
+    2061           8 :   parameter[DA_BB2].push_back(1.15429100);
+    2062           8 :   parameter[DA_BB2].push_back(-0.21503500);
+    2063             : 
+    2064           8 :   parameter[DA_BB3].push_back(-1.35600000);
+    2065           8 :   parameter[DA_BB3].push_back(0.58928300);
+    2066           8 :   parameter[DA_BB3].push_back(6.71894100);
+    2067           8 :   parameter[DA_BB3].push_back(4.14050900);
+    2068           8 :   parameter[DA_BB3].push_back(-9.65859900);
+    2069           8 :   parameter[DA_BB3].push_back(4.43185000);
+    2070           8 :   parameter[DA_BB3].push_back(-0.64657300);
+    2071             : 
+    2072           8 :   parameter[DA_SC1].push_back(6.67100000);
+    2073           8 :   parameter[DA_SC1].push_back(-0.00871400);
+    2074           8 :   parameter[DA_SC1].push_back(1.63289100);
+    2075           8 :   parameter[DA_SC1].push_back(-0.06637700);
+    2076           8 :   parameter[DA_SC1].push_back(-1.48632900);
+    2077           8 :   parameter[DA_SC1].push_back(0.78551800);
+    2078           8 :   parameter[DA_SC1].push_back(-0.12087300);
+    2079             : 
+    2080           8 :   parameter[DA_SC2].push_back(5.95100000);
+    2081           8 :   parameter[DA_SC2].push_back(-0.02634300);
+    2082           8 :   parameter[DA_SC2].push_back(2.54864300);
+    2083           8 :   parameter[DA_SC2].push_back(-0.49015800);
+    2084           8 :   parameter[DA_SC2].push_back(-1.55386900);
+    2085           8 :   parameter[DA_SC2].push_back(0.86630200);
+    2086           8 :   parameter[DA_SC2].push_back(-0.13546200);
+    2087             : 
+    2088           8 :   parameter[DA_SC3].push_back(11.39400000);
+    2089           8 :   parameter[DA_SC3].push_back(0.00859500);
+    2090           8 :   parameter[DA_SC3].push_back(-0.25471400);
+    2091           8 :   parameter[DA_SC3].push_back(0.48718800);
+    2092           8 :   parameter[DA_SC3].push_back(-1.74520000);
+    2093           8 :   parameter[DA_SC3].push_back(0.99246200);
+    2094           8 :   parameter[DA_SC3].push_back(-0.16351900);
+    2095             : 
+    2096           8 :   parameter[DA_SC4].push_back(6.45900000);
+    2097           8 :   parameter[DA_SC4].push_back(0.01991800);
+    2098           8 :   parameter[DA_SC4].push_back(4.17962300);
+    2099           8 :   parameter[DA_SC4].push_back(0.97469100);
+    2100           8 :   parameter[DA_SC4].push_back(-5.02950400);
+    2101           8 :   parameter[DA_SC4].push_back(2.55371800);
+    2102           8 :   parameter[DA_SC4].push_back(-0.39113400);
+    2103             : 
+    2104           8 :   parameter[DA_3TE].push_back(4.23000000);
+    2105           8 :   parameter[DA_3TE].push_back(0.00062600);
+    2106           8 :   parameter[DA_3TE].push_back(0.92142000);
+    2107           8 :   parameter[DA_3TE].push_back(0.08016400);
+    2108           8 :   parameter[DA_3TE].push_back(-0.39000300);
+    2109           8 :   parameter[DA_3TE].push_back(0.12402500);
+    2110           8 :   parameter[DA_3TE].push_back(-0.01117900);
+    2111             : 
+    2112           8 :   parameter[DA_5TE].push_back(4.23000000);
+    2113           8 :   parameter[DA_5TE].push_back(0.00055500);
+    2114           8 :   parameter[DA_5TE].push_back(0.92183900);
+    2115           8 :   parameter[DA_5TE].push_back(0.07907600);
+    2116           8 :   parameter[DA_5TE].push_back(-0.38895100);
+    2117           8 :   parameter[DA_5TE].push_back(0.12359600);
+    2118           8 :   parameter[DA_5TE].push_back(-0.01111600);
+    2119             : 
+    2120           8 :   parameter[DA_TE3].push_back(2.87400000);
+    2121           8 :   parameter[DA_TE3].push_back(0.00112900);
+    2122           8 :   parameter[DA_TE3].push_back(12.51167200);
+    2123           8 :   parameter[DA_TE3].push_back(-7.67548000);
+    2124           8 :   parameter[DA_TE3].push_back(-2.02234000);
+    2125           8 :   parameter[DA_TE3].push_back(2.50837100);
+    2126           8 :   parameter[DA_TE3].push_back(-0.49458500);
+    2127             : 
+    2128           8 :   parameter[DA_TE5].push_back(8.03600000);
+    2129           8 :   parameter[DA_TE5].push_back(0.00473100);
+    2130           8 :   parameter[DA_TE5].push_back(4.65554400);
+    2131           8 :   parameter[DA_TE5].push_back(0.66424100);
+    2132           8 :   parameter[DA_TE5].push_back(-6.62131300);
+    2133           8 :   parameter[DA_TE5].push_back(3.96107400);
+    2134           8 :   parameter[DA_TE5].push_back(-0.69075800);
+    2135             : 
+    2136           8 :   parameter[DC_BB1].push_back(32.88500000);
+    2137           8 :   parameter[DC_BB1].push_back(0.08189900);
+    2138           8 :   parameter[DC_BB1].push_back(-7.32493500);
+    2139           8 :   parameter[DC_BB1].push_back(2.15976900);
+    2140           8 :   parameter[DC_BB1].push_back(-3.52612100);
+    2141           8 :   parameter[DC_BB1].push_back(2.31058600);
+    2142           8 :   parameter[DC_BB1].push_back(-0.39402700);
+    2143             : 
+    2144           8 :   parameter[DC_BB2].push_back(3.80600000);
+    2145           8 :   parameter[DC_BB2].push_back(-0.10559800);
+    2146           8 :   parameter[DC_BB2].push_back(9.52527700);
+    2147           8 :   parameter[DC_BB2].push_back(-6.12131700);
+    2148           8 :   parameter[DC_BB2].push_back(-0.54899400);
+    2149           8 :   parameter[DC_BB2].push_back(1.15592900);
+    2150           8 :   parameter[DC_BB2].push_back(-0.21494500);
+    2151             : 
+    2152           8 :   parameter[DC_BB3].push_back(-1.35600000);
+    2153           8 :   parameter[DC_BB3].push_back(0.55525700);
+    2154           8 :   parameter[DC_BB3].push_back(6.80305500);
+    2155           8 :   parameter[DC_BB3].push_back(4.05924700);
+    2156           8 :   parameter[DC_BB3].push_back(-9.61034700);
+    2157           8 :   parameter[DC_BB3].push_back(4.41253800);
+    2158           8 :   parameter[DC_BB3].push_back(-0.64315100);
+    2159             : 
+    2160           8 :   parameter[DC_SC1].push_back(5.95100000);
+    2161           8 :   parameter[DC_SC1].push_back(-0.02899900);
+    2162           8 :   parameter[DC_SC1].push_back(2.59587800);
+    2163           8 :   parameter[DC_SC1].push_back(-0.55388300);
+    2164           8 :   parameter[DC_SC1].push_back(-1.56395100);
+    2165           8 :   parameter[DC_SC1].push_back(0.88967400);
+    2166           8 :   parameter[DC_SC1].push_back(-0.14062500);
+    2167             : 
+    2168           8 :   parameter[DC_SC2].push_back(11.62100000);
+    2169           8 :   parameter[DC_SC2].push_back(0.01358100);
+    2170           8 :   parameter[DC_SC2].push_back(-0.24913000);
+    2171           8 :   parameter[DC_SC2].push_back(0.48787200);
+    2172           8 :   parameter[DC_SC2].push_back(-1.52867300);
+    2173           8 :   parameter[DC_SC2].push_back(0.83694900);
+    2174           8 :   parameter[DC_SC2].push_back(-0.13395300);
+    2175             : 
+    2176           8 :   parameter[DC_SC3].push_back(5.01900000);
+    2177           8 :   parameter[DC_SC3].push_back(-0.03298400);
+    2178           8 :   parameter[DC_SC3].push_back(5.54242800);
+    2179           8 :   parameter[DC_SC3].push_back(-0.96081500);
+    2180           8 :   parameter[DC_SC3].push_back(-3.71051600);
+    2181           8 :   parameter[DC_SC3].push_back(2.16500200);
+    2182           8 :   parameter[DC_SC3].push_back(-0.35023400);
+    2183             : 
+    2184           8 :   parameter[DC_3TE].push_back(4.23000000);
+    2185           8 :   parameter[DC_3TE].push_back(0.00055700);
+    2186           8 :   parameter[DC_3TE].push_back(0.92181400);
+    2187           8 :   parameter[DC_3TE].push_back(0.07924000);
+    2188           8 :   parameter[DC_3TE].push_back(-0.38916400);
+    2189           8 :   parameter[DC_3TE].push_back(0.12369900);
+    2190           8 :   parameter[DC_3TE].push_back(-0.01113300);
+    2191             : 
+    2192           8 :   parameter[DC_5TE].push_back(4.23000000);
+    2193           8 :   parameter[DC_5TE].push_back(0.00066500);
+    2194           8 :   parameter[DC_5TE].push_back(0.92103900);
+    2195           8 :   parameter[DC_5TE].push_back(0.08064600);
+    2196           8 :   parameter[DC_5TE].push_back(-0.39034900);
+    2197           8 :   parameter[DC_5TE].push_back(0.12417600);
+    2198           8 :   parameter[DC_5TE].push_back(-0.01120600);
+    2199             : 
+    2200           8 :   parameter[DC_TE3].push_back(2.87400000);
+    2201           8 :   parameter[DC_TE3].push_back(-0.05235500);
+    2202           8 :   parameter[DC_TE3].push_back(13.09201200);
+    2203           8 :   parameter[DC_TE3].push_back(-9.48128200);
+    2204           8 :   parameter[DC_TE3].push_back(-0.14958600);
+    2205           8 :   parameter[DC_TE3].push_back(1.75537200);
+    2206           8 :   parameter[DC_TE3].push_back(-0.39347500);
+    2207             : 
+    2208           8 :   parameter[DC_TE5].push_back(8.03600000);
+    2209           8 :   parameter[DC_TE5].push_back(-0.00513600);
+    2210           8 :   parameter[DC_TE5].push_back(4.67705700);
+    2211           8 :   parameter[DC_TE5].push_back(0.48333300);
+    2212           8 :   parameter[DC_TE5].push_back(-6.34511000);
+    2213           8 :   parameter[DC_TE5].push_back(3.83388500);
+    2214           8 :   parameter[DC_TE5].push_back(-0.67367800);
+    2215             : 
+    2216           8 :   parameter[DG_BB1].push_back(32.88500000);
+    2217           8 :   parameter[DG_BB1].push_back(0.08182900);
+    2218           8 :   parameter[DG_BB1].push_back(-7.32133900);
+    2219           8 :   parameter[DG_BB1].push_back(2.15767900);
+    2220           8 :   parameter[DG_BB1].push_back(-3.52369700);
+    2221           8 :   parameter[DG_BB1].push_back(2.30839600);
+    2222           8 :   parameter[DG_BB1].push_back(-0.39348300);
+    2223             : 
+    2224           8 :   parameter[DG_BB2].push_back(3.80600000);
+    2225           8 :   parameter[DG_BB2].push_back(-0.10618100);
+    2226           8 :   parameter[DG_BB2].push_back(9.54169000);
+    2227           8 :   parameter[DG_BB2].push_back(-6.15177600);
+    2228           8 :   parameter[DG_BB2].push_back(-0.53462400);
+    2229           8 :   parameter[DG_BB2].push_back(1.15581300);
+    2230           8 :   parameter[DG_BB2].push_back(-0.21567000);
+    2231             : 
+    2232           8 :   parameter[DG_BB3].push_back(-1.35600000);
+    2233           8 :   parameter[DG_BB3].push_back(0.57489100);
+    2234           8 :   parameter[DG_BB3].push_back(6.75164700);
+    2235           8 :   parameter[DG_BB3].push_back(4.11300900);
+    2236           8 :   parameter[DG_BB3].push_back(-9.63394600);
+    2237           8 :   parameter[DG_BB3].push_back(4.41675400);
+    2238           8 :   parameter[DG_BB3].push_back(-0.64339900);
+    2239             : 
+    2240           8 :   parameter[DG_SC1].push_back(6.67100000);
+    2241           8 :   parameter[DG_SC1].push_back(-0.00886600);
+    2242           8 :   parameter[DG_SC1].push_back(1.63333000);
+    2243           8 :   parameter[DG_SC1].push_back(-0.06892100);
+    2244           8 :   parameter[DG_SC1].push_back(-1.48683500);
+    2245           8 :   parameter[DG_SC1].push_back(0.78670800);
+    2246           8 :   parameter[DG_SC1].push_back(-0.12113900);
+    2247             : 
+    2248           8 :   parameter[DG_SC2].push_back(11.39400000);
+    2249           8 :   parameter[DG_SC2].push_back(0.00907900);
+    2250           8 :   parameter[DG_SC2].push_back(-0.22475500);
+    2251           8 :   parameter[DG_SC2].push_back(0.49535100);
+    2252           8 :   parameter[DG_SC2].push_back(-1.75324900);
+    2253           8 :   parameter[DG_SC2].push_back(0.98767400);
+    2254           8 :   parameter[DG_SC2].push_back(-0.16150800);
+    2255             : 
+    2256           8 :   parameter[DG_SC3].push_back(10.90100000);
+    2257           8 :   parameter[DG_SC3].push_back(0.02207600);
+    2258           8 :   parameter[DG_SC3].push_back(0.17932200);
+    2259           8 :   parameter[DG_SC3].push_back(0.73253200);
+    2260           8 :   parameter[DG_SC3].push_back(-1.95554900);
+    2261           8 :   parameter[DG_SC3].push_back(0.98339900);
+    2262           8 :   parameter[DG_SC3].push_back(-0.14763600);
+    2263             : 
+    2264           8 :   parameter[DG_SC4].push_back(6.45900000);
+    2265           8 :   parameter[DG_SC4].push_back(0.02018400);
+    2266           8 :   parameter[DG_SC4].push_back(4.17705400);
+    2267           8 :   parameter[DG_SC4].push_back(0.98531700);
+    2268           8 :   parameter[DG_SC4].push_back(-5.04354900);
+    2269           8 :   parameter[DG_SC4].push_back(2.56123700);
+    2270           8 :   parameter[DG_SC4].push_back(-0.39249300);
+    2271             : 
+    2272           8 :   parameter[DG_3TE].push_back(4.23000000);
+    2273           8 :   parameter[DG_3TE].push_back(0.00061700);
+    2274           8 :   parameter[DG_3TE].push_back(0.92140100);
+    2275           8 :   parameter[DG_3TE].push_back(0.08016400);
+    2276           8 :   parameter[DG_3TE].push_back(-0.39003500);
+    2277           8 :   parameter[DG_3TE].push_back(0.12406900);
+    2278           8 :   parameter[DG_3TE].push_back(-0.01119200);
+    2279             : 
+    2280           8 :   parameter[DG_5TE].push_back(4.23000000);
+    2281           8 :   parameter[DG_5TE].push_back(0.00064900);
+    2282           8 :   parameter[DG_5TE].push_back(0.92110500);
+    2283           8 :   parameter[DG_5TE].push_back(0.08031500);
+    2284           8 :   parameter[DG_5TE].push_back(-0.38997000);
+    2285           8 :   parameter[DG_5TE].push_back(0.12401200);
+    2286           8 :   parameter[DG_5TE].push_back(-0.01118100);
+    2287             : 
+    2288           8 :   parameter[DG_TE3].push_back(2.87400000);
+    2289           8 :   parameter[DG_TE3].push_back(0.00182000);
+    2290           8 :   parameter[DG_TE3].push_back(12.41507000);
+    2291           8 :   parameter[DG_TE3].push_back(-7.47384800);
+    2292           8 :   parameter[DG_TE3].push_back(-2.11864700);
+    2293           8 :   parameter[DG_TE3].push_back(2.50112600);
+    2294           8 :   parameter[DG_TE3].push_back(-0.48652200);
+    2295             : 
+    2296           8 :   parameter[DG_TE5].push_back(8.03600000);
+    2297           8 :   parameter[DG_TE5].push_back(0.00676400);
+    2298           8 :   parameter[DG_TE5].push_back(4.65989200);
+    2299           8 :   parameter[DG_TE5].push_back(0.78482500);
+    2300           8 :   parameter[DG_TE5].push_back(-6.86460600);
+    2301           8 :   parameter[DG_TE5].push_back(4.11675400);
+    2302           8 :   parameter[DG_TE5].push_back(-0.72249100);
+    2303             : 
+    2304           8 :   parameter[DT_BB1].push_back(32.88500000);
+    2305           8 :   parameter[DT_BB1].push_back(0.08220100);
+    2306           8 :   parameter[DT_BB1].push_back(-7.33006800);
+    2307           8 :   parameter[DT_BB1].push_back(2.16636500);
+    2308           8 :   parameter[DT_BB1].push_back(-3.53465700);
+    2309           8 :   parameter[DT_BB1].push_back(2.31447600);
+    2310           8 :   parameter[DT_BB1].push_back(-0.39445400);
+    2311             : 
+    2312           8 :   parameter[DT_BB2].push_back(3.80600000);
+    2313           8 :   parameter[DT_BB2].push_back(-0.10723000);
+    2314           8 :   parameter[DT_BB2].push_back(9.56675000);
+    2315           8 :   parameter[DT_BB2].push_back(-6.20236100);
+    2316           8 :   parameter[DT_BB2].push_back(-0.49550400);
+    2317           8 :   parameter[DT_BB2].push_back(1.14300600);
+    2318           8 :   parameter[DT_BB2].push_back(-0.21420000);
+    2319             : 
+    2320           8 :   parameter[DT_BB3].push_back(-1.35600000);
+    2321           8 :   parameter[DT_BB3].push_back(0.56737900);
+    2322           8 :   parameter[DT_BB3].push_back(6.76595400);
+    2323           8 :   parameter[DT_BB3].push_back(4.08976100);
+    2324           8 :   parameter[DT_BB3].push_back(-9.61512500);
+    2325           8 :   parameter[DT_BB3].push_back(4.40975100);
+    2326           8 :   parameter[DT_BB3].push_back(-0.64239800);
+    2327             : 
+    2328           8 :   parameter[DT_SC1].push_back(5.95100000);
+    2329           8 :   parameter[DT_SC1].push_back(-0.02926500);
+    2330           8 :   parameter[DT_SC1].push_back(2.59630300);
+    2331           8 :   parameter[DT_SC1].push_back(-0.56152200);
+    2332           8 :   parameter[DT_SC1].push_back(-1.56532600);
+    2333           8 :   parameter[DT_SC1].push_back(0.89322800);
+    2334           8 :   parameter[DT_SC1].push_back(-0.14142900);
+    2335             : 
+    2336           8 :   parameter[DT_SC2].push_back(10.90100000);
+    2337           8 :   parameter[DT_SC2].push_back(0.02183400);
+    2338           8 :   parameter[DT_SC2].push_back(0.19463000);
+    2339           8 :   parameter[DT_SC2].push_back(0.72393000);
+    2340           8 :   parameter[DT_SC2].push_back(-1.93199500);
+    2341           8 :   parameter[DT_SC2].push_back(0.96856300);
+    2342           8 :   parameter[DT_SC2].push_back(-0.14512600);
+    2343             : 
+    2344           8 :   parameter[DT_SC3].push_back(4.31400000);
+    2345           8 :   parameter[DT_SC3].push_back(-0.07745600);
+    2346           8 :   parameter[DT_SC3].push_back(12.49820300);
+    2347           8 :   parameter[DT_SC3].push_back(-7.64994200);
+    2348           8 :   parameter[DT_SC3].push_back(-3.00359600);
+    2349           8 :   parameter[DT_SC3].push_back(3.26263300);
+    2350           8 :   parameter[DT_SC3].push_back(-0.64498600);
+    2351             : 
+    2352           8 :   parameter[DT_3TE].push_back(4.23000000);
+    2353           8 :   parameter[DT_3TE].push_back(0.00062000);
+    2354           8 :   parameter[DT_3TE].push_back(0.92141100);
+    2355           8 :   parameter[DT_3TE].push_back(0.08030900);
+    2356           8 :   parameter[DT_3TE].push_back(-0.39021500);
+    2357           8 :   parameter[DT_3TE].push_back(0.12414000);
+    2358           8 :   parameter[DT_3TE].push_back(-0.01120100);
+    2359             : 
+    2360           8 :   parameter[DT_5TE].push_back(4.23000000);
+    2361           8 :   parameter[DT_5TE].push_back(0.00063700);
+    2362           8 :   parameter[DT_5TE].push_back(0.92130800);
+    2363           8 :   parameter[DT_5TE].push_back(0.08026900);
+    2364           8 :   parameter[DT_5TE].push_back(-0.39007500);
+    2365           8 :   parameter[DT_5TE].push_back(0.12406600);
+    2366           8 :   parameter[DT_5TE].push_back(-0.01118800);
+    2367             : 
+    2368           8 :   parameter[DT_TE3].push_back(2.87400000);
+    2369           8 :   parameter[DT_TE3].push_back(-0.00251200);
+    2370           8 :   parameter[DT_TE3].push_back(12.43576400);
+    2371           8 :   parameter[DT_TE3].push_back(-7.55343800);
+    2372           8 :   parameter[DT_TE3].push_back(-2.07363500);
+    2373           8 :   parameter[DT_TE3].push_back(2.51279300);
+    2374           8 :   parameter[DT_TE3].push_back(-0.49437100);
+    2375             : 
+    2376           8 :   parameter[DT_TE5].push_back(8.03600000);
+    2377           8 :   parameter[DT_TE5].push_back(0.00119900);
+    2378           8 :   parameter[DT_TE5].push_back(4.91762300);
+    2379           8 :   parameter[DT_TE5].push_back(0.65637000);
+    2380           8 :   parameter[DT_TE5].push_back(-7.23392500);
+    2381           8 :   parameter[DT_TE5].push_back(4.44636600);
+    2382           8 :   parameter[DT_TE5].push_back(-0.79467800);
+    2383             : 
+    2384           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    2385           8 :   if( moldat ) {
+    2386        8400 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    2387        8392 :       std::string Aname = moldat->getAtomName(atoms[i]);
+    2388        8392 :       std::string Rname = moldat->getResidueName(atoms[i]);
+    2389        8392 :       if(Rname=="ALA") {
+    2390          72 :         if(Aname=="BB") {
+    2391          72 :           atoi[i]=ALA_BB;
+    2392           0 :         } else error("Atom name not known: "+Aname);
+    2393        8320 :       } else if(Rname=="ARG") {
+    2394         420 :         if(Aname=="BB") {
+    2395         140 :           atoi[i]=ARG_BB;
+    2396         280 :         } else if(Aname=="SC1") {
+    2397         140 :           atoi[i]=ARG_SC1;
+    2398         140 :         } else if(Aname=="SC2") {
+    2399         140 :           atoi[i]=ARG_SC2;
+    2400           0 :         } else error("Atom name not known: "+Aname);
+    2401        7900 :       } else if(Rname=="ASN") {
+    2402         240 :         if(Aname=="BB") {
+    2403         120 :           atoi[i]=ASN_BB;
+    2404         120 :         } else if(Aname=="SC1") {
+    2405         120 :           atoi[i]=ASN_SC1;
+    2406           0 :         } else error("Atom name not known: "+Aname);
+    2407        7660 :       } else if(Rname=="ASP") {
+    2408         368 :         if(Aname=="BB") {
+    2409         184 :           atoi[i]=ASP_BB;
+    2410         184 :         } else if(Aname=="SC1") {
+    2411         184 :           atoi[i]=ASP_SC1;
+    2412           0 :         } else error("Atom name not known: "+Aname);
+    2413        7292 :       } else if(Rname=="CYS") {
+    2414          16 :         if(Aname=="BB") {
+    2415           8 :           atoi[i]=CYS_BB;
+    2416           8 :         } else if(Aname=="SC1") {
+    2417           8 :           atoi[i]=CYS_SC1;
+    2418           0 :         } else error("Atom name not known: "+Aname);
+    2419        7276 :       } else if(Rname=="GLN") {
+    2420         224 :         if(Aname=="BB") {
+    2421         112 :           atoi[i]=GLN_BB;
+    2422         112 :         } else if(Aname=="SC1") {
+    2423         112 :           atoi[i]=GLN_SC1;
+    2424           0 :         } else error("Atom name not known: "+Aname);
+    2425        7052 :       } else if(Rname=="GLU") {
+    2426         480 :         if(Aname=="BB") {
+    2427         240 :           atoi[i]=GLU_BB;
+    2428         240 :         } else if(Aname=="SC1") {
+    2429         240 :           atoi[i]=GLU_SC1;
+    2430           0 :         } else error("Atom name not known: "+Aname);
+    2431        6572 :       } else if(Rname=="GLY") {
+    2432         116 :         if(Aname=="BB") {
+    2433         116 :           atoi[i]=GLY_BB;
+    2434           0 :         } else error("Atom name not known: "+Aname);
+    2435        6456 :       } else if(Rname=="HIS") {
+    2436         576 :         if(Aname=="BB") {
+    2437         144 :           atoi[i]=HIS_BB;
+    2438         432 :         } else if(Aname=="SC1") {
+    2439         144 :           atoi[i]=HIS_SC1;
+    2440         288 :         } else if(Aname=="SC2") {
+    2441         144 :           atoi[i]=HIS_SC2;
+    2442         144 :         } else if(Aname=="SC3") {
+    2443         144 :           atoi[i]=HIS_SC3;
+    2444           0 :         } else error("Atom name not known: "+Aname);
+    2445        5880 :       } else if(Rname=="ILE") {
+    2446         584 :         if(Aname=="BB") {
+    2447         292 :           atoi[i]=ILE_BB;
+    2448         292 :         } else if(Aname=="SC1") {
+    2449         292 :           atoi[i]=ILE_SC1;
+    2450           0 :         } else error("Atom name not known: "+Aname);
+    2451        5296 :       } else if(Rname=="LEU") {
+    2452         448 :         if(Aname=="BB") {
+    2453         224 :           atoi[i]=LEU_BB;
+    2454         224 :         } else if(Aname=="SC1") {
+    2455         224 :           atoi[i]=LEU_SC1;
+    2456           0 :         } else error("Atom name not known: "+Aname);
+    2457        4848 :       } else if(Rname=="LYS") {
+    2458         792 :         if(Aname=="BB") {
+    2459         264 :           atoi[i]=LYS_BB;
+    2460         528 :         } else if(Aname=="SC1") {
+    2461         264 :           atoi[i]=LYS_SC1;
+    2462         264 :         } else if(Aname=="SC2") {
+    2463         264 :           atoi[i]=LYS_SC2;
+    2464           0 :         } else error("Atom name not known: "+Aname);
+    2465        4056 :       } else if(Rname=="MET") {
+    2466          80 :         if(Aname=="BB") {
+    2467          40 :           atoi[i]=MET_BB;
+    2468          40 :         } else if(Aname=="SC1") {
+    2469          40 :           atoi[i]=MET_SC1;
+    2470           0 :         } else error("Atom name not known: "+Aname);
+    2471        3976 :       } else if(Rname=="PHE") {
+    2472         512 :         if(Aname=="BB") {
+    2473         128 :           atoi[i]=PHE_BB;
+    2474         384 :         } else if(Aname=="SC1") {
+    2475         128 :           atoi[i]=PHE_SC1;
+    2476         256 :         } else if(Aname=="SC2") {
+    2477         128 :           atoi[i]=PHE_SC2;
+    2478         128 :         } else if(Aname=="SC3") {
+    2479         128 :           atoi[i]=PHE_SC3;
+    2480           0 :         } else error("Atom name not known: "+Aname);
+    2481        3464 :       } else if(Rname=="PRO") {
+    2482         128 :         if(Aname=="BB") {
+    2483          64 :           atoi[i]=PRO_BB;
+    2484          64 :         } else if(Aname=="SC1") {
+    2485          64 :           atoi[i]=PRO_SC1;
+    2486           0 :         } else error("Atom name not known: "+Aname);
+    2487        3336 :       } else if(Rname=="SER") {
+    2488         248 :         if(Aname=="BB") {
+    2489         124 :           atoi[i]=SER_BB;
+    2490         124 :         } else if(Aname=="SC1") {
+    2491         124 :           atoi[i]=SER_SC1;
+    2492           0 :         } else error("Atom name not known: "+Aname);
+    2493        3088 :       } else if(Rname=="THR") {
+    2494         288 :         if(Aname=="BB") {
+    2495         144 :           atoi[i]=THR_BB;
+    2496         144 :         } else if(Aname=="SC1") {
+    2497         144 :           atoi[i]=THR_SC1;
+    2498           0 :         } else error("Atom name not known: "+Aname);
+    2499        2800 :       } else if(Rname=="TRP") {
+    2500           0 :         if(Aname=="BB") {
+    2501           0 :           atoi[i]=TRP_BB;
+    2502           0 :         } else if(Aname=="SC1") {
+    2503           0 :           atoi[i]=TRP_SC1;
+    2504           0 :         } else if(Aname=="SC2") {
+    2505           0 :           atoi[i]=TRP_SC2;
+    2506           0 :         } else if(Aname=="SC3") {
+    2507           0 :           atoi[i]=TRP_SC3;
+    2508           0 :         } else if(Aname=="SC4") {
+    2509           0 :           atoi[i]=TRP_SC4;
+    2510           0 :         } else error("Atom name not known: "+Aname);
+    2511        2800 :       } else if(Rname=="TYR") {
+    2512         544 :         if(Aname=="BB") {
+    2513         136 :           atoi[i]=TYR_BB;
+    2514         408 :         } else if(Aname=="SC1") {
+    2515         136 :           atoi[i]=TYR_SC1;
+    2516         272 :         } else if(Aname=="SC2") {
+    2517         136 :           atoi[i]=TYR_SC2;
+    2518         136 :         } else if(Aname=="SC3") {
+    2519         136 :           atoi[i]=TYR_SC3;
+    2520           0 :         } else error("Atom name not known: "+Aname);
+    2521        2256 :       } else if(Rname=="VAL") {
+    2522         288 :         if(Aname=="BB") {
+    2523         144 :           atoi[i]=VAL_BB;
+    2524         144 :         } else if(Aname=="SC1") {
+    2525         144 :           atoi[i]=VAL_SC1;
+    2526           0 :         } else error("Atom name not known: "+Aname);
+    2527        1968 :       } else if(Rname=="  A") {
+    2528           0 :         if(Aname=="BB1") {
+    2529           0 :           atoi[i]=A_BB1;
+    2530           0 :         } else if(Aname=="BB2") {
+    2531           0 :           atoi[i]=A_BB2;
+    2532           0 :         } else if(Aname=="BB3") {
+    2533           0 :           atoi[i]=A_BB3;
+    2534           0 :         } else if(Aname=="SC1") {
+    2535           0 :           atoi[i]=A_SC1;
+    2536           0 :         } else if(Aname=="SC2") {
+    2537           0 :           atoi[i]=A_SC2;
+    2538           0 :         } else if(Aname=="SC3") {
+    2539           0 :           atoi[i]=A_SC3;
+    2540           0 :         } else if(Aname=="SC4") {
+    2541           0 :           atoi[i]=A_SC4;
+    2542           0 :         } else if(Aname=="3TE") {
+    2543           0 :           atoi[i]=A_3TE;
+    2544           0 :         } else if(Aname=="5TE") {
+    2545           0 :           atoi[i]=A_5TE;
+    2546           0 :         } else if(Aname=="TE3") {
+    2547           0 :           atoi[i]=A_TE3;
+    2548           0 :         } else if(Aname=="TE5") {
+    2549           0 :           atoi[i]=A_TE5;
+    2550           0 :         } else error("Atom name not known: "+Aname);
+    2551        1968 :       } else if(Rname=="  C") {
+    2552           0 :         if(Aname=="BB1") {
+    2553           0 :           atoi[i]=C_BB1;
+    2554           0 :         } else if(Aname=="BB2") {
+    2555           0 :           atoi[i]=C_BB2;
+    2556           0 :         } else if(Aname=="BB3") {
+    2557           0 :           atoi[i]=C_BB3;
+    2558           0 :         } else if(Aname=="SC1") {
+    2559           0 :           atoi[i]=C_SC1;
+    2560           0 :         } else if(Aname=="SC2") {
+    2561           0 :           atoi[i]=C_SC2;
+    2562           0 :         } else if(Aname=="SC3") {
+    2563           0 :           atoi[i]=C_SC3;
+    2564           0 :         } else if(Aname=="3TE") {
+    2565           0 :           atoi[i]=C_3TE;
+    2566           0 :         } else if(Aname=="5TE") {
+    2567           0 :           atoi[i]=C_5TE;
+    2568           0 :         } else if(Aname=="TE3") {
+    2569           0 :           atoi[i]=C_TE3;
+    2570           0 :         } else if(Aname=="TE5") {
+    2571           0 :           atoi[i]=C_TE5;
+    2572           0 :         } else error("Atom name not known: "+Aname);
+    2573        1968 :       } else if(Rname=="  G") {
+    2574           0 :         if(Aname=="BB1") {
+    2575           0 :           atoi[i]=G_BB1;
+    2576           0 :         } else if(Aname=="BB2") {
+    2577           0 :           atoi[i]=G_BB2;
+    2578           0 :         } else if(Aname=="BB3") {
+    2579           0 :           atoi[i]=G_BB3;
+    2580           0 :         } else if(Aname=="SC1") {
+    2581           0 :           atoi[i]=G_SC1;
+    2582           0 :         } else if(Aname=="SC2") {
+    2583           0 :           atoi[i]=G_SC2;
+    2584           0 :         } else if(Aname=="SC3") {
+    2585           0 :           atoi[i]=G_SC3;
+    2586           0 :         } else if(Aname=="SC4") {
+    2587           0 :           atoi[i]=G_SC4;
+    2588           0 :         } else if(Aname=="3TE") {
+    2589           0 :           atoi[i]=G_3TE;
+    2590           0 :         } else if(Aname=="5TE") {
+    2591           0 :           atoi[i]=G_5TE;
+    2592           0 :         } else if(Aname=="TE3") {
+    2593           0 :           atoi[i]=G_TE3;
+    2594           0 :         } else if(Aname=="TE5") {
+    2595           0 :           atoi[i]=G_TE5;
+    2596           0 :         } else error("Atom name not known: "+Aname);
+    2597        1968 :       } else if(Rname=="  U") {
+    2598           0 :         if(Aname=="BB1") {
+    2599           0 :           atoi[i]=U_BB1;
+    2600           0 :         } else if(Aname=="BB2") {
+    2601           0 :           atoi[i]=U_BB2;
+    2602           0 :         } else if(Aname=="BB3") {
+    2603           0 :           atoi[i]=U_BB3;
+    2604           0 :         } else if(Aname=="SC1") {
+    2605           0 :           atoi[i]=U_SC1;
+    2606           0 :         } else if(Aname=="SC2") {
+    2607           0 :           atoi[i]=U_SC2;
+    2608           0 :         } else if(Aname=="SC3") {
+    2609           0 :           atoi[i]=U_SC3;
+    2610           0 :         } else if(Aname=="3TE") {
+    2611           0 :           atoi[i]=U_3TE;
+    2612           0 :         } else if(Aname=="5TE") {
+    2613           0 :           atoi[i]=U_5TE;
+    2614           0 :         } else if(Aname=="TE3") {
+    2615           0 :           atoi[i]=U_TE3;
+    2616           0 :         } else if(Aname=="TE5") {
+    2617           0 :           atoi[i]=U_TE5;
+    2618           0 :         } else error("Atom name not known: "+Aname);
+    2619        1968 :       } else if(Rname==" DA") {
+    2620         696 :         if(Aname=="BB1") {
+    2621          96 :           atoi[i]=DA_BB1;
+    2622         600 :         } else if(Aname=="BB2") {
+    2623          96 :           atoi[i]=DA_BB2;
+    2624         504 :         } else if(Aname=="BB3") {
+    2625          96 :           atoi[i]=DA_BB3;
+    2626         408 :         } else if(Aname=="SC1") {
+    2627         100 :           atoi[i]=DA_SC1;
+    2628         308 :         } else if(Aname=="SC2") {
+    2629         100 :           atoi[i]=DA_SC2;
+    2630         208 :         } else if(Aname=="SC3") {
+    2631         100 :           atoi[i]=DA_SC3;
+    2632         108 :         } else if(Aname=="SC4") {
+    2633         100 :           atoi[i]=DA_SC4;
+    2634           8 :         } else if(Aname=="3TE") {
+    2635           0 :           atoi[i]=DA_3TE;
+    2636           8 :         } else if(Aname=="5TE") {
+    2637           0 :           atoi[i]=DA_5TE;
+    2638           8 :         } else if(Aname=="TE3") {
+    2639           4 :           atoi[i]=DA_TE3;
+    2640           4 :         } else if(Aname=="TE5") {
+    2641           4 :           atoi[i]=DA_TE5;
+    2642           0 :         } else error("Atom name not known: "+Aname);
+    2643        1272 :       } else if(Rname==" DC") {
+    2644         312 :         if(Aname=="BB1") {
+    2645          52 :           atoi[i]=DC_BB1;
+    2646         260 :         } else if(Aname=="BB2") {
+    2647          52 :           atoi[i]=DC_BB2;
+    2648         208 :         } else if(Aname=="BB3") {
+    2649          52 :           atoi[i]=DC_BB3;
+    2650         156 :         } else if(Aname=="SC1") {
+    2651          52 :           atoi[i]=DC_SC1;
+    2652         104 :         } else if(Aname=="SC2") {
+    2653          52 :           atoi[i]=DC_SC2;
+    2654          52 :         } else if(Aname=="SC3") {
+    2655          52 :           atoi[i]=DC_SC3;
+    2656           0 :         } else if(Aname=="3TE") {
+    2657           0 :           atoi[i]=DC_3TE;
+    2658           0 :         } else if(Aname=="5TE") {
+    2659           0 :           atoi[i]=DC_5TE;
+    2660           0 :         } else if(Aname=="TE3") {
+    2661           0 :           atoi[i]=DC_TE3;
+    2662           0 :         } else if(Aname=="TE5") {
+    2663           0 :           atoi[i]=DC_TE5;
+    2664           0 :         } else error("Atom name not known: "+Aname);
+    2665         960 :       } else if(Rname==" DG") {
+    2666         364 :         if(Aname=="BB1") {
+    2667          52 :           atoi[i]=DG_BB1;
+    2668         312 :         } else if(Aname=="BB2") {
+    2669          52 :           atoi[i]=DG_BB2;
+    2670         260 :         } else if(Aname=="BB3") {
+    2671          52 :           atoi[i]=DG_BB3;
+    2672         208 :         } else if(Aname=="SC1") {
+    2673          52 :           atoi[i]=DG_SC1;
+    2674         156 :         } else if(Aname=="SC2") {
+    2675          52 :           atoi[i]=DG_SC2;
+    2676         104 :         } else if(Aname=="SC3") {
+    2677          52 :           atoi[i]=DG_SC3;
+    2678          52 :         } else if(Aname=="SC4") {
+    2679          52 :           atoi[i]=DG_SC4;
+    2680           0 :         } else if(Aname=="3TE") {
+    2681           0 :           atoi[i]=DG_3TE;
+    2682           0 :         } else if(Aname=="5TE") {
+    2683           0 :           atoi[i]=DG_5TE;
+    2684           0 :         } else if(Aname=="TE3") {
+    2685           0 :           atoi[i]=DG_TE3;
+    2686           0 :         } else if(Aname=="TE5") {
+    2687           0 :           atoi[i]=DG_TE5;
+    2688           0 :         } else error("Atom name not known: "+Aname);
+    2689         596 :       } else if(Rname==" DT") {
+    2690         596 :         if(Aname=="BB1") {
+    2691          96 :           atoi[i]=DT_BB1;
+    2692         500 :         } else if(Aname=="BB2") {
+    2693          96 :           atoi[i]=DT_BB2;
+    2694         404 :         } else if(Aname=="BB3") {
+    2695          96 :           atoi[i]=DT_BB3;
+    2696         308 :         } else if(Aname=="SC1") {
+    2697         100 :           atoi[i]=DT_SC1;
+    2698         208 :         } else if(Aname=="SC2") {
+    2699         100 :           atoi[i]=DT_SC2;
+    2700         108 :         } else if(Aname=="SC3") {
+    2701         100 :           atoi[i]=DT_SC3;
+    2702           8 :         } else if(Aname=="3TE") {
+    2703           0 :           atoi[i]=DT_3TE;
+    2704           8 :         } else if(Aname=="5TE") {
+    2705           0 :           atoi[i]=DT_5TE;
+    2706           8 :         } else if(Aname=="TE3") {
+    2707           4 :           atoi[i]=DT_TE3;
+    2708           4 :         } else if(Aname=="TE5") {
+    2709           4 :           atoi[i]=DT_TE5;
+    2710           0 :         } else error("Atom name not known: "+Aname);
+    2711           0 :       } else error("Residue not known: "+Rname);
+    2712             :     }
+    2713             :   } else {
+    2714           0 :     error("MOLINFO DATA not found\n");
+    2715             :   }
+    2716           8 : }
+    2717             : 
+    2718           6 : void SAXS::getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, std::vector<unsigned> residue_atom)
+    2719             : {
+    2720             : 
+    2721           6 :   parameter_solv[TRP].push_back(60737.60249988003);
+    2722           6 :   parameter_solv[TRP].push_back(-77.75716755173752);
+    2723           6 :   parameter_solv[TRP].push_back(-205962.98557711052);
+    2724           6 :   parameter_solv[TRP].push_back(-62013.46984155453);
+    2725           6 :   parameter_solv[TRP].push_back(680710.7592231638);
+    2726           6 :   parameter_solv[TRP].push_back(-681336.8777362367);
+    2727           6 :   parameter_solv[TRP].push_back(211473.65530642506);
+    2728             : 
+    2729           6 :   parameter_solv[TYR].push_back(46250.80359987982);
+    2730           6 :   parameter_solv[TYR].push_back(-45.8287864681578);
+    2731           6 :   parameter_solv[TYR].push_back(-143872.91752817619);
+    2732           6 :   parameter_solv[TYR].push_back(-39049.68736409533);
+    2733           6 :   parameter_solv[TYR].push_back(441321.71874090104);
+    2734           6 :   parameter_solv[TYR].push_back(-434478.0972346327);
+    2735           6 :   parameter_solv[TYR].push_back(133179.3694641212);
+    2736             : 
+    2737           6 :   parameter_solv[PHE].push_back(42407.164900118914);
+    2738           6 :   parameter_solv[PHE].push_back(-159.1980754191431);
+    2739           6 :   parameter_solv[PHE].push_back(-123847.86192757386);
+    2740           6 :   parameter_solv[PHE].push_back(-41797.69041575073);
+    2741           6 :   parameter_solv[PHE].push_back(380283.7035277073);
+    2742           6 :   parameter_solv[PHE].push_back(-361432.67247521743);
+    2743           6 :   parameter_solv[PHE].push_back(107750.64978068044);
+    2744             : 
+    2745           6 :   parameter_solv[HIP].push_back(24473.47360011923);
+    2746           6 :   parameter_solv[HIP].push_back(-111.64156672747428);
+    2747           6 :   parameter_solv[HIP].push_back(-65826.16993707925);
+    2748           6 :   parameter_solv[HIP].push_back(-23305.91329798928);
+    2749           6 :   parameter_solv[HIP].push_back(194795.11911635034);
+    2750           6 :   parameter_solv[HIP].push_back(-180454.49458095312);
+    2751           6 :   parameter_solv[HIP].push_back(52699.374196745615);
+    2752             : 
+    2753           6 :   parameter_solv[ARG].push_back(34106.70239988039);
+    2754           6 :   parameter_solv[ARG].push_back(152.7472727640246);
+    2755           6 :   parameter_solv[ARG].push_back(-117086.49392248681);
+    2756           6 :   parameter_solv[ARG].push_back(-19664.229479267167);
+    2757           6 :   parameter_solv[ARG].push_back(364454.0909203641);
+    2758           6 :   parameter_solv[ARG].push_back(-382075.8018312776);
+    2759           6 :   parameter_solv[ARG].push_back(122775.75036605193);
+    2760             : 
+    2761           6 :   parameter_solv[LYS].push_back(32292.090000118922);
+    2762           6 :   parameter_solv[LYS].push_back(-111.97371180593888);
+    2763           6 :   parameter_solv[LYS].push_back(-91953.10997619898);
+    2764           6 :   parameter_solv[LYS].push_back(-30690.807047993283);
+    2765           6 :   parameter_solv[LYS].push_back(282092.40760143084);
+    2766           6 :   parameter_solv[LYS].push_back(-269503.2592457489);
+    2767           6 :   parameter_solv[LYS].push_back(80777.81552915688);
+    2768             : 
+    2769           6 :   parameter_solv[CYS].push_back(11352.902500119093);
+    2770           6 :   parameter_solv[CYS].push_back(-45.5226331859686);
+    2771           6 :   parameter_solv[CYS].push_back(-20925.085562607524);
+    2772           6 :   parameter_solv[CYS].push_back(-5662.685408989286);
+    2773           6 :   parameter_solv[CYS].push_back(38559.10376731146);
+    2774           6 :   parameter_solv[CYS].push_back(-27885.23426006181);
+    2775           6 :   parameter_solv[CYS].push_back(6280.15058191397);
+    2776             : 
+    2777           6 :   parameter_solv[ASP].push_back(13511.73760011933);
+    2778           6 :   parameter_solv[ASP].push_back(-59.929111107656595);
+    2779           6 :   parameter_solv[ASP].push_back(-25849.869639655575);
+    2780           6 :   parameter_solv[ASP].push_back(-7541.669448872824);
+    2781           6 :   parameter_solv[ASP].push_back(50760.92045144903);
+    2782           6 :   parameter_solv[ASP].push_back(-37677.87583269734);
+    2783           6 :   parameter_solv[ASP].push_back(8745.7056219399);
+    2784             : 
+    2785           6 :   parameter_solv[GLU].push_back(20443.280400119456);
+    2786           6 :   parameter_solv[GLU].push_back(-113.77561814283207);
+    2787           6 :   parameter_solv[GLU].push_back(-45587.79314626863);
+    2788           6 :   parameter_solv[GLU].push_back(-16187.556837331254);
+    2789           6 :   parameter_solv[GLU].push_back(112609.65830609271);
+    2790           6 :   parameter_solv[GLU].push_back(-93362.05323205091);
+    2791           6 :   parameter_solv[GLU].push_back(24519.557866124724);
+    2792             : 
+    2793           6 :   parameter_solv[ILE].push_back(27858.948100119596);
+    2794           6 :   parameter_solv[ILE].push_back(-159.27355145839834);
+    2795           6 :   parameter_solv[ILE].push_back(-61571.43463039565);
+    2796           6 :   parameter_solv[ILE].push_back(-21324.879474559468);
+    2797           6 :   parameter_solv[ILE].push_back(144070.7572894681);
+    2798           6 :   parameter_solv[ILE].push_back(-115021.81959095894);
+    2799           6 :   parameter_solv[ILE].push_back(28939.085108838968);
+    2800             : 
+    2801           6 :   parameter_solv[LEU].push_back(27858.948100119596);
+    2802           6 :   parameter_solv[LEU].push_back(-165.61892007509647);
+    2803           6 :   parameter_solv[LEU].push_back(-62564.568746500125);
+    2804           6 :   parameter_solv[LEU].push_back(-22465.332149768525);
+    2805           6 :   parameter_solv[LEU].push_back(151616.79489291538);
+    2806           6 :   parameter_solv[LEU].push_back(-122905.6119395393);
+    2807           6 :   parameter_solv[LEU].push_back(31436.664377885514);
+    2808             : 
+    2809           6 :   parameter_solv[MET].push_back(25609.60090011981);
+    2810           6 :   parameter_solv[MET].push_back(-135.38857843066708);
+    2811           6 :   parameter_solv[MET].push_back(-67771.01108177133);
+    2812           6 :   parameter_solv[MET].push_back(-25228.934337676077);
+    2813           6 :   parameter_solv[MET].push_back(199649.95030712147);
+    2814           6 :   parameter_solv[MET].push_back(-182251.94895101967);
+    2815           6 :   parameter_solv[MET].push_back(52502.88444247481);
+    2816             : 
+    2817           6 :   parameter_solv[ASN].push_back(14376.010000119095);
+    2818           6 :   parameter_solv[ASN].push_back(-67.65579048748472);
+    2819           6 :   parameter_solv[ASN].push_back(-28302.87809850141);
+    2820           6 :   parameter_solv[ASN].push_back(-8577.439830985548);
+    2821           6 :   parameter_solv[ASN].push_back(57532.879075695324);
+    2822           6 :   parameter_solv[ASN].push_back(-43261.79286366774);
+    2823           6 :   parameter_solv[ASN].push_back(10186.448634149085);
+    2824             : 
+    2825           6 :   parameter_solv[PRO].push_back(16866.21690011944);
+    2826           6 :   parameter_solv[PRO].push_back(-70.84327801054884);
+    2827           6 :   parameter_solv[PRO].push_back(-31465.84064925844);
+    2828           6 :   parameter_solv[PRO].push_back(-8653.3693368317);
+    2829           6 :   parameter_solv[PRO].push_back(58032.28250733714);
+    2830           6 :   parameter_solv[PRO].push_back(-41521.01146771431);
+    2831           6 :   parameter_solv[PRO].push_back(9184.530596102064);
+    2832             : 
+    2833           6 :   parameter_solv[GLN].push_back(21503.289600119);
+    2834           6 :   parameter_solv[GLN].push_back(-121.30164008960246);
+    2835           6 :   parameter_solv[GLN].push_back(-50468.580981118175);
+    2836           6 :   parameter_solv[GLN].push_back(-18462.49098408308);
+    2837           6 :   parameter_solv[GLN].push_back(132718.44904081387);
+    2838           6 :   parameter_solv[GLN].push_back(-113787.22666510186);
+    2839           6 :   parameter_solv[GLN].push_back(30920.348610969988);
+    2840             : 
+    2841           6 :   parameter_solv[SER].push_back(9181.472400119354);
+    2842           6 :   parameter_solv[SER].push_back(-28.77519915767741);
+    2843           6 :   parameter_solv[SER].push_back(-15205.543144104717);
+    2844           6 :   parameter_solv[SER].push_back(-3377.782176346411);
+    2845           6 :   parameter_solv[SER].push_back(23345.555771001076);
+    2846           6 :   parameter_solv[SER].push_back(-15312.694356014094);
+    2847           6 :   parameter_solv[SER].push_back(3013.8428466148);
+    2848             : 
+    2849           6 :   parameter_solv[THR].push_back(15020.953600119403);
+    2850           6 :   parameter_solv[THR].push_back(-61.91004832631006);
+    2851           6 :   parameter_solv[THR].push_back(-27814.537889259853);
+    2852           6 :   parameter_solv[THR].push_back(-7532.227289701552);
+    2853           6 :   parameter_solv[THR].push_back(50586.30566118166);
+    2854           6 :   parameter_solv[THR].push_back(-35943.866131120165);
+    2855           6 :   parameter_solv[THR].push_back(7880.093558764326);
+    2856             : 
+    2857           6 :   parameter_solv[VAL].push_back(19647.628900119355);
+    2858           6 :   parameter_solv[VAL].push_back(-89.04983250107853);
+    2859           6 :   parameter_solv[VAL].push_back(-38050.09958470928);
+    2860           6 :   parameter_solv[VAL].push_back(-10921.427112288537);
+    2861           6 :   parameter_solv[VAL].push_back(72774.32322962297);
+    2862           6 :   parameter_solv[VAL].push_back(-52689.060152305225);
+    2863           6 :   parameter_solv[VAL].push_back(11806.492503632868);
+    2864             : 
+    2865           6 :   parameter_solv[ALA].push_back(7515.156100119276);
+    2866           6 :   parameter_solv[ALA].push_back(-20.226381685697746);
+    2867           6 :   parameter_solv[ALA].push_back(-11761.841094237716);
+    2868           6 :   parameter_solv[ALA].push_back(-2341.4929468980367);
+    2869           6 :   parameter_solv[ALA].push_back(16545.385777961936);
+    2870           6 :   parameter_solv[ALA].push_back(-10397.175253025776);
+    2871           6 :   parameter_solv[ALA].push_back(1921.5264606725107);
+    2872             : 
+    2873           6 :   parameter_solv[GLY].push_back(3594.002500119159);
+    2874           6 :   parameter_solv[GLY].push_back(-6.910836154887606);
+    2875           6 :   parameter_solv[GLY].push_back(-4937.354220666574);
+    2876           6 :   parameter_solv[GLY].push_back(-785.4549468992149);
+    2877           6 :   parameter_solv[GLY].push_back(5852.854429532936);
+    2878           6 :   parameter_solv[GLY].push_back(-3391.2927115487832);
+    2879           6 :   parameter_solv[GLY].push_back(552.3280571490722);
+    2880             : 
+    2881           6 :   parameter_solv[HIS].push_back(22888.664100119073);
+    2882           6 :   parameter_solv[HIS].push_back(-133.86265270962434);
+    2883           6 :   parameter_solv[HIS].push_back(-57533.51591635819);
+    2884           6 :   parameter_solv[HIS].push_back(-21767.293192014684);
+    2885           6 :   parameter_solv[HIS].push_back(161255.14120001195);
+    2886           6 :   parameter_solv[HIS].push_back(-142176.64081149307);
+    2887           6 :   parameter_solv[HIS].push_back(39642.61185646193);
+    2888             : 
+    2889           6 :   parameter_mix[TRP].push_back(48294.0117571196);
+    2890           6 :   parameter_mix[TRP].push_back(-205.45879626487798);
+    2891           6 :   parameter_mix[TRP].push_back(-148816.1858118254);
+    2892           6 :   parameter_mix[TRP].push_back(-54968.030079609875);
+    2893           6 :   parameter_mix[TRP].push_back(491793.79967057955);
+    2894           6 :   parameter_mix[TRP].push_back(-476312.9117969879);
+    2895           6 :   parameter_mix[TRP].push_back(144159.96165644142);
+    2896             : 
+    2897           6 :   parameter_mix[TYR].push_back(36984.20240312081);
+    2898           6 :   parameter_mix[TYR].push_back(-83.86380083812203);
+    2899           6 :   parameter_mix[TYR].push_back(-108820.52211887162);
+    2900           6 :   parameter_mix[TYR].push_back(-33934.69818901515);
+    2901           6 :   parameter_mix[TYR].push_back(341504.736372253);
+    2902           6 :   parameter_mix[TYR].push_back(-334008.1748614056);
+    2903           6 :   parameter_mix[TYR].push_back(102033.08077851454);
+    2904             : 
+    2905           6 :   parameter_mix[PHE].push_back(32119.469231338233);
+    2906           6 :   parameter_mix[PHE].push_back(-172.96940450568917);
+    2907           6 :   parameter_mix[PHE].push_back(-85831.4326887122);
+    2908           6 :   parameter_mix[PHE].push_back(-33193.32405438845);
+    2909           6 :   parameter_mix[PHE].push_back(262940.64471909316);
+    2910           6 :   parameter_mix[PHE].push_back(-243540.06898907054);
+    2911           6 :   parameter_mix[PHE].push_back(71084.54387480798);
+    2912             : 
+    2913           6 :   parameter_mix[HIP].push_back(22833.36414923898);
+    2914           6 :   parameter_mix[HIP].push_back(-134.0493955562186);
+    2915           6 :   parameter_mix[HIP].push_back(-55325.55607328898);
+    2916           6 :   parameter_mix[HIP].push_back(-21898.314938881984);
+    2917           6 :   parameter_mix[HIP].push_back(159995.6912885654);
+    2918           6 :   parameter_mix[HIP].push_back(-142968.19796084083);
+    2919           6 :   parameter_mix[HIP].push_back(40417.44581470003);
+    2920             : 
+    2921           6 :   parameter_mix[ARG].push_back(31385.401600920715);
+    2922           6 :   parameter_mix[ARG].push_back(36.114094042884254);
+    2923           6 :   parameter_mix[ARG].push_back(-103730.44467490204);
+    2924           6 :   parameter_mix[ARG].push_back(-27036.249157905615);
+    2925           6 :   parameter_mix[ARG].push_back(347011.0339314942);
+    2926           6 :   parameter_mix[ARG].push_back(-358879.9736802336);
+    2927           6 :   parameter_mix[ARG].push_back(114432.18361399164);
+    2928             : 
+    2929           6 :   parameter_mix[LYS].push_back(25511.35812671878);
+    2930           6 :   parameter_mix[LYS].push_back(-130.4381491986372);
+    2931           6 :   parameter_mix[LYS].push_back(-69258.61236879184);
+    2932           6 :   parameter_mix[LYS].push_back(-27066.36783798707);
+    2933           6 :   parameter_mix[LYS].push_back(220092.65231165203);
+    2934           6 :   parameter_mix[LYS].push_back(-207794.5056092443);
+    2935           6 :   parameter_mix[LYS].push_back(61665.57004630315);
+    2936             : 
+    2937           6 :   parameter_mix[CYS].push_back(11505.517261618916);
+    2938           6 :   parameter_mix[CYS].push_back(-33.60468076978334);
+    2939           6 :   parameter_mix[CYS].push_back(-18328.882710004465);
+    2940           6 :   parameter_mix[CYS].push_back(-3956.9113649567626);
+    2941           6 :   parameter_mix[CYS].push_back(27546.35146501212);
+    2942           6 :   parameter_mix[CYS].push_back(-18024.826330595406);
+    2943           6 :   parameter_mix[CYS].push_back(3551.2207387570024);
+    2944             : 
+    2945           6 :   parameter_mix[ASP].push_back(13713.858501879382);
+    2946           6 :   parameter_mix[ASP].push_back(-51.33286241257164);
+    2947           6 :   parameter_mix[ASP].push_back(-23807.8549764091);
+    2948           6 :   parameter_mix[ASP].push_back(-6153.667315935503);
+    2949           6 :   parameter_mix[ASP].push_back(41296.118377286424);
+    2950           6 :   parameter_mix[ASP].push_back(-28740.28391184026);
+    2951           6 :   parameter_mix[ASP].push_back(6132.671533319127);
+    2952             : 
+    2953           6 :   parameter_mix[GLU].push_back(19156.03660739947);
+    2954           6 :   parameter_mix[GLU].push_back(-110.90600703589246);
+    2955           6 :   parameter_mix[GLU].push_back(-40319.3351514524);
+    2956           6 :   parameter_mix[GLU].push_back(-14679.813393816446);
+    2957           6 :   parameter_mix[GLU].push_back(96769.28565573556);
+    2958           6 :   parameter_mix[GLU].push_back(-77909.09315520026);
+    2959           6 :   parameter_mix[GLU].push_back(19770.047062759568);
+    2960             : 
+    2961           6 :   parameter_mix[ILE].push_back(20693.06215917923);
+    2962           6 :   parameter_mix[ILE].push_back(-102.87208880594848);
+    2963           6 :   parameter_mix[ILE].push_back(-41080.44036311675);
+    2964           6 :   parameter_mix[ILE].push_back(-12874.439649378206);
+    2965           6 :   parameter_mix[ILE].push_back(84947.33147117581);
+    2966           6 :   parameter_mix[ILE].push_back(-63779.07871450237);
+    2967           6 :   parameter_mix[ILE].push_back(14938.919981690511);
+    2968             : 
+    2969           6 :   parameter_mix[LEU].push_back(20693.062159179233);
+    2970           6 :   parameter_mix[LEU].push_back(-114.09539845409269);
+    2971           6 :   parameter_mix[LEU].push_back(-42417.3431074524);
+    2972           6 :   parameter_mix[LEU].push_back(-14393.801090829746);
+    2973           6 :   parameter_mix[LEU].push_back(93640.48403643962);
+    2974           6 :   parameter_mix[LEU].push_back(-71990.10354816525);
+    2975           6 :   parameter_mix[LEU].push_back(17299.01082057651);
+    2976             : 
+    2977           6 :   parameter_mix[MET].push_back(22400.800002738917);
+    2978           6 :   parameter_mix[MET].push_back(-138.14469221559762);
+    2979           6 :   parameter_mix[MET].push_back(-53013.97694299946);
+    2980           6 :   parameter_mix[MET].push_back(-21079.899452619244);
+    2981           6 :   parameter_mix[MET].push_back(148607.1089339919);
+    2982           6 :   parameter_mix[MET].push_back(-129827.63962878387);
+    2983           6 :   parameter_mix[MET].push_back(35882.3297822684);
+    2984             : 
+    2985           6 :   parameter_mix[ASN].push_back(14384.287416519475);
+    2986           6 :   parameter_mix[ASN].push_back(-55.24976731179147);
+    2987           6 :   parameter_mix[ASN].push_back(-25372.978199926372);
+    2988           6 :   parameter_mix[ASN].push_back(-6646.452004616925);
+    2989           6 :   parameter_mix[ASN].push_back(44594.5027556148);
+    2990           6 :   parameter_mix[ASN].push_back(-31202.511764907107);
+    2991           6 :   parameter_mix[ASN].push_back(6703.764135873442);
+    2992             : 
+    2993           6 :   parameter_mix[PRO].push_back(13503.797145659117);
+    2994           6 :   parameter_mix[PRO].push_back(-38.58316011847087);
+    2995           6 :   parameter_mix[PRO].push_back(-21446.17847324053);
+    2996           6 :   parameter_mix[PRO].push_back(-4480.55896170459);
+    2997           6 :   parameter_mix[PRO].push_back(31274.287350083254);
+    2998           6 :   parameter_mix[PRO].push_back(-19984.249229169505);
+    2999           6 :   parameter_mix[PRO].push_back(3782.272312712745);
+    3000             : 
+    3001           6 :   parameter_mix[GLN].push_back(19938.23724683901);
+    3002           6 :   parameter_mix[GLN].push_back(-121.24884503048865);
+    3003           6 :   parameter_mix[GLN].push_back(-43928.589472297834);
+    3004           6 :   parameter_mix[GLN].push_back(-16805.069757865473);
+    3005           6 :   parameter_mix[GLN].push_back(112831.61348476357);
+    3006           6 :   parameter_mix[GLN].push_back(-93979.08819184235);
+    3007           6 :   parameter_mix[GLN].push_back(24741.563493163732);
+    3008             : 
+    3009           6 :   parameter_mix[SER].push_back(8813.67020471935);
+    3010           6 :   parameter_mix[SER].push_back(-18.291615317790175);
+    3011           6 :   parameter_mix[SER].push_back(-12585.074732466266);
+    3012           6 :   parameter_mix[SER].push_back(-2064.454891600786);
+    3013           6 :   parameter_mix[SER].push_back(15273.905065790364);
+    3014           6 :   parameter_mix[SER].push_back(-8813.056005263466);
+    3015           6 :   parameter_mix[SER].push_back(1404.9812302289881);
+    3016             : 
+    3017           6 :   parameter_mix[THR].push_back(13233.997179639062);
+    3018           6 :   parameter_mix[THR].push_back(-39.40454157416847);
+    3019           6 :   parameter_mix[THR].push_back(-21430.58717233547);
+    3020           6 :   parameter_mix[THR].push_back(-4566.332853710876);
+    3021           6 :   parameter_mix[THR].push_back(31717.497780073558);
+    3022           6 :   parameter_mix[THR].push_back(-20299.614304281313);
+    3023           6 :   parameter_mix[THR].push_back(3837.207224537505);
+    3024             : 
+    3025           6 :   parameter_mix[VAL].push_back(15135.438016299158);
+    3026           6 :   parameter_mix[VAL].push_back(-51.415141550353205);
+    3027           6 :   parameter_mix[VAL].push_back(-25859.078442379723);
+    3028           6 :   parameter_mix[VAL].push_back(-6007.697291593915);
+    3029           6 :   parameter_mix[VAL].push_back(40997.969600345634);
+    3030           6 :   parameter_mix[VAL].push_back(-27036.257386814148);
+    3031           6 :   parameter_mix[VAL].push_back(5328.922363811635);
+    3032             : 
+    3033           6 :   parameter_mix[ALA].push_back(6586.942863819189);
+    3034           6 :   parameter_mix[ALA].push_back(-10.96713559950907);
+    3035           6 :   parameter_mix[ALA].push_back(-8758.836131731925);
+    3036           6 :   parameter_mix[ALA].push_back(-1223.1723720922605);
+    3037           6 :   parameter_mix[ALA].push_back(9475.182453543037);
+    3038           6 :   parameter_mix[ALA].push_back(-5124.611191433804);
+    3039           6 :   parameter_mix[ALA].push_back(721.7625962949869);
+    3040             : 
+    3041           6 :   parameter_mix[GLY].push_back(3596.0718542192762);
+    3042           6 :   parameter_mix[GLY].push_back(-4.079285964028122);
+    3043           6 :   parameter_mix[GLY].push_back(-4089.4217504382686);
+    3044           6 :   parameter_mix[GLY].push_back(-450.9650932154967);
+    3045           6 :   parameter_mix[GLY].push_back(3737.026778223427);
+    3046           6 :   parameter_mix[GLY].push_back(-1862.9856575810572);
+    3047           6 :   parameter_mix[GLY].push_back(222.97288276257262);
+    3048             : 
+    3049           6 :   parameter_mix[HIS].push_back(21779.124723299232);
+    3050           6 :   parameter_mix[HIS].push_back(-131.4603421188538);
+    3051           6 :   parameter_mix[HIS].push_back(-49068.74667421681);
+    3052           6 :   parameter_mix[HIS].push_back(-18685.909496392127);
+    3053           6 :   parameter_mix[HIS].push_back(127724.60792384286);
+    3054           6 :   parameter_mix[HIS].push_back(-107419.22159440348);
+    3055           6 :   parameter_mix[HIS].push_back(28577.228634530744);
+    3056             : 
+    3057           6 :   parameter_vac[TRP].push_back(9599.949107368187);
+    3058           6 :   parameter_vac[TRP].push_back(-66.35331786175249);
+    3059           6 :   parameter_vac[TRP].push_back(-26311.640290970638);
+    3060           6 :   parameter_vac[TRP].push_back(-11577.314600529338);
+    3061           6 :   parameter_vac[TRP].push_back(85847.52554160352);
+    3062           6 :   parameter_vac[TRP].push_back(-79417.17065742958);
+    3063           6 :   parameter_vac[TRP].push_back(23090.348430572863);
+    3064             : 
+    3065           6 :   parameter_vac[TYR].push_back(7393.553846412945);
+    3066           6 :   parameter_vac[TYR].push_back(-27.51954035778316);
+    3067           6 :   parameter_vac[TYR].push_back(-20329.10485615286);
+    3068           6 :   parameter_vac[TYR].push_back(-7444.276340508767);
+    3069           6 :   parameter_vac[TYR].push_back(66343.22315132803);
+    3070           6 :   parameter_vac[TYR].push_back(-64470.58721639446);
+    3071           6 :   parameter_vac[TYR].push_back(19614.63563898146);
+    3072             : 
+    3073           6 :   parameter_vac[PHE].push_back(6081.874997705279);
+    3074           6 :   parameter_vac[PHE].push_back(-40.474695969500104);
+    3075           6 :   parameter_vac[PHE].push_back(-14354.627390498901);
+    3076           6 :   parameter_vac[PHE].push_back(-6156.69750315959);
+    3077           6 :   parameter_vac[PHE].push_back(42580.84239395237);
+    3078           6 :   parameter_vac[PHE].push_back(-37704.09749809582);
+    3079           6 :   parameter_vac[PHE].push_back(10543.005717478625);
+    3080             : 
+    3081           6 :   parameter_vac[HIP].push_back(5325.791987063724);
+    3082           6 :   parameter_vac[HIP].push_back(-35.512112257530156);
+    3083           6 :   parameter_vac[HIP].push_back(-11488.443296477566);
+    3084           6 :   parameter_vac[HIP].push_back(-4916.724935318093);
+    3085           6 :   parameter_vac[HIP].push_back(32134.338675979947);
+    3086           6 :   parameter_vac[HIP].push_back(-27388.387595464188);
+    3087           6 :   parameter_vac[HIP].push_back(7359.899986748838);
+    3088             : 
+    3089           6 :   parameter_vac[ARG].push_back(7220.306892248294);
+    3090           6 :   parameter_vac[ARG].push_back(-20.65912886190997);
+    3091           6 :   parameter_vac[ARG].push_back(-22700.70129646048);
+    3092           6 :   parameter_vac[ARG].push_back(-8696.901551172636);
+    3093           6 :   parameter_vac[ARG].push_back(83641.36257312517);
+    3094           6 :   parameter_vac[ARG].push_back(-85237.33676336925);
+    3095           6 :   parameter_vac[ARG].push_back(26899.162688310953);
+    3096             : 
+    3097           6 :   parameter_vac[LYS].push_back(5038.613120729022);
+    3098           6 :   parameter_vac[LYS].push_back(-34.08366887546492);
+    3099           6 :   parameter_vac[LYS].push_back(-12812.921120433106);
+    3100           6 :   parameter_vac[LYS].push_back(-5843.761329082788);
+    3101           6 :   parameter_vac[LYS].push_back(42419.08427856609);
+    3102           6 :   parameter_vac[LYS].push_back(-39460.49038159249);
+    3103           6 :   parameter_vac[LYS].push_back(11542.320830663035);
+    3104             : 
+    3105           6 :   parameter_vac[CYS].push_back(2915.0458981763995);
+    3106           6 :   parameter_vac[CYS].push_back(-5.380571839804511);
+    3107           6 :   parameter_vac[CYS].push_back(-3865.366285883624);
+    3108           6 :   parameter_vac[CYS].push_back(-602.3275271136284);
+    3109           6 :   parameter_vac[CYS].push_back(4524.133086072617);
+    3110           6 :   parameter_vac[CYS].push_back(-2537.87137720241);
+    3111           6 :   parameter_vac[CYS].push_back(381.52870758240016);
+    3112             : 
+    3113           6 :   parameter_vac[ASP].push_back(3479.750728224898);
+    3114           6 :   parameter_vac[ASP].push_back(-10.33897891836596);
+    3115           6 :   parameter_vac[ASP].push_back(-5382.628188436401);
+    3116           6 :   parameter_vac[ASP].push_back(-1183.8060939576694);
+    3117           6 :   parameter_vac[ASP].push_back(8100.082378727997);
+    3118           6 :   parameter_vac[ASP].push_back(-5162.630696148773);
+    3119           6 :   parameter_vac[ASP].push_back(958.993022379732);
+    3120             : 
+    3121           6 :   parameter_vac[GLU].push_back(4487.461543955491);
+    3122           6 :   parameter_vac[GLU].push_back(-26.671865751817936);
+    3123           6 :   parameter_vac[GLU].push_back(-8829.738168429001);
+    3124           6 :   parameter_vac[GLU].push_back(-3297.668395415257);
+    3125           6 :   parameter_vac[GLU].push_back(20686.457747123466);
+    3126           6 :   parameter_vac[GLU].push_back(-16030.814134196151);
+    3127           6 :   parameter_vac[GLU].push_back(3858.4457728083275);
+    3128             : 
+    3129           6 :   parameter_vac[ILE].push_back(3842.5968201937776);
+    3130           6 :   parameter_vac[ILE].push_back(-13.848165050578492);
+    3131           6 :   parameter_vac[ILE].push_back(-6480.062699452774);
+    3132           6 :   parameter_vac[ILE].push_back(-1636.3888925440413);
+    3133           6 :   parameter_vac[ILE].push_back(10967.333210698738);
+    3134           6 :   parameter_vac[ILE].push_back(-7483.704914714421);
+    3135           6 :   parameter_vac[ILE].push_back(1548.5696047594895);
+    3136             : 
+    3137           6 :   parameter_vac[LEU].push_back(3842.5968201937785);
+    3138           6 :   parameter_vac[LEU].push_back(-16.2745108270949);
+    3139           6 :   parameter_vac[LEU].push_back(-6807.110269770606);
+    3140           6 :   parameter_vac[LEU].push_back(-1926.6303434106014);
+    3141           6 :   parameter_vac[LEU].push_back(12577.952756390941);
+    3142           6 :   parameter_vac[LEU].push_back(-8829.40489330961);
+    3143           6 :   parameter_vac[LEU].push_back(1882.919316016889);
+    3144             : 
+    3145           6 :   parameter_vac[MET].push_back(4898.512892967389);
+    3146           6 :   parameter_vac[MET].push_back(-30.588244886468207);
+    3147           6 :   parameter_vac[MET].push_back(-10159.093665859045);
+    3148           6 :   parameter_vac[MET].push_back(-4025.0261508449653);
+    3149           6 :   parameter_vac[MET].push_back(26007.394369425827);
+    3150           6 :   parameter_vac[MET].push_back(-21199.218680206573);
+    3151           6 :   parameter_vac[MET].push_back(5423.004225853842);
+    3152             : 
+    3153           6 :   parameter_vac[ASN].push_back(3598.1423998115492);
+    3154           6 :   parameter_vac[ASN].push_back(-10.357995638888545);
+    3155           6 :   parameter_vac[ASN].push_back(-5565.603011562138);
+    3156           6 :   parameter_vac[ASN].push_back(-1190.3294930971967);
+    3157           6 :   parameter_vac[ASN].push_back(8227.920711951123);
+    3158           6 :   parameter_vac[ASN].push_back(-5222.61541118056);
+    3159           6 :   parameter_vac[ASN].push_back(968.593406702772);
+    3160             : 
+    3161           6 :   parameter_vac[PRO].push_back(2702.925890807494);
+    3162           6 :   parameter_vac[PRO].push_back(-4.11690159421177);
+    3163           6 :   parameter_vac[PRO].push_back(-3395.325331307625);
+    3164           6 :   parameter_vac[PRO].push_back(-458.95242128002894);
+    3165           6 :   parameter_vac[PRO].push_back(3584.3640448715823);
+    3166           6 :   parameter_vac[PRO].push_back(-1921.4140769384692);
+    3167           6 :   parameter_vac[PRO].push_back(267.08577848319516);
+    3168             : 
+    3169           6 :   parameter_vac[GLN].push_back(4621.773132292556);
+    3170           6 :   parameter_vac[GLN].push_back(-29.511778489038818);
+    3171           6 :   parameter_vac[GLN].push_back(-9486.077450010192);
+    3172           6 :   parameter_vac[GLN].push_back(-3768.5756897489828);
+    3173           6 :   parameter_vac[GLN].push_back(23828.07111260487);
+    3174           6 :   parameter_vac[GLN].push_back(-19110.205836780202);
+    3175           6 :   parameter_vac[GLN].push_back(4791.718204894083);
+    3176             : 
+    3177           6 :   parameter_vac[SER].push_back(2115.1504654043965);
+    3178           6 :   parameter_vac[SER].push_back(-2.4158378234251234);
+    3179           6 :   parameter_vac[SER].push_back(-2488.1131972903822);
+    3180           6 :   parameter_vac[SER].push_back(-263.64072945387693);
+    3181           6 :   parameter_vac[SER].push_back(2251.376687850687);
+    3182           6 :   parameter_vac[SER].push_back(-1066.0790768852626);
+    3183           6 :   parameter_vac[SER].push_back(105.5155397911316);
+    3184             : 
+    3185           6 :   parameter_vac[THR].push_back(2914.9061707158835);
+    3186           6 :   parameter_vac[THR].push_back(-5.032844592364407);
+    3187           6 :   parameter_vac[THR].push_back(-3903.2546253886653);
+    3188           6 :   parameter_vac[THR].push_back(-559.4734271244915);
+    3189           6 :   parameter_vac[THR].push_back(4315.044828297787);
+    3190           6 :   parameter_vac[THR].push_back(-2331.211908177365);
+    3191           6 :   parameter_vac[THR].push_back(323.76849758109853);
+    3192             : 
+    3193           6 :   parameter_vac[VAL].push_back(2914.8744247581953);
+    3194           6 :   parameter_vac[VAL].push_back(-5.847217106105881);
+    3195           6 :   parameter_vac[VAL].push_back(-4096.370479502377);
+    3196           6 :   parameter_vac[VAL].push_back(-655.2917606620404);
+    3197           6 :   parameter_vac[VAL].push_back(4888.77261250007);
+    3198           6 :   parameter_vac[VAL].push_back(-2765.7552774385167);
+    3199           6 :   parameter_vac[VAL].push_back(421.9081598033515);
+    3200             : 
+    3201           6 :   parameter_vac[ALA].push_back(1443.3438146824446);
+    3202           6 :   parameter_vac[ALA].push_back(-1.1234573178567506);
+    3203           6 :   parameter_vac[ALA].push_back(-1492.4547663363514);
+    3204           6 :   parameter_vac[ALA].push_back(-121.47935619968672);
+    3205           6 :   parameter_vac[ALA].push_back(1139.689871538201);
+    3206           6 :   parameter_vac[ALA].push_back(-483.8336547914466);
+    3207           6 :   parameter_vac[ALA].push_back(32.48231950404626);
+    3208             : 
+    3209           6 :   parameter_vac[GLY].push_back(899.5356000422925);
+    3210           6 :   parameter_vac[GLY].push_back(-0.5200880084066986);
+    3211           6 :   parameter_vac[GLY].push_back(-787.5892053280859);
+    3212           6 :   parameter_vac[GLY].push_back(-56.07596224884467);
+    3213           6 :   parameter_vac[GLY].push_back(546.4212287680981);
+    3214           6 :   parameter_vac[GLY].push_back(-222.2667666932616);
+    3215           6 :   parameter_vac[GLY].push_back(12.474587265791476);
+    3216             : 
+    3217           6 :   parameter_vac[HIS].push_back(5180.842705000207);
+    3218           6 :   parameter_vac[HIS].push_back(-29.578973475252766);
+    3219           6 :   parameter_vac[HIS].push_back(-10323.417251934066);
+    3220           6 :   parameter_vac[HIS].push_back(-3788.977215582307);
+    3221           6 :   parameter_vac[HIS].push_back(24427.720792289427);
+    3222           6 :   parameter_vac[HIS].push_back(-19307.35836837878);
+    3223           6 :   parameter_vac[HIS].push_back(4780.831414992477);
+    3224             : 
+    3225             :   // NUCLEIC ACIDS
+    3226             : 
+    3227           6 :   parameter_solv[BB_PO2].push_back(575.5201001192197);
+    3228           6 :   parameter_solv[BB_PO2].push_back(-0.6126595489733868);
+    3229           6 :   parameter_solv[BB_PO2].push_back(-623.3371092254897);
+    3230           6 :   parameter_solv[BB_PO2].push_back(-68.05795957022156);
+    3231           6 :   parameter_solv[BB_PO2].push_back(561.8052621243662);
+    3232           6 :   parameter_solv[BB_PO2].push_back(-283.39573309540344);
+    3233           6 :   parameter_solv[BB_PO2].push_back(35.55001698010027);
+    3234             : 
+    3235           6 :   parameter_solv[BB_DNA].push_back(21211.009600118316);
+    3236           6 :   parameter_solv[BB_DNA].push_back(-90.18805990529991);
+    3237           6 :   parameter_solv[BB_DNA].push_back(-39731.1337351215);
+    3238           6 :   parameter_solv[BB_DNA].push_back(-10920.373563712878);
+    3239           6 :   parameter_solv[BB_DNA].push_back(72882.21702424977);
+    3240           6 :   parameter_solv[BB_DNA].push_back(-51747.487078112754);
+    3241           6 :   parameter_solv[BB_DNA].push_back(11308.67842901876);
+    3242             : 
+    3243           6 :   parameter_solv[BB_DNA_5].push_back(22737.624100119025);
+    3244           6 :   parameter_solv[BB_DNA_5].push_back(-102.72714886664163);
+    3245           6 :   parameter_solv[BB_DNA_5].push_back(-43685.329677789705);
+    3246           6 :   parameter_solv[BB_DNA_5].push_back(-12564.259374093454);
+    3247           6 :   parameter_solv[BB_DNA_5].push_back(83454.87540484876);
+    3248           6 :   parameter_solv[BB_DNA_5].push_back(-60367.15652138888);
+    3249           6 :   parameter_solv[BB_DNA_5].push_back(13507.33372986899);
+    3250             : 
+    3251           6 :   parameter_solv[BB_DNA_3].push_back(22737.62410011902);
+    3252           6 :   parameter_solv[BB_DNA_3].push_back(-101.57816684452263);
+    3253           6 :   parameter_solv[BB_DNA_3].push_back(-43488.53670557616);
+    3254           6 :   parameter_solv[BB_DNA_3].push_back(-12345.056184958417);
+    3255           6 :   parameter_solv[BB_DNA_3].push_back(81963.5236411489);
+    3256           6 :   parameter_solv[BB_DNA_3].push_back(-58791.59443618196);
+    3257           6 :   parameter_solv[BB_DNA_3].push_back(13003.199362335576);
+    3258             : 
+    3259           6 :   parameter_solv[BB_RNA].push_back(23953.752900120977);
+    3260           6 :   parameter_solv[BB_RNA].push_back(-117.35779348824401);
+    3261           6 :   parameter_solv[BB_RNA].push_back(-47644.41735332837);
+    3262           6 :   parameter_solv[BB_RNA].push_back(-14641.556643789863);
+    3263           6 :   parameter_solv[BB_RNA].push_back(96893.48627050382);
+    3264           6 :   parameter_solv[BB_RNA].push_back(-72249.62534169314);
+    3265           6 :   parameter_solv[BB_RNA].push_back(16792.05552105538);
+    3266             : 
+    3267           6 :   parameter_solv[BB_RNA_5].push_back(25574.406400119024);
+    3268           6 :   parameter_solv[BB_RNA_5].push_back(-131.99642772933734);
+    3269           6 :   parameter_solv[BB_RNA_5].push_back(-52136.51404531249);
+    3270           6 :   parameter_solv[BB_RNA_5].push_back(-16682.14273917604);
+    3271           6 :   parameter_solv[BB_RNA_5].push_back(110278.019216394);
+    3272           6 :   parameter_solv[BB_RNA_5].push_back(-83715.92027818545);
+    3273           6 :   parameter_solv[BB_RNA_5].push_back(19875.891337706045);
+    3274             : 
+    3275           6 :   parameter_solv[BB_RNA_3].push_back(25574.406400119024);
+    3276           6 :   parameter_solv[BB_RNA_3].push_back(-127.96875237036166);
+    3277           6 :   parameter_solv[BB_RNA_3].push_back(-51407.183917584385);
+    3278           6 :   parameter_solv[BB_RNA_3].push_back(-15922.900669975606);
+    3279           6 :   parameter_solv[BB_RNA_3].push_back(105078.58889106264);
+    3280           6 :   parameter_solv[BB_RNA_3].push_back(-78289.16276190648);
+    3281           6 :   parameter_solv[BB_RNA_3].push_back(18156.83214344118);
+    3282             : 
+    3283           6 :   parameter_solv[BASE_A].push_back(13282.562500119211);
+    3284           6 :   parameter_solv[BASE_A].push_back(-76.45124168404048);
+    3285           6 :   parameter_solv[BASE_A].push_back(-28376.06994108963);
+    3286           6 :   parameter_solv[BASE_A].push_back(-9972.910773722022);
+    3287           6 :   parameter_solv[BASE_A].push_back(65873.86341939073);
+    3288           6 :   parameter_solv[BASE_A].push_back(-52064.33492910885);
+    3289           6 :   parameter_solv[BASE_A].push_back(12931.608989412513);
+    3290             : 
+    3291           6 :   parameter_solv[BASE_C].push_back(10600.76160011891);
+    3292           6 :   parameter_solv[BASE_C].push_back(-49.1670871249108);
+    3293           6 :   parameter_solv[BASE_C].push_back(-20239.818742072875);
+    3294           6 :   parameter_solv[BASE_C].push_back(-6020.278780090207);
+    3295           6 :   parameter_solv[BASE_C].push_back(39632.13288981881);
+    3296           6 :   parameter_solv[BASE_C].push_back(-28954.779736165576);
+    3297           6 :   parameter_solv[BASE_C].push_back(6551.541109526305);
+    3298             : 
+    3299           6 :   parameter_solv[BASE_G].push_back(15470.384400119934);
+    3300           6 :   parameter_solv[BASE_G].push_back(-93.8013620200972);
+    3301           6 :   parameter_solv[BASE_G].push_back(-36188.29687013545);
+    3302           6 :   parameter_solv[BASE_G].push_back(-13717.685098209471);
+    3303           6 :   parameter_solv[BASE_G].push_back(95658.18473657136);
+    3304           6 :   parameter_solv[BASE_G].push_back(-81262.37811451119);
+    3305           6 :   parameter_solv[BASE_G].push_back(21841.903930943085);
+    3306             : 
+    3307           6 :   parameter_solv[BASE_T].push_back(17210.81610011936);
+    3308           6 :   parameter_solv[BASE_T].push_back(-93.10189802920208);
+    3309           6 :   parameter_solv[BASE_T].push_back(-36466.51927689957);
+    3310           6 :   parameter_solv[BASE_T].push_back(-12425.55615716932);
+    3311           6 :   parameter_solv[BASE_T].push_back(83847.427808925);
+    3312           6 :   parameter_solv[BASE_T].push_back(-66735.64997846584);
+    3313           6 :   parameter_solv[BASE_T].push_back(16757.3463987507);
+    3314             : 
+    3315           6 :   parameter_solv[BASE_U].push_back(10909.802500119395);
+    3316           6 :   parameter_solv[BASE_U].push_back(-46.17712672768298);
+    3317           6 :   parameter_solv[BASE_U].push_back(-20149.67695512526);
+    3318           6 :   parameter_solv[BASE_U].push_back(-5590.242961204435);
+    3319           6 :   parameter_solv[BASE_U].push_back(37169.2740983132);
+    3320           6 :   parameter_solv[BASE_U].push_back(-26475.631627167604);
+    3321           6 :   parameter_solv[BASE_U].push_back(5808.201015156168);
+    3322             : 
+    3323           6 :   parameter_mix[BB_PO2].push_back(1487.2888381188868);
+    3324           6 :   parameter_mix[BB_PO2].push_back(-0.6155376265599789);
+    3325           6 :   parameter_mix[BB_PO2].push_back(-1181.5076027691764);
+    3326           6 :   parameter_mix[BB_PO2].push_back(-66.25027450710594);
+    3327           6 :   parameter_mix[BB_PO2].push_back(697.0421991965113);
+    3328           6 :   parameter_mix[BB_PO2].push_back(-261.8559466354847);
+    3329           6 :   parameter_mix[BB_PO2].push_back(9.974337082362194);
+    3330             : 
+    3331           6 :   parameter_mix[BB_DNA].push_back(17766.29474499878);
+    3332           6 :   parameter_mix[BB_DNA].push_back(-48.97330188566253);
+    3333           6 :   parameter_mix[BB_DNA].push_back(-28199.563596327207);
+    3334           6 :   parameter_mix[BB_DNA].push_back(-5623.82085602494);
+    3335           6 :   parameter_mix[BB_DNA].push_back(39646.22954828498);
+    3336           6 :   parameter_mix[BB_DNA].push_back(-24658.81157651943);
+    3337           6 :   parameter_mix[BB_DNA].push_back(4453.73906293146);
+    3338             : 
+    3339           6 :   parameter_mix[BB_DNA_5].push_back(18696.09744203927);
+    3340           6 :   parameter_mix[BB_DNA_5].push_back(-56.29408880833802);
+    3341           6 :   parameter_mix[BB_DNA_5].push_back(-30486.108599707608);
+    3342           6 :   parameter_mix[BB_DNA_5].push_back(-6524.195857141158);
+    3343           6 :   parameter_mix[BB_DNA_5].push_back(45280.80142686446);
+    3344           6 :   parameter_mix[BB_DNA_5].push_back(-29007.98616567993);
+    3345           6 :   parameter_mix[BB_DNA_5].push_back(5488.566965501818);
+    3346             : 
+    3347           6 :   parameter_mix[BB_DNA_3].push_back(18696.097442039274);
+    3348           6 :   parameter_mix[BB_DNA_3].push_back(-55.5645003501971);
+    3349           6 :   parameter_mix[BB_DNA_3].push_back(-30422.262113654506);
+    3350           6 :   parameter_mix[BB_DNA_3].push_back(-6409.659659309089);
+    3351           6 :   parameter_mix[BB_DNA_3].push_back(44605.76043515699);
+    3352           6 :   parameter_mix[BB_DNA_3].push_back(-28295.62152988411);
+    3353           6 :   parameter_mix[BB_DNA_3].push_back(5262.5765863484);
+    3354             : 
+    3355           6 :   parameter_mix[BB_RNA].push_back(21356.177105457366);
+    3356           6 :   parameter_mix[BB_RNA].push_back(-76.73490647754872);
+    3357           6 :   parameter_mix[BB_RNA].push_back(-36845.234814782816);
+    3358           6 :   parameter_mix[BB_RNA].push_back(-9066.559625582728);
+    3359           6 :   parameter_mix[BB_RNA].push_back(61167.998793390485);
+    3360           6 :   parameter_mix[BB_RNA].push_back(-41467.23384423218);
+    3361           6 :   parameter_mix[BB_RNA].push_back(8518.937793863257);
+    3362             : 
+    3363           6 :   parameter_mix[BB_RNA_5].push_back(22386.63276427916);
+    3364           6 :   parameter_mix[BB_RNA_5].push_back(-85.70426456933487);
+    3365           6 :   parameter_mix[BB_RNA_5].push_back(-39490.50298502025);
+    3366           6 :   parameter_mix[BB_RNA_5].push_back(-10223.702594972712);
+    3367           6 :   parameter_mix[BB_RNA_5].push_back(68450.60459618448);
+    3368           6 :   parameter_mix[BB_RNA_5].push_back(-47409.91098159006);
+    3369           6 :   parameter_mix[BB_RNA_5].push_back(10031.136138513202);
+    3370             : 
+    3371           6 :   parameter_mix[BB_RNA_3].push_back(22386.63276427916);
+    3372           6 :   parameter_mix[BB_RNA_3].push_back(-81.93760812351479);
+    3373           6 :   parameter_mix[BB_RNA_3].push_back(-39031.70571520093);
+    3374           6 :   parameter_mix[BB_RNA_3].push_back(-9666.316086142708);
+    3375           6 :   parameter_mix[BB_RNA_3].push_back(65120.07128126262);
+    3376           6 :   parameter_mix[BB_RNA_3].push_back(-44110.13603681317);
+    3377           6 :   parameter_mix[BB_RNA_3].push_back(9036.76498256983);
+    3378             : 
+    3379           6 :   parameter_mix[BASE_A].push_back(15897.31116611889);
+    3380           6 :   parameter_mix[BASE_A].push_back(-67.86385832953485);
+    3381           6 :   parameter_mix[BASE_A].push_back(-28851.754660951636);
+    3382           6 :   parameter_mix[BASE_A].push_back(-8144.431687170413);
+    3383           6 :   parameter_mix[BASE_A].push_back(53606.39082954489);
+    3384           6 :   parameter_mix[BASE_A].push_back(-38083.51243782253);
+    3385           6 :   parameter_mix[BASE_A].push_back(8293.47107993253);
+    3386             : 
+    3387           6 :   parameter_mix[BASE_C].push_back(11733.2828871599);
+    3388           6 :   parameter_mix[BASE_C].push_back(-38.76775400274115);
+    3389           6 :   parameter_mix[BASE_C].push_back(-19318.84666423464);
+    3390           6 :   parameter_mix[BASE_C].push_back(-4507.915522704176);
+    3391           6 :   parameter_mix[BASE_C].push_back(30576.57671286052);
+    3392           6 :   parameter_mix[BASE_C].push_back(-20132.46696910844);
+    3393           6 :   parameter_mix[BASE_C].push_back(3947.8727087996162);
+    3394             : 
+    3395           6 :   parameter_mix[BASE_G].push_back(19146.612417237808);
+    3396           6 :   parameter_mix[BASE_G].push_back(-102.37046638004914);
+    3397           6 :   parameter_mix[BASE_G].push_back(-38718.96478190546);
+    3398           6 :   parameter_mix[BASE_G].push_back(-13238.106081860074);
+    3399           6 :   parameter_mix[BASE_G].push_back(87309.07460288722);
+    3400           6 :   parameter_mix[BASE_G].push_back(-68364.82442984737);
+    3401           6 :   parameter_mix[BASE_G].push_back(16815.362401369);
+    3402             : 
+    3403           6 :   parameter_mix[BASE_T].push_back(17050.440260819163);
+    3404           6 :   parameter_mix[BASE_T].push_back(-76.33750600643376);
+    3405           6 :   parameter_mix[BASE_T].push_back(-31849.539096715005);
+    3406           6 :   parameter_mix[BASE_T].push_back(-9484.498992751434);
+    3407           6 :   parameter_mix[BASE_T].push_back(62881.895771680494);
+    3408           6 :   parameter_mix[BASE_T].push_back(-46531.948557759024);
+    3409           6 :   parameter_mix[BASE_T].push_back(10734.196329884822);
+    3410             : 
+    3411           6 :   parameter_mix[BASE_U].push_back(11904.095265219023);
+    3412           6 :   parameter_mix[BASE_U].push_back(-34.67511054915295);
+    3413           6 :   parameter_mix[BASE_U].push_back(-18842.275003104005);
+    3414           6 :   parameter_mix[BASE_U].push_back(-3993.1174764890684);
+    3415           6 :   parameter_mix[BASE_U].push_back(27663.625106762345);
+    3416           6 :   parameter_mix[BASE_U].push_back(-17577.387831701515);
+    3417           6 :   parameter_mix[BASE_U].push_back(3273.183903219142);
+    3418             : 
+    3419           6 :   parameter_vac[BB_PO2].push_back(960.8822037291127);
+    3420           6 :   parameter_vac[BB_PO2].push_back(-0.09312135742159174);
+    3421           6 :   parameter_vac[BB_PO2].push_back(-469.39643497461844);
+    3422           6 :   parameter_vac[BB_PO2].push_back(-9.779346709041985);
+    3423           6 :   parameter_vac[BB_PO2].push_back(162.1581550003227);
+    3424           6 :   parameter_vac[BB_PO2].push_back(-37.06686233305618);
+    3425           6 :   parameter_vac[BB_PO2].push_back(-4.695586672655664);
+    3426             : 
+    3427           6 :   parameter_vac[BB_DNA].push_back(3720.2522996838984);
+    3428           6 :   parameter_vac[BB_DNA].push_back(-5.4229642176938);
+    3429           6 :   parameter_vac[BB_DNA].push_back(-4800.897672711981);
+    3430           6 :   parameter_vac[BB_DNA].push_back(-597.2274673070993);
+    3431           6 :   parameter_vac[BB_DNA].push_back(4825.908840953665);
+    3432           6 :   parameter_vac[BB_DNA].push_back(-2451.397454446564);
+    3433           6 :   parameter_vac[BB_DNA].push_back(294.93071756645685);
+    3434             : 
+    3435           6 :   parameter_vac[BB_DNA_5].push_back(3843.234214262163);
+    3436           6 :   parameter_vac[BB_DNA_5].push_back(-6.423078416284452);
+    3437           6 :   parameter_vac[BB_DNA_5].push_back(-5112.1216386963115);
+    3438           6 :   parameter_vac[BB_DNA_5].push_back(-713.8373583426668);
+    3439           6 :   parameter_vac[BB_DNA_5].push_back(5547.545382516269);
+    3440           6 :   parameter_vac[BB_DNA_5].push_back(-2973.5659871174225);
+    3441           6 :   parameter_vac[BB_DNA_5].push_back(407.2789106630427);
+    3442             : 
+    3443           6 :   parameter_vac[BB_DNA_3].push_back(3843.234214262163);
+    3444           6 :   parameter_vac[BB_DNA_3].push_back(-6.268636561475645);
+    3445           6 :   parameter_vac[BB_DNA_3].push_back(-5103.192931218086);
+    3446           6 :   parameter_vac[BB_DNA_3].push_back(-693.8705734390547);
+    3447           6 :   parameter_vac[BB_DNA_3].push_back(5443.979645097035);
+    3448           6 :   parameter_vac[BB_DNA_3].push_back(-2871.4337477324893);
+    3449           6 :   parameter_vac[BB_DNA_3].push_back(377.3062915349831);
+    3450             : 
+    3451           6 :   parameter_vac[BB_RNA].push_back(4760.071443398374);
+    3452           6 :   parameter_vac[BB_RNA].push_back(-11.0990475402486);
+    3453           6 :   parameter_vac[BB_RNA].push_back(-6934.713566418421);
+    3454           6 :   parameter_vac[BB_RNA].push_back(-1256.5202524085096);
+    3455           6 :   parameter_vac[BB_RNA].push_back(9024.962587066922);
+    3456           6 :   parameter_vac[BB_RNA].push_back(-5386.842667932241);
+    3457           6 :   parameter_vac[BB_RNA].push_back(907.42947751372);
+    3458             : 
+    3459           6 :   parameter_vac[BB_RNA_5].push_back(4899.051406033406);
+    3460           6 :   parameter_vac[BB_RNA_5].push_back(-12.279240472628238);
+    3461           6 :   parameter_vac[BB_RNA_5].push_back(-7276.273570813667);
+    3462           6 :   parameter_vac[BB_RNA_5].push_back(-1400.9520839250868);
+    3463           6 :   parameter_vac[BB_RNA_5].push_back(9912.215823228895);
+    3464           6 :   parameter_vac[BB_RNA_5].push_back(-6079.2565270404075);
+    3465           6 :   parameter_vac[BB_RNA_5].push_back(1073.53428175472);
+    3466             : 
+    3467           6 :   parameter_vac[BB_RNA_3].push_back(4899.051406033406);
+    3468           6 :   parameter_vac[BB_RNA_3].push_back(-11.642804195148194);
+    3469           6 :   parameter_vac[BB_RNA_3].push_back(-7213.774619570996);
+    3470           6 :   parameter_vac[BB_RNA_3].push_back(-1317.4463949342964);
+    3471           6 :   parameter_vac[BB_RNA_3].push_back(9450.928929264686);
+    3472           6 :   parameter_vac[BB_RNA_3].push_back(-5643.856117200917);
+    3473           6 :   parameter_vac[BB_RNA_3].push_back(949.4698817407918);
+    3474             : 
+    3475           6 :   parameter_vac[BASE_A].push_back(4756.697028810353);
+    3476           6 :   parameter_vac[BASE_A].push_back(-12.158940746852812);
+    3477           6 :   parameter_vac[BASE_A].push_back(-7106.473423744205);
+    3478           6 :   parameter_vac[BASE_A].push_back(-1376.295184173137);
+    3479           6 :   parameter_vac[BASE_A].push_back(9747.132255557788);
+    3480           6 :   parameter_vac[BASE_A].push_back(-5900.026637038756);
+    3481           6 :   parameter_vac[BASE_A].push_back(1004.6226388342955);
+    3482             : 
+    3483           6 :   parameter_vac[BASE_C].push_back(3246.698975674651);
+    3484           6 :   parameter_vac[BASE_C].push_back(-6.125036521218687);
+    3485           6 :   parameter_vac[BASE_C].push_back(-4280.666521437201);
+    3486           6 :   parameter_vac[BASE_C].push_back(-684.0183580843932);
+    3487           6 :   parameter_vac[BASE_C].push_back(5077.062889522692);
+    3488           6 :   parameter_vac[BASE_C].push_back(-2870.3239317750963);
+    3489           6 :   parameter_vac[BASE_C].push_back(434.51551177863547);
+    3490             : 
+    3491           6 :   parameter_vac[BASE_G].push_back(5924.105658596052);
+    3492           6 :   parameter_vac[BASE_G].push_back(-23.097956587232552);
+    3493           6 :   parameter_vac[BASE_G].push_back(-10149.526301285418);
+    3494           6 :   parameter_vac[BASE_G].push_back(-2752.9166169522528);
+    3495           6 :   parameter_vac[BASE_G].push_back(18239.32985385683);
+    3496           6 :   parameter_vac[BASE_G].push_back(-12749.277858800957);
+    3497           6 :   parameter_vac[BASE_G].push_back(2715.354663787367);
+    3498             : 
+    3499           6 :   parameter_vac[BASE_T].push_back(4222.889713694404);
+    3500           6 :   parameter_vac[BASE_T].push_back(-12.15861456306705);
+    3501           6 :   parameter_vac[BASE_T].push_back(-6395.50289789404);
+    3502           6 :   parameter_vac[BASE_T].push_back(-1421.3942549301012);
+    3503           6 :   parameter_vac[BASE_T].push_back(9757.061008720135);
+    3504           6 :   parameter_vac[BASE_T].push_back(-6399.630933839126);
+    3505           6 :   parameter_vac[BASE_T].push_back(1258.9874225605438);
+    3506             : 
+    3507           6 :   parameter_vac[BASE_U].push_back(3247.251361465539);
+    3508           6 :   parameter_vac[BASE_U].push_back(-5.211020853261115);
+    3509           6 :   parameter_vac[BASE_U].push_back(-4125.165310360279);
+    3510           6 :   parameter_vac[BASE_U].push_back(-575.1860235473902);
+    3511           6 :   parameter_vac[BASE_U].push_back(4457.6562621371495);
+    3512           6 :   parameter_vac[BASE_U].push_back(-2368.7250146912766);
+    3513           6 :   parameter_vac[BASE_U].push_back(313.23997718445014);
+    3514             : 
+    3515       21178 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    3516       21172 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    3517       21172 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    3518       21172 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    3519       21172 :     if(Rname=="ALA") {
+    3520        1098 :       atoi[residue_atom[i]]=ALA;
+    3521       20074 :     } else if(Rname=="ARG") {
+    3522        1296 :       atoi[residue_atom[i]]=ARG;
+    3523       18778 :     } else if(Rname=="ASN") {
+    3524        1080 :       atoi[residue_atom[i]]=ASN;
+    3525       17698 :     } else if(Rname=="ASP") {
+    3526         936 :       atoi[residue_atom[i]]=ASP;
+    3527       16762 :     } else if(Rname=="CYS") {
+    3528          72 :       atoi[residue_atom[i]]=CYS;
+    3529       16690 :     } else if(Rname=="GLN") {
+    3530        1596 :       atoi[residue_atom[i]]=GLN;
+    3531       15094 :     } else if(Rname=="GLU") {
+    3532         714 :       atoi[residue_atom[i]]=GLU;
+    3533       14380 :     } else if(Rname=="GLY") {
+    3534         972 :       atoi[residue_atom[i]]=GLY;
+    3535       13408 :     } else if(Rname=="HIS") {
+    3536           0 :       atoi[residue_atom[i]]=HIS;
+    3537       13408 :     } else if(Rname=="HID") {
+    3538           0 :       atoi[residue_atom[i]]=HIS;
+    3539       13408 :     } else if(Rname=="HIE") {
+    3540         216 :       atoi[residue_atom[i]]=HIS;
+    3541       13192 :     } else if(Rname=="HIP") {
+    3542           0 :       atoi[residue_atom[i]]=HIP;
+    3543             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    3544       13192 :     } else if(Rname=="HSD") {
+    3545           0 :       atoi[residue_atom[i]]=HIS;
+    3546       13192 :     } else if(Rname=="HSE") {
+    3547           0 :       atoi[residue_atom[i]]=HIS;
+    3548       13192 :     } else if(Rname=="HSP") {
+    3549           0 :       atoi[residue_atom[i]]=HIP;
+    3550       13192 :     } else if(Rname=="ILE") {
+    3551        1296 :       atoi[residue_atom[i]]=ILE;
+    3552       11896 :     } else if(Rname=="LEU") {
+    3553        2280 :       atoi[residue_atom[i]]=LEU;
+    3554        9616 :     } else if(Rname=="LYS") {
+    3555        1560 :       atoi[residue_atom[i]]=LYS;
+    3556        8056 :     } else if(Rname=="MET") {
+    3557         912 :       atoi[residue_atom[i]]=MET;
+    3558        7144 :     } else if(Rname=="PHE") {
+    3559        1512 :       atoi[residue_atom[i]]=PHE;
+    3560        5632 :     } else if(Rname=="PRO") {
+    3561        1122 :       atoi[residue_atom[i]]=PRO;
+    3562        4510 :     } else if(Rname=="SER") {
+    3563         792 :       atoi[residue_atom[i]]=SER;
+    3564        3718 :     } else if(Rname=="THR") {
+    3565         756 :       atoi[residue_atom[i]]=THR;
+    3566        2962 :     } else if(Rname=="TRP") {
+    3567           0 :       atoi[residue_atom[i]]=TRP;
+    3568        2962 :     } else if(Rname=="TYR") {
+    3569         792 :       atoi[residue_atom[i]]=TYR;
+    3570        2170 :     } else if(Rname=="VAL") {
+    3571        1632 :       atoi[residue_atom[i]]=VAL;
+    3572             :     }
+    3573             :     // NUCLEIC ACIDS
+    3574             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    3575             :     // RNA - G
+    3576         538 :     else if(Rname=="G") {
+    3577           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3578           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3579           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3580           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3581           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3582           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3583           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3584           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3585           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3586           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3587           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3588           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3589           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3590           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3591           0 :         atoi[residue_atom[i]]=BASE_G;
+    3592           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3593             :       // RNA - G3
+    3594         538 :     } else if(Rname=="G3") {
+    3595           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3596           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3597           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3598           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3599           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3600           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3601           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3602           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3603           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3604           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3605           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3606           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3607           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3608           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3609           0 :         atoi[residue_atom[i]]=BASE_G;
+    3610           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3611             :       // RNA - G5
+    3612         538 :     } else if(Rname=="G5") {
+    3613           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3614           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3615           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3616           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3617           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3618           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3619           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3620           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3621           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3622           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3623           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3624           0 :         atoi[residue_atom[i]]=BASE_G;
+    3625           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3626             :       // RNA - U
+    3627         538 :     } else if(Rname=="U") {
+    3628        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3629        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3630          42 :         atoi [residue_atom[i]]=BB_PO2;
+    3631        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3632        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3633         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3634         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3635         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3636         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3637         224 :         atoi[residue_atom[i]]=BB_RNA;
+    3638         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3639         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3640         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3641         154 :         atoi[residue_atom[i]]=BASE_U;
+    3642           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3643             :       // RNA - U3
+    3644         118 :     } else if(Rname=="U3") {
+    3645         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3646         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3647           6 :         atoi [residue_atom[i]]=BB_PO2;
+    3648         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3649         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3650         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3651         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3652          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3653          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3654          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3655          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3656          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3657          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3658          22 :         atoi[residue_atom[i]]=BASE_U;
+    3659           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3660             :       // RNA - U5
+    3661          56 :     } else if(Rname=="U5") {
+    3662         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3663         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3664         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3665         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3666          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3667          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3668          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3669          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3670          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3671          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3672          22 :         atoi[residue_atom[i]]=BASE_U;
+    3673           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3674             :       // RNA - A
+    3675           0 :     } else if(Rname=="A") {
+    3676           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3677           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3678           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3679           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3680           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3681           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3682           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3683           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3684           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3685           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3686           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3687           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3688           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3689           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3690           0 :         atoi[residue_atom[i]]=BASE_A;
+    3691           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3692             :       // RNA - A3
+    3693           0 :     } else if(Rname=="A3") {
+    3694           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3695           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3696           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3697           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3698           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3699           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3700           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3701           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3702           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3703           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3704           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3705           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3706           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3707           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3708           0 :         atoi[residue_atom[i]]=BASE_A;
+    3709           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3710             :       // RNA - A5
+    3711           0 :     } else if(Rname=="A5") {
+    3712           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3713           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3714           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3715           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3716           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3717           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3718           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3719           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3720           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3721           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3722           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3723           0 :         atoi[residue_atom[i]]=BASE_A;
+    3724           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3725             :       // RNA - C
+    3726           0 :     } else if(Rname=="C") {
+    3727           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3728           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3729           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3730           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3731           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3732           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3733           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3734           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3735           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3736           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3737           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3738           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3739           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3740           0 :         atoi[residue_atom[i]]=BASE_C;
+    3741           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3742             :       // RNA - C3
+    3743           0 :     } else if(Rname=="C3") {
+    3744           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3745           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3746           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3747           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3748           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3749           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3750           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3751           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3752           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3753           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3754           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3755           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3756           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3757           0 :         atoi[residue_atom[i]]=BASE_C;
+    3758           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3759             :       // RNA - C5
+    3760           0 :     } else if(Rname=="C5") {
+    3761           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3762           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3763           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3764           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3765           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3766           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3767           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3768           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3769           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3770           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3771           0 :         atoi[residue_atom[i]]=BASE_C;
+    3772           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3773             :       // DNA - G
+    3774           0 :     } else if(Rname=="DG") {
+    3775           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3776           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3777           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3778           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3779           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3780           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3781           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3782           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    3783           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    3784           0 :         atoi[residue_atom[i]]=BB_DNA;
+    3785           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3786           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3787           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3788           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3789           0 :         atoi[residue_atom[i]]=BASE_G;
+    3790           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3791             :       // DNA - G3
+    3792           0 :     } else if(Rname=="DG3") {
+    3793           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3794           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3795           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3796           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3797           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3798           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3799           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    3800           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3801             :                 Aname=="H3T" ) {
+    3802           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    3803           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3804           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3805           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3806           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3807           0 :         atoi[residue_atom[i]]=BASE_G;
+    3808           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3809             :       // DNA - G5
+    3810           0 :     } else if(Rname=="DG5") {
+    3811           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3812           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    3813           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3814           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3815           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3816             :           Aname=="H5T" ) {
+    3817           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    3818           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3819           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3820           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3821           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3822           0 :         atoi[residue_atom[i]]=BASE_G;
+    3823           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3824             :       // DNA - T
+    3825           0 :     } else if(Rname=="DT") {
+    3826           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3827           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3828           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3829           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3830           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3831           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3832           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3833           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    3834           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    3835           0 :         atoi[residue_atom[i]]=BB_DNA;
+    3836           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    3837           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    3838           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    3839           0 :                 Aname=="H72" || Aname=="H73" ) {
+    3840           0 :         atoi[residue_atom[i]]=BASE_T;
+    3841           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3842             :       // DNA - T3
+    3843           0 :     } else if(Rname=="DT3") {
+    3844           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3845           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3846           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3847           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3848           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3849           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3850           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    3851           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3852             :                 Aname=="H3T" ) {
+    3853           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    3854           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    3855           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    3856           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    3857           0 :                 Aname=="H72" || Aname=="H73" ) {
+    3858           0 :         atoi[residue_atom[i]]=BASE_T;
+    3859           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3860             :       // DNA - T5
+    3861           0 :     } else if(Rname=="DT5") {
+    3862           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3863           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    3864           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3865           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3866           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3867             :           Aname=="H5T" ) {
+    3868           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    3869           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    3870           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    3871           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    3872           0 :                 Aname=="H72" || Aname=="H73" ) {
+    3873           0 :         atoi[residue_atom[i]]=BASE_T;
+    3874           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3875             :       // DNA - A
+    3876           0 :     } else if(Rname=="DA") {
+    3877           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3878           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3879           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3880           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3881           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3882           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3883           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3884           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    3885           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    3886           0 :         atoi[residue_atom[i]]=BB_DNA;
+    3887           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3888           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3889           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3890           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3891           0 :         atoi[residue_atom[i]]=BASE_A;
+    3892           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3893             :       // DNA - A3
+    3894           0 :     } else if(Rname=="DA3") {
+    3895           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3896           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3897           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3898           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3899           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3900           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3901           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    3902           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3903             :                 Aname=="H3T" ) {
+    3904           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    3905           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3906           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3907           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3908           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3909           0 :         atoi[residue_atom[i]]=BASE_A;
+    3910           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3911             :       // DNA - A5
+    3912           0 :     } else if(Rname=="DA5") {
+    3913           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3914           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    3915           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3916           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3917           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3918             :           Aname=="H5T" ) {
+    3919           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    3920           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3921           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3922           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3923           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3924           0 :         atoi[residue_atom[i]]=BASE_A;
+    3925           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3926             :       // DNA - C
+    3927           0 :     } else if(Rname=="DC") {
+    3928           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3929           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3930           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3931           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3932           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3933           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3934           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3935           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    3936           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    3937           0 :         atoi[residue_atom[i]]=BB_DNA;
+    3938           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3939           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3940           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3941           0 :         atoi[residue_atom[i]]=BASE_C;
+    3942           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3943             :       // DNA - C3
+    3944           0 :     } else if(Rname=="DC3") {
+    3945           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3946           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3947           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3948           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3949           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    3950           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3951           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    3952           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3953             :                 Aname=="H3T" ) {
+    3954           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    3955           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3956           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3957           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3958           0 :         atoi[residue_atom[i]]=BASE_C;
+    3959           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3960             :       // DNA - C5
+    3961           0 :     } else if(Rname=="DC5") {
+    3962           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3963           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    3964           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    3965           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    3966           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    3967             :           Aname=="H5T" ) {
+    3968           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    3969           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    3970           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    3971           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    3972           0 :         atoi[residue_atom[i]]=BASE_C;
+    3973           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3974           0 :     } else error("Residue not known: "+Rname);
+    3975             :   }
+    3976           6 : }
+    3977             : 
+    3978           4 : void SAXS::getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H)
+    3979             : {
+    3980           4 :   parameter_solv_H[TRP].push_back(60737.60249988011);
+    3981           4 :   parameter_solv_H[TRP].push_back(-77.77344118516487);
+    3982           4 :   parameter_solv_H[TRP].push_back(-205962.80436572764);
+    3983           4 :   parameter_solv_H[TRP].push_back(-62014.18523271781);
+    3984           4 :   parameter_solv_H[TRP].push_back(680712.0512548896);
+    3985           4 :   parameter_solv_H[TRP].push_back(-681337.967312983);
+    3986           4 :   parameter_solv_H[TRP].push_back(211474.00338118695);
+    3987             : 
+    3988           4 :   parameter_solv_H[TYR].push_back(46250.803599880084);
+    3989           4 :   parameter_solv_H[TYR].push_back(-45.827646837514614);
+    3990           4 :   parameter_solv_H[TYR].push_back(-143872.94597686914);
+    3991           4 :   parameter_solv_H[TYR].push_back(-39049.51580628132);
+    3992           4 :   parameter_solv_H[TYR].push_back(441321.31246635393);
+    3993           4 :   parameter_solv_H[TYR].push_back(-434477.6826175059);
+    3994           4 :   parameter_solv_H[TYR].push_back(133179.21673104732);
+    3995             : 
+    3996           4 :   parameter_solv_H[PHE].push_back(42407.164900118914);
+    3997           4 :   parameter_solv_H[PHE].push_back(-159.20054549009086);
+    3998           4 :   parameter_solv_H[PHE].push_back(-123847.83591352346);
+    3999           4 :   parameter_solv_H[PHE].push_back(-41797.78884558073);
+    4000           4 :   parameter_solv_H[PHE].push_back(380283.87543872406);
+    4001           4 :   parameter_solv_H[PHE].push_back(-361432.81356389285);
+    4002           4 :   parameter_solv_H[PHE].push_back(107750.69385054041);
+    4003             : 
+    4004           4 :   parameter_solv_H[HIP].push_back(24473.473600119047);
+    4005           4 :   parameter_solv_H[HIP].push_back(-111.6412807124612);
+    4006           4 :   parameter_solv_H[HIP].push_back(-65826.17293437096);
+    4007           4 :   parameter_solv_H[HIP].push_back(-23305.902022201855);
+    4008           4 :   parameter_solv_H[HIP].push_back(194795.09953510275);
+    4009           4 :   parameter_solv_H[HIP].push_back(-180454.47859494278);
+    4010           4 :   parameter_solv_H[HIP].push_back(52699.36922660704);
+    4011             : 
+    4012           4 :   parameter_solv_H[ARG].push_back(34106.70239988039);
+    4013           4 :   parameter_solv_H[ARG].push_back(152.74468231268114);
+    4014           4 :   parameter_solv_H[ARG].push_back(-117086.46040369231);
+    4015           4 :   parameter_solv_H[ARG].push_back(-19664.37512726012);
+    4016           4 :   parameter_solv_H[ARG].push_back(364454.3721646173);
+    4017           4 :   parameter_solv_H[ARG].push_back(-382076.05102190404);
+    4018           4 :   parameter_solv_H[ARG].push_back(122775.83306003918);
+    4019             : 
+    4020           4 :   parameter_solv_H[LYS].push_back(32292.09000011877);
+    4021           4 :   parameter_solv_H[LYS].push_back(-111.97888350941923);
+    4022           4 :   parameter_solv_H[LYS].push_back(-91953.05212591762);
+    4023           4 :   parameter_solv_H[LYS].push_back(-30691.03615444628);
+    4024           4 :   parameter_solv_H[LYS].push_back(282092.82233263896);
+    4025           4 :   parameter_solv_H[LYS].push_back(-269503.6095978623);
+    4026           4 :   parameter_solv_H[LYS].push_back(80777.92760273012);
+    4027             : 
+    4028           4 :   parameter_solv_H[CYS].push_back(11352.902500119093);
+    4029           4 :   parameter_solv_H[CYS].push_back(-45.52255488723637);
+    4030           4 :   parameter_solv_H[CYS].push_back(-20925.086525675117);
+    4031           4 :   parameter_solv_H[CYS].push_back(-5662.681335644281);
+    4032           4 :   parameter_solv_H[CYS].push_back(38559.09602816144);
+    4033           4 :   parameter_solv_H[CYS].push_back(-27885.22747486708);
+    4034           4 :   parameter_solv_H[CYS].push_back(6280.148346561226);
+    4035             : 
+    4036           4 :   parameter_solv_H[ASP].push_back(13511.73760011933);
+    4037           4 :   parameter_solv_H[ASP].push_back(-59.92934247210642);
+    4038           4 :   parameter_solv_H[ASP].push_back(-25849.867077822244);
+    4039           4 :   parameter_solv_H[ASP].push_back(-7541.679510407563);
+    4040           4 :   parameter_solv_H[ASP].push_back(50760.93853987092);
+    4041           4 :   parameter_solv_H[ASP].push_back(-37677.89102528413);
+    4042           4 :   parameter_solv_H[ASP].push_back(8745.710458140105);
+    4043             : 
+    4044           4 :   parameter_solv_H[GLU].push_back(20443.280400119456);
+    4045           4 :   parameter_solv_H[GLU].push_back(-113.77513581661388);
+    4046           4 :   parameter_solv_H[GLU].push_back(-45587.79863958479);
+    4047           4 :   parameter_solv_H[GLU].push_back(-16187.534798976243);
+    4048           4 :   parameter_solv_H[GLU].push_back(112609.61802147207);
+    4049           4 :   parameter_solv_H[GLU].push_back(-93362.01894077536);
+    4050           4 :   parameter_solv_H[GLU].push_back(24519.546829431332);
+    4051             : 
+    4052           4 :   parameter_solv_H[ILE].push_back(27858.948100119596);
+    4053           4 :   parameter_solv_H[ILE].push_back(-159.27394962770595);
+    4054           4 :   parameter_solv_H[ILE].push_back(-61571.43025249802);
+    4055           4 :   parameter_solv_H[ILE].push_back(-21324.89659912433);
+    4056           4 :   parameter_solv_H[ILE].push_back(144070.7880009225);
+    4057           4 :   parameter_solv_H[ILE].push_back(-115021.84534734003);
+    4058           4 :   parameter_solv_H[ILE].push_back(28939.093300284097);
+    4059             : 
+    4060           4 :   parameter_solv_H[LEU].push_back(27858.948100119596);
+    4061           4 :   parameter_solv_H[LEU].push_back(-165.61872365361);
+    4062           4 :   parameter_solv_H[LEU].push_back(-62564.5706162518);
+    4063           4 :   parameter_solv_H[LEU].push_back(-22465.325666767214);
+    4064           4 :   parameter_solv_H[LEU].push_back(151616.7844050042);
+    4065           4 :   parameter_solv_H[LEU].push_back(-122905.60389771541);
+    4066           4 :   parameter_solv_H[LEU].push_back(31436.66201442061);
+    4067             : 
+    4068           4 :   parameter_solv_H[MET].push_back(25609.60090011981);
+    4069           4 :   parameter_solv_H[MET].push_back(-135.38816369794569);
+    4070           4 :   parameter_solv_H[MET].push_back(-67771.01548433342);
+    4071           4 :   parameter_solv_H[MET].push_back(-25228.91756660071);
+    4072           4 :   parameter_solv_H[MET].push_back(199649.92084565928);
+    4073           4 :   parameter_solv_H[MET].push_back(-182251.9246506795);
+    4074           4 :   parameter_solv_H[MET].push_back(52502.876819125115);
+    4075             : 
+    4076           4 :   parameter_solv_H[ASN].push_back(14376.010000119095);
+    4077           4 :   parameter_solv_H[ASN].push_back(-67.65587848183215);
+    4078           4 :   parameter_solv_H[ASN].push_back(-28302.877059425664);
+    4079           4 :   parameter_solv_H[ASN].push_back(-8577.444107282141);
+    4080           4 :   parameter_solv_H[ASN].push_back(57532.88704197217);
+    4081           4 :   parameter_solv_H[ASN].push_back(-43261.79974462857);
+    4082           4 :   parameter_solv_H[ASN].push_back(10186.450874679671);
+    4083             : 
+    4084           4 :   parameter_solv_H[PRO].push_back(16866.21690011944);
+    4085           4 :   parameter_solv_H[PRO].push_back(-70.84312112734995);
+    4086           4 :   parameter_solv_H[PRO].push_back(-31465.8423531932);
+    4087           4 :   parameter_solv_H[PRO].push_back(-8653.362744540535);
+    4088           4 :   parameter_solv_H[PRO].push_back(58032.27079924916);
+    4089           4 :   parameter_solv_H[PRO].push_back(-41521.001733021694);
+    4090           4 :   parameter_solv_H[PRO].push_back(9184.527523759205);
+    4091             : 
+    4092           4 :   parameter_solv_H[GLN].push_back(21503.289600119);
+    4093           4 :   parameter_solv_H[GLN].push_back(-121.3012777474678);
+    4094           4 :   parameter_solv_H[GLN].push_back(-50468.58503443957);
+    4095           4 :   parameter_solv_H[GLN].push_back(-18462.47495329696);
+    4096           4 :   parameter_solv_H[GLN].push_back(132718.42007501892);
+    4097           4 :   parameter_solv_H[GLN].push_back(-113787.20224345029);
+    4098           4 :   parameter_solv_H[GLN].push_back(30920.340813688686);
+    4099             : 
+    4100           4 :   parameter_solv_H[SER].push_back(9181.47240011935);
+    4101           4 :   parameter_solv_H[SER].push_back(-28.775273124392083);
+    4102           4 :   parameter_solv_H[SER].push_back(-15205.54229808512);
+    4103           4 :   parameter_solv_H[SER].push_back(-3377.785599913673);
+    4104           4 :   parameter_solv_H[SER].push_back(23345.562090489493);
+    4105           4 :   parameter_solv_H[SER].push_back(-15312.699787471944);
+    4106           4 :   parameter_solv_H[SER].push_back(3013.844610647712);
+    4107             : 
+    4108           4 :   parameter_solv_H[THR].push_back(15020.953600119403);
+    4109           4 :   parameter_solv_H[THR].push_back(-61.909951810375105);
+    4110           4 :   parameter_solv_H[THR].push_back(-27814.538986050964);
+    4111           4 :   parameter_solv_H[THR].push_back(-7532.222992514079);
+    4112           4 :   parameter_solv_H[THR].push_back(50586.29804970814);
+    4113           4 :   parameter_solv_H[THR].push_back(-35943.85986777198);
+    4114           4 :   parameter_solv_H[THR].push_back(7880.091610023207);
+    4115             : 
+    4116           4 :   parameter_solv_H[VAL].push_back(19647.628900119355);
+    4117           4 :   parameter_solv_H[VAL].push_back(-89.04968136833762);
+    4118           4 :   parameter_solv_H[VAL].push_back(-38050.10118919102);
+    4119           4 :   parameter_solv_H[VAL].push_back(-10921.421066774372);
+    4120           4 :   parameter_solv_H[VAL].push_back(72774.31277743122);
+    4121           4 :   parameter_solv_H[VAL].push_back(-52689.05168504517);
+    4122           4 :   parameter_solv_H[VAL].push_back(11806.48989635518);
+    4123             : 
+    4124           4 :   parameter_solv_H[ALA].push_back(7515.156100119273);
+    4125           4 :   parameter_solv_H[ALA].push_back(-20.226317591188526);
+    4126           4 :   parameter_solv_H[ALA].push_back(-11761.841775007797);
+    4127           4 :   parameter_solv_H[ALA].push_back(-2341.4903622033885);
+    4128           4 :   parameter_solv_H[ALA].push_back(16545.381259883452);
+    4129           4 :   parameter_solv_H[ALA].push_back(-10397.171546969075);
+    4130           4 :   parameter_solv_H[ALA].push_back(1921.5253045340198);
+    4131             : 
+    4132           4 :   parameter_solv_H[GLY].push_back(3594.002500119159);
+    4133           4 :   parameter_solv_H[GLY].push_back(-6.910832388009796);
+    4134           4 :   parameter_solv_H[GLY].push_back(-4937.3542895091905);
+    4135           4 :   parameter_solv_H[GLY].push_back(-785.4545979203357);
+    4136           4 :   parameter_solv_H[GLY].push_back(5852.853693316741);
+    4137           4 :   parameter_solv_H[GLY].push_back(-3391.2920205126734);
+    4138           4 :   parameter_solv_H[GLY].push_back(552.3278183161507);
+    4139             : 
+    4140           4 :   parameter_solv_H[HIS].push_back(22888.664100119073);
+    4141           4 :   parameter_solv_H[HIS].push_back(-133.86281863999585);
+    4142           4 :   parameter_solv_H[HIS].push_back(-57533.51412287858);
+    4143           4 :   parameter_solv_H[HIS].push_back(-21767.300111408193);
+    4144           4 :   parameter_solv_H[HIS].push_back(161255.15347073504);
+    4145           4 :   parameter_solv_H[HIS].push_back(-142176.65100718598);
+    4146           4 :   parameter_solv_H[HIS].push_back(39642.61507384587);
+    4147             : 
+    4148           4 :   parameter_mix_H[TRP].push_back(2974.6515001192306);
+    4149           4 :   parameter_mix_H[TRP].push_back(-18.361939022074825);
+    4150           4 :   parameter_mix_H[TRP].push_back(-7284.637435770752);
+    4151           4 :   parameter_mix_H[TRP].push_back(-2945.7969900381895);
+    4152           4 :   parameter_mix_H[TRP].push_back(21235.01878657283);
+    4153           4 :   parameter_mix_H[TRP].push_back(-18909.7406035548);
+    4154           4 :   parameter_mix_H[TRP].push_back(5324.324204245179);
+    4155             : 
+    4156           4 :   parameter_mix_H[TYR].push_back(2029.7362801192114);
+    4157           4 :   parameter_mix_H[TYR].push_back(-6.983186065527884);
+    4158           4 :   parameter_mix_H[TYR].push_back(-5041.996113037476);
+    4159           4 :   parameter_mix_H[TYR].push_back(-1744.5213085724158);
+    4160           4 :   parameter_mix_H[TYR].push_back(15329.420227814338);
+    4161           4 :   parameter_mix_H[TYR].push_back(-14648.322529889958);
+    4162           4 :   parameter_mix_H[TYR].push_back(4405.608657083287);
+    4163             : 
+    4164           4 :   parameter_mix_H[PHE].push_back(1704.6885401192117);
+    4165           4 :   parameter_mix_H[PHE].push_back(-10.077274979133408);
+    4166           4 :   parameter_mix_H[PHE].push_back(-3769.440088334303);
+    4167           4 :   parameter_mix_H[PHE].push_back(-1574.6255694551546);
+    4168           4 :   parameter_mix_H[PHE].push_back(10996.32497868798);
+    4169           4 :   parameter_mix_H[PHE].push_back(-9840.68281283696);
+    4170           4 :   parameter_mix_H[PHE].push_back(2792.098605716682);
+    4171             : 
+    4172           4 :   parameter_mix_H[HIP].push_back(1376.0462401192394);
+    4173           4 :   parameter_mix_H[HIP].push_back(-8.576320475413144);
+    4174           4 :   parameter_mix_H[HIP].push_back(-2796.8327726392167);
+    4175           4 :   parameter_mix_H[HIP].push_back(-1165.0473128576);
+    4176           4 :   parameter_mix_H[HIP].push_back(7495.063650365717);
+    4177           4 :   parameter_mix_H[HIP].push_back(-6331.20422098132);
+    4178           4 :   parameter_mix_H[HIP].push_back(1692.637366093312);
+    4179             : 
+    4180           4 :   parameter_mix_H[ARG].push_back(1280.940480119178);
+    4181           4 :   parameter_mix_H[ARG].push_back(-7.411214928783748);
+    4182           4 :   parameter_mix_H[ARG].push_back(-3747.6200569785033);
+    4183           4 :   parameter_mix_H[ARG].push_back(-1766.5282176004569);
+    4184           4 :   parameter_mix_H[ARG].push_back(14307.817638456267);
+    4185           4 :   parameter_mix_H[ARG].push_back(-14297.104122885643);
+    4186           4 :   parameter_mix_H[ARG].push_back(4450.526244207772);
+    4187             : 
+    4188           4 :   parameter_mix_H[LYS].push_back(570.7272001192143);
+    4189           4 :   parameter_mix_H[LYS].push_back(-5.371742288956095);
+    4190           4 :   parameter_mix_H[LYS].push_back(-1255.9868267793006);
+    4191           4 :   parameter_mix_H[LYS].push_back(-748.3071074443138);
+    4192           4 :   parameter_mix_H[LYS].push_back(4534.824932304509);
+    4193           4 :   parameter_mix_H[LYS].push_back(-4125.307867230812);
+    4194           4 :   parameter_mix_H[LYS].push_back(1178.781491068295);
+    4195             : 
+    4196           4 :   parameter_mix_H[CYS].push_back(410.21750011921864);
+    4197           4 :   parameter_mix_H[CYS].push_back(-0.7655651758449595);
+    4198           4 :   parameter_mix_H[CYS].push_back(-523.8897033718782);
+    4199           4 :   parameter_mix_H[CYS].push_back(-89.88478273744425);
+    4200           4 :   parameter_mix_H[CYS].push_back(655.3313542467919);
+    4201           4 :   parameter_mix_H[CYS].push_back(-407.87897719750896);
+    4202           4 :   parameter_mix_H[CYS].push_back(76.50541508448237);
+    4203             : 
+    4204           4 :   parameter_mix_H[ASP].push_back(893.6531201192147);
+    4205           4 :   parameter_mix_H[ASP].push_back(-3.0756255172248874);
+    4206           4 :   parameter_mix_H[ASP].push_back(-1453.1760425275006);
+    4207           4 :   parameter_mix_H[ASP].push_back(-365.0424824614137);
+    4208           4 :   parameter_mix_H[ASP].push_back(2443.570600976796);
+    4209           4 :   parameter_mix_H[ASP].push_back(-1679.8996339740277);
+    4210           4 :   parameter_mix_H[ASP].push_back(352.33054461512455);
+    4211             : 
+    4212           4 :   parameter_mix_H[GLU].push_back(1075.4955601191884);
+    4213           4 :   parameter_mix_H[GLU].push_back(-6.917429973203965);
+    4214           4 :   parameter_mix_H[GLU].push_back(-2262.861870389347);
+    4215           4 :   parameter_mix_H[GLU].push_back(-909.8078514527992);
+    4216           4 :   parameter_mix_H[GLU].push_back(5841.923857549836);
+    4217           4 :   parameter_mix_H[GLU].push_back(-4784.620969556751);
+    4218           4 :   parameter_mix_H[GLU].push_back(1230.873134652953);
+    4219             : 
+    4220           4 :   parameter_mix_H[ILE].push_back(466.0127201192081);
+    4221           4 :   parameter_mix_H[ILE].push_back(-0.9323443258150218);
+    4222           4 :   parameter_mix_H[ILE].push_back(-576.7178005955719);
+    4223           4 :   parameter_mix_H[ILE].push_back(-103.03003361062478);
+    4224           4 :   parameter_mix_H[ILE].push_back(706.4269951176641);
+    4225           4 :   parameter_mix_H[ILE].push_back(-420.4412859632717);
+    4226           4 :   parameter_mix_H[ILE].push_back(71.53175726608731);
+    4227             : 
+    4228           4 :   parameter_mix_H[LEU].push_back(466.0127201192081);
+    4229           4 :   parameter_mix_H[LEU].push_back(-1.9793605752606065);
+    4230           4 :   parameter_mix_H[LEU].push_back(-718.3988478701591);
+    4231           4 :   parameter_mix_H[LEU].push_back(-227.36409339012113);
+    4232           4 :   parameter_mix_H[LEU].push_back(1389.2058254917304);
+    4233           4 :   parameter_mix_H[LEU].push_back(-990.0033118748643);
+    4234           4 :   parameter_mix_H[LEU].push_back(213.15736815883042);
+    4235             : 
+    4236           4 :   parameter_mix_H[MET].push_back(562.9855401192196);
+    4237           4 :   parameter_mix_H[MET].push_back(-3.7994094933771643);
+    4238           4 :   parameter_mix_H[MET].push_back(-1139.6331862451661);
+    4239           4 :   parameter_mix_H[MET].push_back(-516.6313269725724);
+    4240           4 :   parameter_mix_H[MET].push_back(3268.957245190869);
+    4241           4 :   parameter_mix_H[MET].push_back(-2809.178864807947);
+    4242           4 :   parameter_mix_H[MET].push_back(761.4832732100416);
+    4243             : 
+    4244           4 :   parameter_mix_H[ASN].push_back(828.7488001191887);
+    4245           4 :   parameter_mix_H[ASN].push_back(-2.1275493073799625);
+    4246           4 :   parameter_mix_H[ASN].push_back(-1222.248291388804);
+    4247           4 :   parameter_mix_H[ASN].push_back(-238.94210659613537);
+    4248           4 :   parameter_mix_H[ASN].push_back(1660.8322402171973);
+    4249           4 :   parameter_mix_H[ASN].push_back(-1008.7934996077323);
+    4250           4 :   parameter_mix_H[ASN].push_back(173.6082238625797);
+    4251             : 
+    4252           4 :   parameter_mix_H[PRO].push_back(578.4409801192146);
+    4253           4 :   parameter_mix_H[PRO].push_back(-0.5379505780909722);
+    4254           4 :   parameter_mix_H[PRO].push_back(-648.146493857212);
+    4255           4 :   parameter_mix_H[PRO].push_back(-56.67223895342921);
+    4256           4 :   parameter_mix_H[PRO].push_back(509.88860586987437);
+    4257           4 :   parameter_mix_H[PRO].push_back(-214.57871784725265);
+    4258           4 :   parameter_mix_H[PRO].push_back(11.99659463759968);
+    4259             : 
+    4260           4 :   parameter_mix_H[GLN].push_back(989.2334401191976);
+    4261           4 :   parameter_mix_H[GLN].push_back(-6.307760694331967);
+    4262           4 :   parameter_mix_H[GLN].push_back(-1971.7067150503622);
+    4263           4 :   parameter_mix_H[GLN].push_back(-791.333088386235);
+    4264           4 :   parameter_mix_H[GLN].push_back(4900.009768434847);
+    4265           4 :   parameter_mix_H[GLN].push_back(-3909.7740976374153);
+    4266           4 :   parameter_mix_H[GLN].push_back(975.4952613244343);
+    4267             : 
+    4268           4 :   parameter_mix_H[SER].push_back(426.39900011920196);
+    4269           4 :   parameter_mix_H[SER].push_back(-0.42304498358319664);
+    4270           4 :   parameter_mix_H[SER].push_back(-484.2066027682147);
+    4271           4 :   parameter_mix_H[SER].push_back(-45.38968988754228);
+    4272           4 :   parameter_mix_H[SER].push_back(401.3420977115044);
+    4273           4 :   parameter_mix_H[SER].push_back(-178.0861461692512);
+    4274           4 :   parameter_mix_H[SER].push_back(13.540349238730284);
+    4275             : 
+    4276           4 :   parameter_mix_H[THR].push_back(525.0470401191992);
+    4277           4 :   parameter_mix_H[THR].push_back(-0.7419102811534484);
+    4278           4 :   parameter_mix_H[THR].push_back(-652.7134808154495);
+    4279           4 :   parameter_mix_H[THR].push_back(-80.39481224407903);
+    4280           4 :   parameter_mix_H[THR].push_back(641.5487902728123);
+    4281           4 :   parameter_mix_H[THR].push_back(-320.4227667104819);
+    4282           4 :   parameter_mix_H[THR].push_back(36.03558531183942);
+    4283             : 
+    4284           4 :   parameter_mix_H[VAL].push_back(414.6228601192123);
+    4285           4 :   parameter_mix_H[VAL].push_back(-0.35889335250521337);
+    4286           4 :   parameter_mix_H[VAL].push_back(-453.11631644097474);
+    4287           4 :   parameter_mix_H[VAL].push_back(-36.402101097644284);
+    4288           4 :   parameter_mix_H[VAL].push_back(336.24049431626804);
+    4289           4 :   parameter_mix_H[VAL].push_back(-127.42235327515239);
+    4290           4 :   parameter_mix_H[VAL].push_back(0.8013280923923705);
+    4291             : 
+    4292           4 :   parameter_mix_H[ALA].push_back(285.21010011920816);
+    4293           4 :   parameter_mix_H[ALA].push_back(-0.1573012439142169);
+    4294           4 :   parameter_mix_H[ALA].push_back(-282.8945838800694);
+    4295           4 :   parameter_mix_H[ALA].push_back(-16.32030056827785);
+    4296           4 :   parameter_mix_H[ALA].push_back(178.065895049598);
+    4297           4 :   parameter_mix_H[ALA].push_back(-60.27423229179658);
+    4298           4 :   parameter_mix_H[ALA].push_back(-1.4695219304131588);
+    4299             : 
+    4300           4 :   parameter_mix_H[GLY].push_back(207.18720011920414);
+    4301           4 :   parameter_mix_H[GLY].push_back(-0.1036587134183235);
+    4302           4 :   parameter_mix_H[GLY].push_back(-185.70794948240638);
+    4303           4 :   parameter_mix_H[GLY].push_back(-11.008101039836257);
+    4304           4 :   parameter_mix_H[GLY].push_back(115.30600405624061);
+    4305           4 :   parameter_mix_H[GLY].push_back(-42.46629718037158);
+    4306           4 :   parameter_mix_H[GLY].push_back(0.9238928987070913);
+    4307             : 
+    4308           4 :   parameter_mix_H[HIS].push_back(1443.9117601192354);
+    4309           4 :   parameter_mix_H[HIS].push_back(-7.478618745973115);
+    4310           4 :   parameter_mix_H[HIS].push_back(-2715.0835155803215);
+    4311           4 :   parameter_mix_H[HIS].push_back(-918.5243015382779);
+    4312           4 :   parameter_mix_H[HIS].push_back(5821.6258431396);
+    4313           4 :   parameter_mix_H[HIS].push_back(-4415.32722209556);
+    4314           4 :   parameter_mix_H[HIS].push_back(1044.7044029209756);
+    4315           4 :   parameter_vac_H[TRP].push_back(36.42122511920832);
+    4316           4 :   parameter_vac_H[TRP].push_back(-0.36925500341767903);
+    4317           4 :   parameter_vac_H[TRP].push_back(-51.34228792835503);
+    4318           4 :   parameter_vac_H[TRP].push_back(-34.10021080004831);
+    4319           4 :   parameter_vac_H[TRP].push_back(132.647034983933);
+    4320           4 :   parameter_vac_H[TRP].push_back(-82.89152328934257);
+    4321           4 :   parameter_vac_H[TRP].push_back(13.029994092013231);
+    4322             : 
+    4323           4 :   parameter_vac_H[TYR].push_back(22.268961119209557);
+    4324           4 :   parameter_vac_H[TYR].push_back(-0.1995573892347673);
+    4325           4 :   parameter_vac_H[TYR].push_back(-36.54202179838511);
+    4326           4 :   parameter_vac_H[TYR].push_back(-23.820801043096694);
+    4327           4 :   parameter_vac_H[TYR].push_back(127.46799692275353);
+    4328           4 :   parameter_vac_H[TYR].push_back(-107.63783234245744);
+    4329           4 :   parameter_vac_H[TYR].push_back(28.180858902960775);
+    4330             : 
+    4331           4 :   parameter_vac_H[PHE].push_back(17.131321119209627);
+    4332           4 :   parameter_vac_H[PHE].push_back(-0.15766725674246446);
+    4333           4 :   parameter_vac_H[PHE].push_back(-19.19964432024534);
+    4334           4 :   parameter_vac_H[PHE].push_back(-12.34326882843138);
+    4335           4 :   parameter_vac_H[PHE].push_back(38.17216645824474);
+    4336           4 :   parameter_vac_H[PHE].push_back(-11.245288857407298);
+    4337           4 :   parameter_vac_H[PHE].push_back(-3.8114731300899343);
+    4338             : 
+    4339           4 :   parameter_vac_H[HIP].push_back(19.34240411920875);
+    4340           4 :   parameter_vac_H[HIP].push_back(-0.13533410292592593);
+    4341           4 :   parameter_vac_H[HIP].push_back(-25.924121027387276);
+    4342           4 :   parameter_vac_H[HIP].push_back(-12.36586927492752);
+    4343           4 :   parameter_vac_H[HIP].push_back(56.75268702111191);
+    4344           4 :   parameter_vac_H[HIP].push_back(-31.126240293638094);
+    4345           4 :   parameter_vac_H[HIP].push_back(2.749811579250848);
+    4346             : 
+    4347           4 :   parameter_vac_H[ARG].push_back(12.027024119209557);
+    4348           4 :   parameter_vac_H[ARG].push_back(-0.41927538341868287);
+    4349           4 :   parameter_vac_H[ARG].push_back(-22.137566939867042);
+    4350           4 :   parameter_vac_H[ARG].push_back(-43.22615008762667);
+    4351           4 :   parameter_vac_H[ARG].push_back(165.77466655520323);
+    4352           4 :   parameter_vac_H[ARG].push_back(-140.68664871425898);
+    4353           4 :   parameter_vac_H[ARG].push_back(36.67401195170306);
+    4354             : 
+    4355           4 :   parameter_vac_H[LYS].push_back(2.5217441192093717);
+    4356           4 :   parameter_vac_H[LYS].push_back(-0.0032825476242835413);
+    4357           4 :   parameter_vac_H[LYS].push_back(14.019071697737793);
+    4358           4 :   parameter_vac_H[LYS].push_back(7.8634074595069245);
+    4359           4 :   parameter_vac_H[LYS].push_back(-82.44639716451474);
+    4360           4 :   parameter_vac_H[LYS].push_back(94.32937851921197);
+    4361           4 :   parameter_vac_H[LYS].push_back(-32.324473823417);
+    4362             : 
+    4363           4 :   parameter_vac_H[CYS].push_back(3.705624880856525);
+    4364           4 :   parameter_vac_H[CYS].push_back(0.005214780840206113);
+    4365           4 :   parameter_vac_H[CYS].push_back(1.25680902661715);
+    4366           4 :   parameter_vac_H[CYS].push_back(0.5779209425501814);
+    4367           4 :   parameter_vac_H[CYS].push_back(-3.716408071089366);
+    4368           4 :   parameter_vac_H[CYS].push_back(2.3947518943233117);
+    4369           4 :   parameter_vac_H[CYS].push_back(-0.40204949737133333);
+    4370             : 
+    4371           4 :   parameter_vac_H[ASP].push_back(14.776336119209605);
+    4372           4 :   parameter_vac_H[ASP].push_back(-0.037351220316916435);
+    4373           4 :   parameter_vac_H[ASP].push_back(-18.556358387626286);
+    4374           4 :   parameter_vac_H[ASP].push_back(-4.1737354794552886);
+    4375           4 :   parameter_vac_H[ASP].push_back(28.424721213037405);
+    4376           4 :   parameter_vac_H[ASP].push_back(-17.51389895324883);
+    4377           4 :   parameter_vac_H[ASP].push_back(2.9729111724708597);
+    4378             : 
+    4379           4 :   parameter_vac_H[GLU].push_back(14.145121119208973);
+    4380           4 :   parameter_vac_H[GLU].push_back(-0.11468766098213011);
+    4381           4 :   parameter_vac_H[GLU].push_back(-26.272637652294613);
+    4382           4 :   parameter_vac_H[GLU].push_back(-13.769758826440151);
+    4383           4 :   parameter_vac_H[GLU].push_back(80.4575683578491);
+    4384           4 :   parameter_vac_H[GLU].push_back(-64.19346347075);
+    4385           4 :   parameter_vac_H[GLU].push_back(15.545440117656236);
+    4386             : 
+    4387           4 :   parameter_vac_H[ILE].push_back(1.9488158808808775);
+    4388           4 :   parameter_vac_H[ILE].push_back(0.05873132133874459);
+    4389           4 :   parameter_vac_H[ILE].push_back(12.032778845884135);
+    4390           4 :   parameter_vac_H[ILE].push_back(7.148416980612881);
+    4391           4 :   parameter_vac_H[ILE].push_back(-41.87377843832961);
+    4392           4 :   parameter_vac_H[ILE].push_back(33.96120749582283);
+    4393           4 :   parameter_vac_H[ILE].push_back(-8.362535852631256);
+    4394             : 
+    4395           4 :   parameter_vac_H[LEU].push_back(1.9488158808977816);
+    4396           4 :   parameter_vac_H[LEU].push_back(0.0778305500414777);
+    4397           4 :   parameter_vac_H[LEU].push_back(12.333370614594);
+    4398           4 :   parameter_vac_H[LEU].push_back(9.449427967560764);
+    4399           4 :   parameter_vac_H[LEU].push_back(-52.65457680603262);
+    4400           4 :   parameter_vac_H[LEU].push_back(44.681877289399615);
+    4401           4 :   parameter_vac_H[LEU].push_back(-11.460498338671227);
+    4402             : 
+    4403           4 :   parameter_vac_H[MET].push_back(3.0940808808117652);
+    4404           4 :   parameter_vac_H[MET].push_back(0.04903755678213222);
+    4405           4 :   parameter_vac_H[MET].push_back(8.981927022922049);
+    4406           4 :   parameter_vac_H[MET].push_back(8.654862771879014);
+    4407           4 :   parameter_vac_H[MET].push_back(-57.09889409156816);
+    4408           4 :   parameter_vac_H[MET].push_back(58.87704775164829);
+    4409           4 :   parameter_vac_H[MET].push_back(-18.60431990258862);
+    4410             : 
+    4411           4 :   parameter_vac_H[ASN].push_back(11.943936119209074);
+    4412           4 :   parameter_vac_H[ASN].push_back(-0.0005000836239497835);
+    4413           4 :   parameter_vac_H[ASN].push_back(-9.581236453763157);
+    4414           4 :   parameter_vac_H[ASN].push_back(0.16244025786232308);
+    4415           4 :   parameter_vac_H[ASN].push_back(2.9276580099749574);
+    4416           4 :   parameter_vac_H[ASN].push_back(2.133535783835143);
+    4417           4 :   parameter_vac_H[ASN].push_back(-1.5709968820975018);
+    4418             : 
+    4419           4 :   parameter_vac_H[PRO].push_back(4.9595288808229245);
+    4420           4 :   parameter_vac_H[PRO].push_back(0.017853932680793515);
+    4421           4 :   parameter_vac_H[PRO].push_back(4.5421559293101605);
+    4422           4 :   parameter_vac_H[PRO].push_back(2.008455612787203);
+    4423           4 :   parameter_vac_H[PRO].push_back(-12.444117841318494);
+    4424           4 :   parameter_vac_H[PRO].push_back(8.511723688836447);
+    4425           4 :   parameter_vac_H[PRO].push_back(-1.6337543903496765);
+    4426             : 
+    4427           4 :   parameter_vac_H[GLN].push_back(11.377129119208574);
+    4428           4 :   parameter_vac_H[GLN].push_back(-0.0674805307761209);
+    4429           4 :   parameter_vac_H[GLN].push_back(-16.56692720411458);
+    4430           4 :   parameter_vac_H[GLN].push_back(-6.477707440126834);
+    4431           4 :   parameter_vac_H[GLN].push_back(34.78232259512621);
+    4432           4 :   parameter_vac_H[GLN].push_back(-19.450886909938312);
+    4433           4 :   parameter_vac_H[GLN].push_back(1.944286925108988);
+    4434             : 
+    4435           4 :   parameter_vac_H[SER].push_back(4.95062488096605);
+    4436           4 :   parameter_vac_H[SER].push_back(0.004676435440506079);
+    4437           4 :   parameter_vac_H[SER].push_back(-0.1896653085608564);
+    4438           4 :   parameter_vac_H[SER].push_back(0.5142284931977218);
+    4439           4 :   parameter_vac_H[SER].push_back(-2.8946087252759893);
+    4440           4 :   parameter_vac_H[SER].push_back(2.1031239401634836);
+    4441           4 :   parameter_vac_H[SER].push_back(-0.38226443516361713);
+    4442             : 
+    4443           4 :   parameter_vac_H[THR].push_back(4.588163880808971);
+    4444           4 :   parameter_vac_H[THR].push_back(0.018587905993982613);
+    4445           4 :   parameter_vac_H[THR].push_back(3.5289861308270214);
+    4446           4 :   parameter_vac_H[THR].push_back(2.0780583604591567);
+    4447           4 :   parameter_vac_H[THR].push_back(-12.3802007068414);
+    4448           4 :   parameter_vac_H[THR].push_back(8.720986674116094);
+    4449           4 :   parameter_vac_H[THR].push_back(-1.683256475122275);
+    4450             : 
+    4451           4 :   parameter_vac_H[VAL].push_back(2.187440880853519);
+    4452           4 :   parameter_vac_H[VAL].push_back(0.028351524826584255);
+    4453           4 :   parameter_vac_H[VAL].push_back(8.36584512491955);
+    4454           4 :   parameter_vac_H[VAL].push_back(3.1686206615123926);
+    4455           4 :   parameter_vac_H[VAL].push_back(-19.81959917770108);
+    4456           4 :   parameter_vac_H[VAL].push_back(13.293003038570571);
+    4457           4 :   parameter_vac_H[VAL].push_back(-2.4595257726774125);
+    4458             : 
+    4459           4 :   parameter_vac_H[ALA].push_back(2.7060248808167935);
+    4460           4 :   parameter_vac_H[ALA].push_back(0.004618897267213416);
+    4461           4 :   parameter_vac_H[ALA].push_back(2.4990261487383947);
+    4462           4 :   parameter_vac_H[ALA].push_back(0.49579332664340864);
+    4463           4 :   parameter_vac_H[ALA].push_back(-3.850400071630347);
+    4464           4 :   parameter_vac_H[ALA].push_back(1.9501161562030942);
+    4465           4 :   parameter_vac_H[ALA].push_back(-0.18332582719788362);
+    4466             : 
+    4467           4 :   parameter_vac_H[GLY].push_back(2.985983880876256);
+    4468           4 :   parameter_vac_H[GLY].push_back(0.0005033131808079042);
+    4469           4 :   parameter_vac_H[GLY].push_back(-0.42250170279962684);
+    4470           4 :   parameter_vac_H[GLY].push_back(0.05620517453257455);
+    4471           4 :   parameter_vac_H[GLY].push_back(-0.16801962822020733);
+    4472           4 :   parameter_vac_H[GLY].push_back(0.23635459648780555);
+    4473           4 :   parameter_vac_H[GLY].push_back(-0.06585244715658795);
+    4474             : 
+    4475           4 :   parameter_vac_H[HIS].push_back(22.77198411920933);
+    4476           4 :   parameter_vac_H[HIS].push_back(-0.06607491006655417);
+    4477           4 :   parameter_vac_H[HIS].push_back(-27.277710268717247);
+    4478           4 :   parameter_vac_H[HIS].push_back(-5.674444390934355);
+    4479           4 :   parameter_vac_H[HIS].push_back(33.4059567406171);
+    4480           4 :   parameter_vac_H[HIS].push_back(-11.60826210271092);
+    4481           4 :   parameter_vac_H[HIS].push_back(-1.7359607560773076);
+    4482             : 
+    4483             :   // NUCLEIC ACIDS
+    4484             : 
+    4485             :   // BB_PO2 H and D parameters are identical as there is no H or D in the bead.
+    4486           4 :   parameter_solv_H[BB_PO2].push_back(575.5201001192197);
+    4487           4 :   parameter_solv_H[BB_PO2].push_back(-0.6126595489733864);
+    4488           4 :   parameter_solv_H[BB_PO2].push_back(-623.3371092254899);
+    4489           4 :   parameter_solv_H[BB_PO2].push_back(-68.05795957022144);
+    4490           4 :   parameter_solv_H[BB_PO2].push_back(561.8052621243661);
+    4491           4 :   parameter_solv_H[BB_PO2].push_back(-283.39573309540276);
+    4492           4 :   parameter_solv_H[BB_PO2].push_back(35.550016980100295);
+    4493             : 
+    4494           4 :   parameter_solv_H[BB_DNA].push_back(21211.009600118316);
+    4495           4 :   parameter_solv_H[BB_DNA].push_back(-90.18805990529991);
+    4496           4 :   parameter_solv_H[BB_DNA].push_back(-39731.13373512149);
+    4497           4 :   parameter_solv_H[BB_DNA].push_back(-10920.373563712872);
+    4498           4 :   parameter_solv_H[BB_DNA].push_back(72882.21702424981);
+    4499           4 :   parameter_solv_H[BB_DNA].push_back(-51747.487078112776);
+    4500           4 :   parameter_solv_H[BB_DNA].push_back(11308.678429018755);
+    4501             : 
+    4502           4 :   parameter_solv_H[BB_DNA_5].push_back(22737.624100119025);
+    4503           4 :   parameter_solv_H[BB_DNA_5].push_back(-102.72714886664161);
+    4504           4 :   parameter_solv_H[BB_DNA_5].push_back(-43685.329677789734);
+    4505           4 :   parameter_solv_H[BB_DNA_5].push_back(-12564.25937409345);
+    4506           4 :   parameter_solv_H[BB_DNA_5].push_back(83454.87540484878);
+    4507           4 :   parameter_solv_H[BB_DNA_5].push_back(-60367.15652138887);
+    4508           4 :   parameter_solv_H[BB_DNA_5].push_back(13507.333729868991);
+    4509             : 
+    4510           4 :   parameter_solv_H[BB_DNA_3].push_back(22737.62410011902);
+    4511           4 :   parameter_solv_H[BB_DNA_3].push_back(-101.57816684452251);
+    4512           4 :   parameter_solv_H[BB_DNA_3].push_back(-43488.536705576145);
+    4513           4 :   parameter_solv_H[BB_DNA_3].push_back(-12345.056184958425);
+    4514           4 :   parameter_solv_H[BB_DNA_3].push_back(81963.52364114887);
+    4515           4 :   parameter_solv_H[BB_DNA_3].push_back(-58791.59443618196);
+    4516           4 :   parameter_solv_H[BB_DNA_3].push_back(13003.199362335583);
+    4517             : 
+    4518           4 :   parameter_solv_H[BB_RNA].push_back(23953.752900120977);
+    4519           4 :   parameter_solv_H[BB_RNA].push_back(-117.35779348824417);
+    4520           4 :   parameter_solv_H[BB_RNA].push_back(-47644.41735332843);
+    4521           4 :   parameter_solv_H[BB_RNA].push_back(-14641.556643789861);
+    4522           4 :   parameter_solv_H[BB_RNA].push_back(96893.48627050371);
+    4523           4 :   parameter_solv_H[BB_RNA].push_back(-72249.62534169303);
+    4524           4 :   parameter_solv_H[BB_RNA].push_back(16792.055521055358);
+    4525             : 
+    4526           4 :   parameter_solv_H[BB_RNA_5].push_back(25574.406400119024);
+    4527           4 :   parameter_solv_H[BB_RNA_5].push_back(-131.99642772933734);
+    4528           4 :   parameter_solv_H[BB_RNA_5].push_back(-52136.51404531251);
+    4529           4 :   parameter_solv_H[BB_RNA_5].push_back(-16682.14273917604);
+    4530           4 :   parameter_solv_H[BB_RNA_5].push_back(110278.01921639398);
+    4531           4 :   parameter_solv_H[BB_RNA_5].push_back(-83715.92027818544);
+    4532           4 :   parameter_solv_H[BB_RNA_5].push_back(19875.89133770605);
+    4533             : 
+    4534           4 :   parameter_solv_H[BB_RNA_3].push_back(25574.406400119027);
+    4535           4 :   parameter_solv_H[BB_RNA_3].push_back(-127.96875237036166);
+    4536           4 :   parameter_solv_H[BB_RNA_3].push_back(-51407.18391758439);
+    4537           4 :   parameter_solv_H[BB_RNA_3].push_back(-15922.900669975606);
+    4538           4 :   parameter_solv_H[BB_RNA_3].push_back(105078.5888910626);
+    4539           4 :   parameter_solv_H[BB_RNA_3].push_back(-78289.16276190645);
+    4540           4 :   parameter_solv_H[BB_RNA_3].push_back(18156.832143441192);
+    4541             : 
+    4542           4 :   parameter_solv_H[BASE_A].push_back(13282.562500119211);
+    4543           4 :   parameter_solv_H[BASE_A].push_back(-76.45124168404048);
+    4544           4 :   parameter_solv_H[BASE_A].push_back(-28376.06994108963);
+    4545           4 :   parameter_solv_H[BASE_A].push_back(-9972.910773722022);
+    4546           4 :   parameter_solv_H[BASE_A].push_back(65873.86341939073);
+    4547           4 :   parameter_solv_H[BASE_A].push_back(-52064.33492910885);
+    4548           4 :   parameter_solv_H[BASE_A].push_back(12931.608989412513);
+    4549             : 
+    4550           4 :   parameter_solv_H[BASE_C].push_back(10600.76160011891);
+    4551           4 :   parameter_solv_H[BASE_C].push_back(-49.1670871249108);
+    4552           4 :   parameter_solv_H[BASE_C].push_back(-20239.818742072875);
+    4553           4 :   parameter_solv_H[BASE_C].push_back(-6020.278780090207);
+    4554           4 :   parameter_solv_H[BASE_C].push_back(39632.13288981881);
+    4555           4 :   parameter_solv_H[BASE_C].push_back(-28954.779736165576);
+    4556           4 :   parameter_solv_H[BASE_C].push_back(6551.541109526305);
+    4557             : 
+    4558           4 :   parameter_solv_H[BASE_G].push_back(15470.384400119934);
+    4559           4 :   parameter_solv_H[BASE_G].push_back(-93.8013620200972);
+    4560           4 :   parameter_solv_H[BASE_G].push_back(-36188.29687013545);
+    4561           4 :   parameter_solv_H[BASE_G].push_back(-13717.685098209471);
+    4562           4 :   parameter_solv_H[BASE_G].push_back(95658.18473657136);
+    4563           4 :   parameter_solv_H[BASE_G].push_back(-81262.37811451119);
+    4564           4 :   parameter_solv_H[BASE_G].push_back(21841.903930943085);
+    4565             : 
+    4566           4 :   parameter_solv_H[BASE_T].push_back(17210.81610011936);
+    4567           4 :   parameter_solv_H[BASE_T].push_back(-93.10189802920208);
+    4568           4 :   parameter_solv_H[BASE_T].push_back(-36466.51927689957);
+    4569           4 :   parameter_solv_H[BASE_T].push_back(-12425.55615716932);
+    4570           4 :   parameter_solv_H[BASE_T].push_back(83847.427808925);
+    4571           4 :   parameter_solv_H[BASE_T].push_back(-66735.64997846584);
+    4572           4 :   parameter_solv_H[BASE_T].push_back(16757.3463987507);
+    4573             : 
+    4574           4 :   parameter_solv_H[BASE_U].push_back(10909.802500119395);
+    4575           4 :   parameter_solv_H[BASE_U].push_back(-46.17712672768298);
+    4576           4 :   parameter_solv_H[BASE_U].push_back(-20149.67695512526);
+    4577           4 :   parameter_solv_H[BASE_U].push_back(-5590.242961204435);
+    4578           4 :   parameter_solv_H[BASE_U].push_back(37169.2740983132);
+    4579           4 :   parameter_solv_H[BASE_U].push_back(-26475.631627167604);
+    4580           4 :   parameter_solv_H[BASE_U].push_back(5808.201015156168);
+    4581             : 
+    4582           4 :   parameter_mix_H[BB_PO2].push_back(80.12660011920252);
+    4583           4 :   parameter_mix_H[BB_PO2].push_back(-0.0278885551982023);
+    4584           4 :   parameter_mix_H[BB_PO2].push_back(-60.532194918222984);
+    4585           4 :   parameter_mix_H[BB_PO2].push_back(-2.976882903409687);
+    4586           4 :   parameter_mix_H[BB_PO2].push_back(33.30645116638125);
+    4587           4 :   parameter_mix_H[BB_PO2].push_back(-11.601573219761374);
+    4588           4 :   parameter_mix_H[BB_PO2].push_back(0.12551046492022422);
+    4589             : 
+    4590           4 :   parameter_mix_H[BB_DNA].push_back(712.7621601191935);
+    4591           4 :   parameter_mix_H[BB_DNA].push_back(-0.3228709821198571);
+    4592           4 :   parameter_mix_H[BB_DNA].push_back(-784.5118228559945);
+    4593           4 :   parameter_mix_H[BB_DNA].push_back(-27.196125702249613);
+    4594           4 :   parameter_mix_H[BB_DNA].push_back(410.0185035102729);
+    4595           4 :   parameter_mix_H[BB_DNA].push_back(-54.453513369320355);
+    4596           4 :   parameter_mix_H[BB_DNA].push_back(-44.85506789237683);
+    4597             : 
+    4598           4 :   parameter_mix_H[BB_DNA_5].push_back(625.175339965785);
+    4599           4 :   parameter_mix_H[BB_DNA_5].push_back(0.2691706617748245);
+    4600           4 :   parameter_mix_H[BB_DNA_5].push_back(-582.8721350420001);
+    4601           4 :   parameter_mix_H[BB_DNA_5].push_back(46.512408351374326);
+    4602           4 :   parameter_mix_H[BB_DNA_5].push_back(-58.93886949899108);
+    4603           4 :   parameter_mix_H[BB_DNA_5].push_back(307.29720336085046);
+    4604           4 :   parameter_mix_H[BB_DNA_5].push_back(-131.71996309259953);
+    4605             : 
+    4606           4 :   parameter_mix_H[BB_DNA_3].push_back(625.1753399401266);
+    4607           4 :   parameter_mix_H[BB_DNA_3].push_back(0.08763234414546289);
+    4608           4 :   parameter_mix_H[BB_DNA_3].push_back(-606.8067575087485);
+    4609           4 :   parameter_mix_H[BB_DNA_3].push_back(20.84427254872218);
+    4610           4 :   parameter_mix_H[BB_DNA_3].push_back(92.53523123608991);
+    4611           4 :   parameter_mix_H[BB_DNA_3].push_back(162.04688035654937);
+    4612           4 :   parameter_mix_H[BB_DNA_3].push_back(-89.13571774638052);
+    4613             : 
+    4614           4 :   parameter_mix_H[BB_RNA].push_back(936.9775801191857);
+    4615           4 :   parameter_mix_H[BB_RNA].push_back(-1.3233686929680253);
+    4616           4 :   parameter_mix_H[BB_RNA].push_back(-1212.1627155263773);
+    4617           4 :   parameter_mix_H[BB_RNA].push_back(-141.35324744384351);
+    4618           4 :   parameter_mix_H[BB_RNA].push_back(1155.8281658363026);
+    4619           4 :   parameter_mix_H[BB_RNA].push_back(-548.9340055857343);
+    4620           4 :   parameter_mix_H[BB_RNA].push_back(50.81734777881503);
+    4621             : 
+    4622           4 :   parameter_mix_H[BB_RNA_5].push_back(848.5355201165631);
+    4623           4 :   parameter_mix_H[BB_RNA_5].push_back(-0.49570338490120175);
+    4624           4 :   parameter_mix_H[BB_RNA_5].push_back(-976.1033073783973);
+    4625           4 :   parameter_mix_H[BB_RNA_5].push_back(-32.943532187986605);
+    4626           4 :   parameter_mix_H[BB_RNA_5].push_back(475.66177061923884);
+    4627           4 :   parameter_mix_H[BB_RNA_5].push_back(17.51955845824258);
+    4628           4 :   parameter_mix_H[BB_RNA_5].push_back(-96.74451972314769);
+    4629             : 
+    4630           4 :   parameter_mix_H[BB_RNA_3].push_back(848.5355201192122);
+    4631           4 :   parameter_mix_H[BB_RNA_3].push_back(-0.8301109354355396);
+    4632           4 :   parameter_mix_H[BB_RNA_3].push_back(-1019.9524389785406);
+    4633           4 :   parameter_mix_H[BB_RNA_3].push_back(-84.1388451424885);
+    4634           4 :   parameter_mix_H[BB_RNA_3].push_back(787.1277245040931);
+    4635           4 :   parameter_mix_H[BB_RNA_3].push_back(-294.67807432795627);
+    4636           4 :   parameter_mix_H[BB_RNA_3].push_back(-1.3214626461251089);
+    4637             : 
+    4638           4 :   parameter_mix_H[BASE_A].push_back(1504.9345001191857);
+    4639           4 :   parameter_mix_H[BASE_A].push_back(-3.5306888452552663);
+    4640           4 :   parameter_mix_H[BASE_A].push_back(-2234.3933572775572);
+    4641           4 :   parameter_mix_H[BASE_A].push_back(-380.0255208494757);
+    4642           4 :   parameter_mix_H[BASE_A].push_back(2726.27802432048);
+    4643           4 :   parameter_mix_H[BASE_A].push_back(-1490.8825754968443);
+    4644           4 :   parameter_mix_H[BASE_A].push_back(199.7501110740159);
+    4645             : 
+    4646           4 :   parameter_mix_H[BASE_C].push_back(939.8188801192172);
+    4647           4 :   parameter_mix_H[BASE_C].push_back(-1.489638186262854);
+    4648           4 :   parameter_mix_H[BASE_C].push_back(-1244.5515798554075);
+    4649           4 :   parameter_mix_H[BASE_C].push_back(-161.3972705672055);
+    4650           4 :   parameter_mix_H[BASE_C].push_back(1276.3568466722545);
+    4651           4 :   parameter_mix_H[BASE_C].push_back(-643.3057776225742);
+    4652           4 :   parameter_mix_H[BASE_C].push_back(72.75963113826273);
+    4653             : 
+    4654           4 :   parameter_mix_H[BASE_G].push_back(1768.434840119199);
+    4655           4 :   parameter_mix_H[BASE_G].push_back(-6.505347007077434);
+    4656           4 :   parameter_mix_H[BASE_G].push_back(-2919.3856777898427);
+    4657           4 :   parameter_mix_H[BASE_G].push_back(-701.2456464463938);
+    4658           4 :   parameter_mix_H[BASE_G].push_back(4464.594230284102);
+    4659           4 :   parameter_mix_H[BASE_G].push_back(-2733.138521295608);
+    4660           4 :   parameter_mix_H[BASE_G].push_back(458.1177706235891);
+    4661             : 
+    4662           4 :   parameter_mix_H[BASE_T].push_back(1179.3981001192033);
+    4663           4 :   parameter_mix_H[BASE_T].push_back(-3.2037849252756527);
+    4664           4 :   parameter_mix_H[BASE_T].push_back(-1821.255498763799);
+    4665           4 :   parameter_mix_H[BASE_T].push_back(-371.01993266441303);
+    4666           4 :   parameter_mix_H[BASE_T].push_back(2604.074226688971);
+    4667           4 :   parameter_mix_H[BASE_T].push_back(-1648.1965787713084);
+    4668           4 :   parameter_mix_H[BASE_T].push_back(307.2962186436368);
+    4669             : 
+    4670           4 :   parameter_mix_H[BASE_U].push_back(956.3442001192266);
+    4671           4 :   parameter_mix_H[BASE_U].push_back(-1.724458000760567);
+    4672           4 :   parameter_mix_H[BASE_U].push_back(-1287.9746970192687);
+    4673           4 :   parameter_mix_H[BASE_U].push_back(-192.74748379510373);
+    4674           4 :   parameter_mix_H[BASE_U].push_back(1459.0789258833893);
+    4675           4 :   parameter_mix_H[BASE_U].push_back(-810.0763075080915);
+    4676           4 :   parameter_mix_H[BASE_U].push_back(119.81810290248339);
+    4677             : 
+    4678           4 :   parameter_vac_H[BB_PO2].push_back(2.7889001116093275);
+    4679           4 :   parameter_vac_H[BB_PO2].push_back(-0.00011178884266113128);
+    4680           4 :   parameter_vac_H[BB_PO2].push_back(-1.1702605818380667);
+    4681           4 :   parameter_vac_H[BB_PO2].push_back(-0.011278044036819933);
+    4682           4 :   parameter_vac_H[BB_PO2].push_back(0.3214006584089025);
+    4683           4 :   parameter_vac_H[BB_PO2].push_back(-0.04097165983591666);
+    4684           4 :   parameter_vac_H[BB_PO2].push_back(-0.017525098100539722);
+    4685             : 
+    4686           4 :   parameter_vac_H[BB_DNA].push_back(5.987809026456476);
+    4687           4 :   parameter_vac_H[BB_DNA].push_back(9.945454528827912e-05);
+    4688           4 :   parameter_vac_H[BB_DNA].push_back(-1.1884708569330031);
+    4689           4 :   parameter_vac_H[BB_DNA].push_back(-0.007457733256362841);
+    4690           4 :   parameter_vac_H[BB_DNA].push_back(0.05666858781418339);
+    4691           4 :   parameter_vac_H[BB_DNA].push_back(-0.15158797629971757);
+    4692           4 :   parameter_vac_H[BB_DNA].push_back(0.11642340861329734);
+    4693             : 
+    4694           4 :   parameter_vac_H[BB_DNA_5].push_back(4.297328944539055);
+    4695           4 :   parameter_vac_H[BB_DNA_5].push_back(0.0014793971885106831);
+    4696           4 :   parameter_vac_H[BB_DNA_5].push_back(1.3961088365255605);
+    4697           4 :   parameter_vac_H[BB_DNA_5].push_back(0.08974639858979384);
+    4698           4 :   parameter_vac_H[BB_DNA_5].push_back(-1.5198099705167643);
+    4699           4 :   parameter_vac_H[BB_DNA_5].push_back(-0.12127122359433733);
+    4700           4 :   parameter_vac_H[BB_DNA_5].push_back(0.4134601046223601);
+    4701             : 
+    4702           4 :   parameter_vac_H[BB_DNA_3].push_back(4.297328886488132);
+    4703           4 :   parameter_vac_H[BB_DNA_3].push_back(0.0041802954281271905);
+    4704           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6065462295705266);
+    4705           4 :   parameter_vac_H[BB_DNA_3].push_back(0.4399805535688805);
+    4706           4 :   parameter_vac_H[BB_DNA_3].push_back(-3.3806711791929804);
+    4707           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6729551563628675);
+    4708           4 :   parameter_vac_H[BB_DNA_3].push_back(-0.10911063067909885);
+    4709             : 
+    4710           4 :   parameter_vac_H[BB_RNA].push_back(9.162728984394093);
+    4711           4 :   parameter_vac_H[BB_RNA].push_back(0.00019952321584579868);
+    4712           4 :   parameter_vac_H[BB_RNA].push_back(-4.744748946331966);
+    4713           4 :   parameter_vac_H[BB_RNA].push_back(0.025106563403946364);
+    4714           4 :   parameter_vac_H[BB_RNA].push_back(1.2302956694109803);
+    4715           4 :   parameter_vac_H[BB_RNA].push_back(0.12359062278096915);
+    4716           4 :   parameter_vac_H[BB_RNA].push_back(-0.1725633367685285);
+    4717             : 
+    4718           4 :   parameter_vac_H[BB_RNA_5].push_back(7.038408898671503);
+    4719           4 :   parameter_vac_H[BB_RNA_5].push_back(0.005106788424920148);
+    4720           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.8981588221803118);
+    4721           4 :   parameter_vac_H[BB_RNA_5].push_back(0.4922588155214312);
+    4722           4 :   parameter_vac_H[BB_RNA_5].push_back(-2.6667853454023644);
+    4723           4 :   parameter_vac_H[BB_RNA_5].push_back(1.533316567240718);
+    4724           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.07199604869737707);
+    4725             : 
+    4726           4 :   parameter_vac_H[BB_RNA_3].push_back(7.038408892621863);
+    4727           4 :   parameter_vac_H[BB_RNA_3].push_back(0.002993083907266898);
+    4728           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.3626596831098492);
+    4729           4 :   parameter_vac_H[BB_RNA_3].push_back(0.3138856961130113);
+    4730           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.684185014289391);
+    4731           4 :   parameter_vac_H[BB_RNA_3].push_back(1.1862168720864616);
+    4732           4 :   parameter_vac_H[BB_RNA_3].push_back(-0.1443894172417523);
+    4733             : 
+    4734           4 :   parameter_vac_H[BASE_A].push_back(42.62784088079008);
+    4735           4 :   parameter_vac_H[BASE_A].push_back(0.02302908536431516);
+    4736           4 :   parameter_vac_H[BASE_A].push_back(-33.22707177297222);
+    4737           4 :   parameter_vac_H[BASE_A].push_back(2.6853748424439834);
+    4738           4 :   parameter_vac_H[BASE_A].push_back(-1.6632902891624768);
+    4739           4 :   parameter_vac_H[BASE_A].push_back(11.905766349515268);
+    4740           4 :   parameter_vac_H[BASE_A].push_back(-4.547083454788805);
+    4741             : 
+    4742           4 :   parameter_vac_H[BASE_C].push_back(20.83009588079022);
+    4743           4 :   parameter_vac_H[BASE_C].push_back(0.017055822321768378);
+    4744           4 :   parameter_vac_H[BASE_C].push_back(-8.349634734370916);
+    4745           4 :   parameter_vac_H[BASE_C].push_back(1.9324634367723073);
+    4746           4 :   parameter_vac_H[BASE_C].push_back(-8.435199734060882);
+    4747           4 :   parameter_vac_H[BASE_C].push_back(8.272798368731268);
+    4748           4 :   parameter_vac_H[BASE_C].push_back(-1.986671440757263);
+    4749             : 
+    4750           4 :   parameter_vac_H[BASE_G].push_back(50.53788088079374);
+    4751           4 :   parameter_vac_H[BASE_G].push_back(0.024035597617780367);
+    4752           4 :   parameter_vac_H[BASE_G].push_back(-47.94916639302998);
+    4753           4 :   parameter_vac_H[BASE_G].push_back(3.143375731466498);
+    4754           4 :   parameter_vac_H[BASE_G].push_back(4.297009866708155);
+    4755           4 :   parameter_vac_H[BASE_G].push_back(15.855448505050578);
+    4756           4 :   parameter_vac_H[BASE_G].push_back(-7.827484135873966);
+    4757             : 
+    4758           4 :   parameter_vac_H[BASE_T].push_back(20.20502488079069);
+    4759           4 :   parameter_vac_H[BASE_T].push_back(0.033659966153300002);
+    4760           4 :   parameter_vac_H[BASE_T].push_back(-6.057999187718758);
+    4761           4 :   parameter_vac_H[BASE_T].push_back(4.146969282504351);
+    4762           4 :   parameter_vac_H[BASE_T].push_back(-20.664315319574357);
+    4763           4 :   parameter_vac_H[BASE_T].push_back(19.982178623201648);
+    4764           4 :   parameter_vac_H[BASE_T].push_back(-5.440921587349456);
+    4765             : 
+    4766           4 :   parameter_vac_H[BASE_U].push_back(20.958084119209754);
+    4767           4 :   parameter_vac_H[BASE_U].push_back(-0.005164660707148803);
+    4768           4 :   parameter_vac_H[BASE_U].push_back(-14.53831312442302);
+    4769           4 :   parameter_vac_H[BASE_U].push_back(-0.5276995756310442);
+    4770           4 :   parameter_vac_H[BASE_U].push_back(7.060900707522138);
+    4771           4 :   parameter_vac_H[BASE_U].push_back(-1.8988408480951036);
+    4772           4 :   parameter_vac_H[BASE_U].push_back(-0.215000567681094);
+    4773             : 
+    4774       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    4775       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    4776       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    4777       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    4778       14294 :     if(Rname=="ALA") {
+    4779         732 :       atoi[residue_atom[i]]=ALA;
+    4780       13562 :     } else if(Rname=="ARG") {
+    4781         864 :       atoi[residue_atom[i]]=ARG;
+    4782       12698 :     } else if(Rname=="ASN") {
+    4783         720 :       atoi[residue_atom[i]]=ASN;
+    4784       11978 :     } else if(Rname=="ASP") {
+    4785         624 :       atoi[residue_atom[i]]=ASP;
+    4786       11354 :     } else if(Rname=="CYS") {
+    4787          48 :       atoi[residue_atom[i]]=CYS;
+    4788       11306 :     } else if(Rname=="GLN") {
+    4789        1064 :       atoi[residue_atom[i]]=GLN;
+    4790       10242 :     } else if(Rname=="GLU") {
+    4791         476 :       atoi[residue_atom[i]]=GLU;
+    4792        9766 :     } else if(Rname=="GLY") {
+    4793         648 :       atoi[residue_atom[i]]=GLY;
+    4794        9118 :     } else if(Rname=="HIS") {
+    4795           0 :       atoi[residue_atom[i]]=HIS;
+    4796        9118 :     } else if(Rname=="HID") {
+    4797           0 :       atoi[residue_atom[i]]=HIS;
+    4798        9118 :     } else if(Rname=="HIE") {
+    4799         144 :       atoi[residue_atom[i]]=HIS;
+    4800        8974 :     } else if(Rname=="HIP") {
+    4801           0 :       atoi[residue_atom[i]]=HIP;
+    4802             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    4803        8974 :     } else if(Rname=="HSD") {
+    4804           0 :       atoi[residue_atom[i]]=HIS;
+    4805        8974 :     } else if(Rname=="HSE") {
+    4806           0 :       atoi[residue_atom[i]]=HIS;
+    4807        8974 :     } else if(Rname=="HSP") {
+    4808           0 :       atoi[residue_atom[i]]=HIP;
+    4809        8974 :     } else if(Rname=="ILE") {
+    4810         864 :       atoi[residue_atom[i]]=ILE;
+    4811        8110 :     } else if(Rname=="LEU") {
+    4812        1520 :       atoi[residue_atom[i]]=LEU;
+    4813        6590 :     } else if(Rname=="LYS") {
+    4814        1040 :       atoi[residue_atom[i]]=LYS;
+    4815        5550 :     } else if(Rname=="MET") {
+    4816         608 :       atoi[residue_atom[i]]=MET;
+    4817        4942 :     } else if(Rname=="PHE") {
+    4818        1008 :       atoi[residue_atom[i]]=PHE;
+    4819        3934 :     } else if(Rname=="PRO") {
+    4820         748 :       atoi[residue_atom[i]]=PRO;
+    4821        3186 :     } else if(Rname=="SER") {
+    4822         528 :       atoi[residue_atom[i]]=SER;
+    4823        2658 :     } else if(Rname=="THR") {
+    4824         504 :       atoi[residue_atom[i]]=THR;
+    4825        2154 :     } else if(Rname=="TRP") {
+    4826           0 :       atoi[residue_atom[i]]=TRP;
+    4827        2154 :     } else if(Rname=="TYR") {
+    4828         528 :       atoi[residue_atom[i]]=TYR;
+    4829        1626 :     } else if(Rname=="VAL") {
+    4830        1088 :       atoi[residue_atom[i]]=VAL;
+    4831             :     }
+    4832             :     // NUCLEIC ACIDS
+    4833             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    4834             :     // RNA - G
+    4835         538 :     else if(Rname=="G") {
+    4836           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4837           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4838           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4839           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4840           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4841           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4842           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4843           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4844           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4845           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4846           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4847           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4848           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4849           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4850           0 :         atoi[residue_atom[i]]=BASE_G;
+    4851           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4852             :       // RNA - G3
+    4853         538 :     } else if(Rname=="G3") {
+    4854           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4855           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4856           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4857           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4858           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4859           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4860           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4861           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4862           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4863           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4864           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4865           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4866           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4867           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4868           0 :         atoi[residue_atom[i]]=BASE_G;
+    4869           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4870             :       // RNA - G5
+    4871         538 :     } else if(Rname=="G5") {
+    4872           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4873           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4874           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4875           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4876           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4877           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4878           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4879           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4880           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4881           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4882           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4883           0 :         atoi[residue_atom[i]]=BASE_G;
+    4884           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4885             :       // RNA - U
+    4886         538 :     } else if(Rname=="U") {
+    4887        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4888        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4889          42 :         atoi [residue_atom[i]]=BB_PO2;
+    4890        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4891        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4892         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4893         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4894         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4895         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4896         224 :         atoi[residue_atom[i]]=BB_RNA;
+    4897         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4898         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4899         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4900         154 :         atoi[residue_atom[i]]=BASE_U;
+    4901           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4902             :       // RNA - U3
+    4903         118 :     } else if(Rname=="U3") {
+    4904         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4905         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4906           6 :         atoi [residue_atom[i]]=BB_PO2;
+    4907         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4908         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4909         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4910         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4911          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4912          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4913          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4914          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4915          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4916          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4917          22 :         atoi[residue_atom[i]]=BASE_U;
+    4918           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4919             :       // RNA - U5
+    4920          56 :     } else if(Rname=="U5") {
+    4921         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4922         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4923         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4924         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4925          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4926          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4927          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4928          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    4929          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    4930          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    4931          22 :         atoi[residue_atom[i]]=BASE_U;
+    4932           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4933             :       // RNA - A
+    4934           0 :     } else if(Rname=="A") {
+    4935           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4936           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4937           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4938           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4939           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4940           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4941           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4942           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4943           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4944           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4945           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4946           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4947           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4948           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4949           0 :         atoi[residue_atom[i]]=BASE_A;
+    4950           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4951             :       // RNA - A3
+    4952           0 :     } else if(Rname=="A3") {
+    4953           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4954           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4955           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4956           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4957           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4958           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4959           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4960           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4961           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4962           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4963           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4964           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4965           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4966           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4967           0 :         atoi[residue_atom[i]]=BASE_A;
+    4968           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4969             :       // RNA - A5
+    4970           0 :     } else if(Rname=="A5") {
+    4971           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4972           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4973           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4974           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4975           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4976           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4977           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4978           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4979           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4980           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4981           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4982           0 :         atoi[residue_atom[i]]=BASE_A;
+    4983           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4984             :       // RNA - C
+    4985           0 :     } else if(Rname=="C") {
+    4986           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4987           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4988           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4989           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4990           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4991           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4992           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4993           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4994           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4995           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4996           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4997           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4998           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4999           0 :         atoi[residue_atom[i]]=BASE_C;
+    5000           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5001             :       // RNA - C3
+    5002           0 :     } else if(Rname=="C3") {
+    5003           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5004           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5005           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5006           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5007           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5008           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5009           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5010           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5011           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5012           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5013           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5014           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5015           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5016           0 :         atoi[residue_atom[i]]=BASE_C;
+    5017           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5018             :       // RNA - C5
+    5019           0 :     } else if(Rname=="C5") {
+    5020           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5021           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5022           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5023           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5024           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5025           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5026           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5027           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5028           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5029           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5030           0 :         atoi[residue_atom[i]]=BASE_C;
+    5031           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5032             :       // DNA - G
+    5033           0 :     } else if(Rname=="DG") {
+    5034           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5035           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5036           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5037           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5038           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5039           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5040           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5041           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5042           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5043           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5044           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5045           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5046           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5047           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5048           0 :         atoi[residue_atom[i]]=BASE_G;
+    5049           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5050             :       // DNA - G3
+    5051           0 :     } else if(Rname=="DG3") {
+    5052           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5053           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5054           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5055           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5056           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5057           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5058           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5059           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5060             :                 Aname=="H3T" ) {
+    5061           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5062           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5063           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5064           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5065           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5066           0 :         atoi[residue_atom[i]]=BASE_G;
+    5067           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5068             :       // DNA - G5
+    5069           0 :     } else if(Rname=="DG5") {
+    5070           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5071           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5072           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5073           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5074           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5075             :           Aname=="H5T" ) {
+    5076           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5077           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5078           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5079           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5080           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5081           0 :         atoi[residue_atom[i]]=BASE_G;
+    5082           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5083             :       // DNA - T
+    5084           0 :     } else if(Rname=="DT") {
+    5085           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5086           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5087           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5088           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5089           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5090           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5091           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5092           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5093           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5094           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5095           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5096           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5097           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5098           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5099           0 :         atoi[residue_atom[i]]=BASE_T;
+    5100           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5101             :       // DNA - T3
+    5102           0 :     } else if(Rname=="DT3") {
+    5103           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5104           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5105           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5106           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5107           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5108           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5109           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5110           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5111             :                 Aname=="H3T" ) {
+    5112           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5113           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5114           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5115           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5116           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5117           0 :         atoi[residue_atom[i]]=BASE_T;
+    5118           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5119             :       // DNA - T5
+    5120           0 :     } else if(Rname=="DT5") {
+    5121           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5122           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5123           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5124           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5125           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5126             :           Aname=="H5T" ) {
+    5127           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5128           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5129           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5130           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5131           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5132           0 :         atoi[residue_atom[i]]=BASE_T;
+    5133           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5134             :       // DNA - A
+    5135           0 :     } else if(Rname=="DA") {
+    5136           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5137           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5138           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5139           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5140           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5141           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5142           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5143           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5144           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5145           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5146           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5147           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5148           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5149           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5150           0 :         atoi[residue_atom[i]]=BASE_A;
+    5151           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5152             :       // DNA - A3
+    5153           0 :     } else if(Rname=="DA3") {
+    5154           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5155           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5156           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5157           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5158           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5159           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5160           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5161           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5162             :                 Aname=="H3T" ) {
+    5163           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5164           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5165           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5166           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5167           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5168           0 :         atoi[residue_atom[i]]=BASE_A;
+    5169           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5170             :       // DNA - A5
+    5171           0 :     } else if(Rname=="DA5") {
+    5172           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5173           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5174           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5175           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5176           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5177             :           Aname=="H5T" ) {
+    5178           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5179           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5180           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5181           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5182           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5183           0 :         atoi[residue_atom[i]]=BASE_A;
+    5184           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5185             :       // DNA - C
+    5186           0 :     } else if(Rname=="DC") {
+    5187           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5188           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5189           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5190           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5191           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5192           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5193           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5194           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5195           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5196           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5197           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5198           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5199           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5200           0 :         atoi[residue_atom[i]]=BASE_C;
+    5201           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5202             :       // DNA - C3
+    5203           0 :     } else if(Rname=="DC3") {
+    5204           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5205           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5206           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5207           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5208           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5209           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5210           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5211           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5212             :                 Aname=="H3T" ) {
+    5213           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5214           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5215           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5216           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5217           0 :         atoi[residue_atom[i]]=BASE_C;
+    5218           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5219             :       // DNA - C5
+    5220           0 :     } else if(Rname=="DC5") {
+    5221           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5222           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5223           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5224           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5225           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5226             :           Aname=="H5T" ) {
+    5227           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5228           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5229           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5230           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5231           0 :         atoi[residue_atom[i]]=BASE_C;
+    5232           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5233           0 :     } else error("Residue not known: "+Rname);
+    5234             :   }
+    5235           4 : }
+    5236             : 
+    5237           4 : void SAXS::getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D)
+    5238             : { // parameter_solv is identical in SAXS/SANS_H/SANS_D since it depends exclusively on param_v. For that reason we kept param_solv only in SAXS and SANS_H.
+    5239           4 :   parameter_mix_D[TRP].push_back(8105.740500119327);
+    5240           4 :   parameter_mix_D[TRP].push_back(-41.785616935469804);
+    5241           4 :   parameter_mix_D[TRP].push_back(-25456.92790554363);
+    5242           4 :   parameter_mix_D[TRP].push_back(-10058.20599969184);
+    5243           4 :   parameter_mix_D[TRP].push_back(86171.76479108425);
+    5244           4 :   parameter_mix_D[TRP].push_back(-83227.63139882773);
+    5245           4 :   parameter_mix_D[TRP].push_back(25121.390436258724);
+    5246             : 
+    5247           4 :   parameter_mix_D[TYR].push_back(6059.530560118732);
+    5248           4 :   parameter_mix_D[TYR].push_back(-24.522695525705736);
+    5249           4 :   parameter_mix_D[TYR].push_back(-17180.858815360847);
+    5250           4 :   parameter_mix_D[TYR].push_back(-5990.1358528219325);
+    5251           4 :   parameter_mix_D[TYR].push_back(52936.46126637543);
+    5252           4 :   parameter_mix_D[TYR].push_back(-50150.0042622683);
+    5253           4 :   parameter_mix_D[TYR].push_back(14914.553672440441);
+    5254             : 
+    5255           4 :   parameter_mix_D[PHE].push_back(5563.404880119222);
+    5256           4 :   parameter_mix_D[PHE].push_back(-33.609784645922794);
+    5257           4 :   parameter_mix_D[PHE].push_back(-14576.935030777448);
+    5258           4 :   parameter_mix_D[PHE].push_back(-5759.170105553782);
+    5259           4 :   parameter_mix_D[PHE].push_back(43316.895956549866);
+    5260           4 :   parameter_mix_D[PHE].push_back(-39106.58694570862);
+    5261           4 :   parameter_mix_D[PHE].push_back(11143.375742877468);
+    5262             : 
+    5263           4 :   parameter_mix_D[HIP].push_back(3981.7108801192553);
+    5264           4 :   parameter_mix_D[HIP].push_back(-23.788371565946427);
+    5265           4 :   parameter_mix_D[HIP].push_back(-9471.73953776056);
+    5266           4 :   parameter_mix_D[HIP].push_back(-3690.3981577198365);
+    5267           4 :   parameter_mix_D[HIP].push_back(26365.958584217453);
+    5268           4 :   parameter_mix_D[HIP].push_back(-23067.58974902849);
+    5269           4 :   parameter_mix_D[HIP].push_back(6390.507451097114);
+    5270             : 
+    5271           4 :   parameter_mix_D[ARG].push_back(6279.489359881259);
+    5272           4 :   parameter_mix_D[ARG].push_back(1.2061878338083583);
+    5273           4 :   parameter_mix_D[ARG].push_back(-20305.413937989913);
+    5274           4 :   parameter_mix_D[ARG].push_back(-5621.666335222669);
+    5275           4 :   parameter_mix_D[ARG].push_back(67341.96785520067);
+    5276           4 :   parameter_mix_D[ARG].push_back(-68849.15464591733);
+    5277           4 :   parameter_mix_D[ARG].push_back(21773.0630363882);
+    5278             : 
+    5279           4 :   parameter_mix_D[LYS].push_back(5434.487400119193);
+    5280           4 :   parameter_mix_D[LYS].push_back(-29.32356328987909);
+    5281           4 :   parameter_mix_D[LYS].push_back(-14363.66155749977);
+    5282           4 :   parameter_mix_D[LYS].push_back(-5650.383128516514);
+    5283           4 :   parameter_mix_D[LYS].push_back(44573.73888236887);
+    5284           4 :   parameter_mix_D[LYS].push_back(-41515.980945300485);
+    5285           4 :   parameter_mix_D[LYS].push_back(12181.965046747513);
+    5286             : 
+    5287           4 :   parameter_mix_D[CYS].push_back(1519.4030001192032);
+    5288           4 :   parameter_mix_D[CYS].push_back(-3.564386334921097);
+    5289           4 :   parameter_mix_D[CYS].push_back(-2275.813167459516);
+    5290           4 :   parameter_mix_D[CYS].push_back(-409.54431591328125);
+    5291           4 :   parameter_mix_D[CYS].push_back(2969.5412742839258);
+    5292           4 :   parameter_mix_D[CYS].push_back(-1798.3157146799638);
+    5293           4 :   parameter_mix_D[CYS].push_back(314.568167888235);
+    5294             : 
+    5295           4 :   parameter_mix_D[ASP].push_back(1861.6998401191709);
+    5296           4 :   parameter_mix_D[ASP].push_back(-5.349780637260551);
+    5297           4 :   parameter_mix_D[ASP].push_back(-2960.36741510377);
+    5298           4 :   parameter_mix_D[ASP].push_back(-621.8270745040523);
+    5299           4 :   parameter_mix_D[ASP].push_back(4334.798300452934);
+    5300           4 :   parameter_mix_D[ASP].push_back(-2776.8560521554878);
+    5301           4 :   parameter_mix_D[ASP].push_back(527.9777182094936);
+    5302             : 
+    5303           4 :   parameter_mix_D[GLU].push_back(2861.6017201192253);
+    5304           4 :   parameter_mix_D[GLU].push_back(-13.146456903921809);
+    5305           4 :   parameter_mix_D[GLU].push_back(-5393.408563875243);
+    5306           4 :   parameter_mix_D[GLU].push_back(-1646.460570818364);
+    5307           4 :   parameter_mix_D[GLU].push_back(10884.544923253858);
+    5308           4 :   parameter_mix_D[GLU].push_back(-8159.923373048856);
+    5309           4 :   parameter_mix_D[GLU].push_back(1914.545660397314);
+    5310             : 
+    5311           4 :   parameter_mix_D[ILE].push_back(4288.585540119189);
+    5312           4 :   parameter_mix_D[ILE].push_back(-19.937215352880365);
+    5313           4 :   parameter_mix_D[ILE].push_back(-8324.540144463375);
+    5314           4 :   parameter_mix_D[ILE].push_back(-2431.835931316717);
+    5315           4 :   parameter_mix_D[ILE].push_back(16079.9912986194);
+    5316           4 :   parameter_mix_D[ILE].push_back(-11637.693060394462);
+    5317           4 :   parameter_mix_D[ILE].push_back(2600.8258068480495);
+    5318             : 
+    5319           4 :   parameter_mix_D[LEU].push_back(4288.585540119186);
+    5320           4 :   parameter_mix_D[LEU].push_back(-21.50343599461759);
+    5321           4 :   parameter_mix_D[LEU].push_back(-8479.703435720274);
+    5322           4 :   parameter_mix_D[LEU].push_back(-2647.8693829269596);
+    5323           4 :   parameter_mix_D[LEU].push_back(17297.18115838578);
+    5324           4 :   parameter_mix_D[LEU].push_back(-12826.972408323161);
+    5325           4 :   parameter_mix_D[LEU].push_back(2953.1262521615645);
+    5326             : 
+    5327           4 :   parameter_mix_D[MET].push_back(3561.6276801191552);
+    5328           4 :   parameter_mix_D[MET].push_back(-22.19323392975885);
+    5329           4 :   parameter_mix_D[MET].push_back(-8348.33907053846);
+    5330           4 :   parameter_mix_D[MET].push_back(-3323.053272414289);
+    5331           4 :   parameter_mix_D[MET].push_back(23153.238909304255);
+    5332           4 :   parameter_mix_D[MET].push_back(-20091.960440908682);
+    5333           4 :   parameter_mix_D[MET].push_back(5518.759669687693);
+    5334             : 
+    5335           4 :   parameter_mix_D[ASN].push_back(2326.5396001192003);
+    5336           4 :   parameter_mix_D[ASN].push_back(-8.634908921289112);
+    5337           4 :   parameter_mix_D[ASN].push_back(-4057.4552636749636);
+    5338           4 :   parameter_mix_D[ASN].push_back(-1032.743130124821);
+    5339           4 :   parameter_mix_D[ASN].push_back(6957.141592429445);
+    5340           4 :   parameter_mix_D[ASN].push_back(-4808.265318722317);
+    5341           4 :   parameter_mix_D[ASN].push_back(1016.3944815533755);
+    5342             : 
+    5343           4 :   parameter_mix_D[PRO].push_back(2471.1663601191985);
+    5344           4 :   parameter_mix_D[PRO].push_back(-6.360795284260088);
+    5345           4 :   parameter_mix_D[PRO].push_back(-3825.4533158429153);
+    5346           4 :   parameter_mix_D[PRO].push_back(-728.7164844824666);
+    5347           4 :   parameter_mix_D[PRO].push_back(5195.036303827973);
+    5348           4 :   parameter_mix_D[PRO].push_back(-3183.733716480742);
+    5349           4 :   parameter_mix_D[PRO].push_back(563.2376162754107);
+    5350             : 
+    5351           4 :   parameter_mix_D[GLN].push_back(3431.669280119236);
+    5352           4 :   parameter_mix_D[GLN].push_back(-19.412747205646166);
+    5353           4 :   parameter_mix_D[GLN].push_back(-7298.017973002134);
+    5354           4 :   parameter_mix_D[GLN].push_back(-2659.3014182337706);
+    5355           4 :   parameter_mix_D[GLN].push_back(17890.76595805173);
+    5356           4 :   parameter_mix_D[GLN].push_back(-14684.603067192957);
+    5357           4 :   parameter_mix_D[GLN].push_back(3814.338335151394);
+    5358             : 
+    5359           4 :   parameter_mix_D[SER].push_back(1423.885200119192);
+    5360           4 :   parameter_mix_D[SER].push_back(-2.586428606204385);
+    5361           4 :   parameter_mix_D[SER].push_back(-1966.7369507188134);
+    5362           4 :   parameter_mix_D[SER].push_back(-289.17277383434106);
+    5363           4 :   parameter_mix_D[SER].push_back(2209.478296043199);
+    5364           4 :   parameter_mix_D[SER].push_back(-1216.1521614944);
+    5365           4 :   parameter_mix_D[SER].push_back(177.0615931546754);
+    5366             : 
+    5367           4 :   parameter_mix_D[THR].push_back(2311.2364801191825);
+    5368           4 :   parameter_mix_D[THR].push_back(-6.258071321531929);
+    5369           4 :   parameter_mix_D[THR].push_back(-3656.295629081312);
+    5370           4 :   parameter_mix_D[THR].push_back(-716.4013890357804);
+    5371           4 :   parameter_mix_D[THR].push_back(5071.656317108832);
+    5372           4 :   parameter_mix_D[THR].push_back(-3125.8076789667816);
+    5373           4 :   parameter_mix_D[THR].push_back(555.9775741081131);
+    5374             : 
+    5375           4 :   parameter_mix_D[VAL].push_back(3041.128320119224);
+    5376           4 :   parameter_mix_D[VAL].push_back(-9.314034190716423);
+    5377           4 :   parameter_mix_D[VAL].push_back(-5075.684780220629);
+    5378           4 :   parameter_mix_D[VAL].push_back(-1070.7083380665008);
+    5379           4 :   parameter_mix_D[VAL].push_back(7455.654515006894);
+    5380           4 :   parameter_mix_D[VAL].push_back(-4701.19187164774);
+    5381           4 :   parameter_mix_D[VAL].push_back(863.4906179388547);
+    5382             : 
+    5383           4 :   parameter_mix_D[ALA].push_back(1187.65300011922);
+    5384           4 :   parameter_mix_D[ALA].push_back(-1.7011187932116822);
+    5385           4 :   parameter_mix_D[ALA].push_back(-1521.0113615359212);
+    5386           4 :   parameter_mix_D[ALA].push_back(-187.93745840575576);
+    5387           4 :   parameter_mix_D[ALA].push_back(1514.6745873304449);
+    5388           4 :   parameter_mix_D[ALA].push_back(-775.3890045113897);
+    5389           4 :   parameter_mix_D[ALA].push_back(96.41428177656567);
+    5390             : 
+    5391           4 :   parameter_mix_D[GLY].push_back(581.6349001192067);
+    5392           4 :   parameter_mix_D[GLY].push_back(-0.5877833598361395);
+    5393           4 :   parameter_mix_D[GLY].push_back(-640.0421286186524);
+    5394           4 :   parameter_mix_D[GLY].push_back(-64.58515074152534);
+    5395           4 :   parameter_mix_D[GLY].push_back(551.9509853583185);
+    5396           4 :   parameter_mix_D[GLY].push_back(-264.1522021146006);
+    5397           4 :   parameter_mix_D[GLY].push_back(28.36986478439301);
+    5398             : 
+    5399           4 :   parameter_mix_D[HIS].push_back(3648.812220119277);
+    5400           4 :   parameter_mix_D[HIS].push_back(-22.703075403555548);
+    5401           4 :   parameter_mix_D[HIS].push_back(-8260.235189881098);
+    5402           4 :   parameter_mix_D[HIS].push_back(-3190.3176569039265);
+    5403           4 :   parameter_mix_D[HIS].push_back(21589.074332364213);
+    5404           4 :   parameter_mix_D[HIS].push_back(-18108.640157613925);
+    5405           4 :   parameter_mix_D[HIS].push_back(4801.237639634437);
+    5406             : 
+    5407           4 :   parameter_vac_D[TRP].push_back(270.43802511921314);
+    5408           4 :   parameter_vac_D[TRP].push_back(-2.196022464340772);
+    5409           4 :   parameter_vac_D[TRP].push_back(-780.9546710244318);
+    5410           4 :   parameter_vac_D[TRP].push_back(-371.1573508312626);
+    5411           4 :   parameter_vac_D[TRP].push_back(2668.7678731652445);
+    5412           4 :   parameter_vac_D[TRP].push_back(-2478.2920954223678);
+    5413           4 :   parameter_vac_D[TRP].push_back(722.3731624901676);
+    5414             : 
+    5415           4 :   parameter_vac_D[TYR].push_back(198.471744119211);
+    5416           4 :   parameter_vac_D[TYR].push_back(-1.236792846228289);
+    5417           4 :   parameter_vac_D[TYR].push_back(-508.0448711054671);
+    5418           4 :   parameter_vac_D[TYR].push_back(-210.55908129481216);
+    5419           4 :   parameter_vac_D[TYR].push_back(1558.3884734212413);
+    5420           4 :   parameter_vac_D[TYR].push_back(-1418.36319255665);
+    5421           4 :   parameter_vac_D[TYR].push_back(407.21567613893296);
+    5422             : 
+    5423           4 :   parameter_vac_D[PHE].push_back(182.46606411921402);
+    5424           4 :   parameter_vac_D[PHE].push_back(-1.2708008333861447);
+    5425           4 :   parameter_vac_D[PHE].push_back(-424.50905926426054);
+    5426           4 :   parameter_vac_D[PHE].push_back(-177.97207825696387);
+    5427           4 :   parameter_vac_D[PHE].push_back(1180.839971941918);
+    5428           4 :   parameter_vac_D[PHE].push_back(-1004.004765231886);
+    5429           4 :   parameter_vac_D[PHE].push_back(269.34384064610344);
+    5430             : 
+    5431           4 :   parameter_vac_D[HIP].push_back(161.95107611920753);
+    5432           4 :   parameter_vac_D[HIP].push_back(-0.9661246983835707);
+    5433           4 :   parameter_vac_D[HIP].push_back(-332.04673226423995);
+    5434           4 :   parameter_vac_D[HIP].push_back(-125.41755194926544);
+    5435           4 :   parameter_vac_D[HIP].push_back(808.705672166199);
+    5436           4 :   parameter_vac_D[HIP].push_back(-648.8340711218191);
+    5437           4 :   parameter_vac_D[HIP].push_back(163.71251277400307);
+    5438             : 
+    5439           4 :   parameter_vac_D[ARG].push_back(289.0340011192071);
+    5440           4 :   parameter_vac_D[ARG].push_back(-1.4195753436279361);
+    5441           4 :   parameter_vac_D[ARG].push_back(-836.3864005546434);
+    5442           4 :   parameter_vac_D[ARG].push_back(-346.7081039129904);
+    5443           4 :   parameter_vac_D[ARG].push_back(2922.003491580559);
+    5444           4 :   parameter_vac_D[ARG].push_back(-2864.816533173085);
+    5445           4 :   parameter_vac_D[ARG].push_back(877.9525045072293);
+    5446             : 
+    5447           4 :   parameter_vac_D[LYS].push_back(228.64464111920753);
+    5448           4 :   parameter_vac_D[LYS].push_back(-1.686580749083617);
+    5449           4 :   parameter_vac_D[LYS].push_back(-544.8870548339771);
+    5450           4 :   parameter_vac_D[LYS].push_back(-252.11087773186324);
+    5451           4 :   parameter_vac_D[LYS].push_back(1693.784850493428);
+    5452           4 :   parameter_vac_D[LYS].push_back(-1514.2375008160348);
+    5453           4 :   parameter_vac_D[LYS].push_back(427.0713155512121);
+    5454             : 
+    5455           4 :   parameter_vac_D[CYS].push_back(50.836900116324315);
+    5456           4 :   parameter_vac_D[CYS].push_back(-0.040204572899665315);
+    5457           4 :   parameter_vac_D[CYS].push_back(-55.592868149339424);
+    5458           4 :   parameter_vac_D[CYS].push_back(-4.341359624977117);
+    5459           4 :   parameter_vac_D[CYS].push_back(41.55290573185214);
+    5460           4 :   parameter_vac_D[CYS].push_back(-17.248208429078456);
+    5461           4 :   parameter_vac_D[CYS].push_back(1.0736187172140528);
+    5462             : 
+    5463           4 :   parameter_vac_D[ASP].push_back(64.12806411920792);
+    5464           4 :   parameter_vac_D[ASP].push_back(-0.08245818875074411);
+    5465           4 :   parameter_vac_D[ASP].push_back(-78.95500211069523);
+    5466           4 :   parameter_vac_D[ASP].push_back(-9.030157332821238);
+    5467           4 :   parameter_vac_D[ASP].push_back(74.72033164806712);
+    5468           4 :   parameter_vac_D[ASP].push_back(-36.71042192737952);
+    5469           4 :   parameter_vac_D[ASP].push_back(4.0989206257493676);
+    5470             : 
+    5471           4 :   parameter_vac_D[GLU].push_back(100.14004911920799);
+    5472           4 :   parameter_vac_D[GLU].push_back(-0.28685123265362006);
+    5473           4 :   parameter_vac_D[GLU].push_back(-152.44619103423773);
+    5474           4 :   parameter_vac_D[GLU].push_back(-32.99432901288321);
+    5475           4 :   parameter_vac_D[GLU].push_back(225.5853175183811);
+    5476           4 :   parameter_vac_D[GLU].push_back(-144.8489352831419);
+    5477           4 :   parameter_vac_D[GLU].push_back(27.49692658880534);
+    5478             : 
+    5479           4 :   parameter_vac_D[ILE].push_back(165.04540911921134);
+    5480           4 :   parameter_vac_D[ILE].push_back(-0.5061553029227089);
+    5481           4 :   parameter_vac_D[ILE].push_back(-275.1890586090823);
+    5482           4 :   parameter_vac_D[ILE].push_back(-57.288063177375356);
+    5483           4 :   parameter_vac_D[ILE].push_back(398.9780357099449);
+    5484           4 :   parameter_vac_D[ILE].push_back(-245.42678814428692);
+    5485           4 :   parameter_vac_D[ILE].push_back(42.72941025472001);
+    5486             : 
+    5487           4 :   parameter_vac_D[LEU].push_back(165.04540911921134);
+    5488           4 :   parameter_vac_D[LEU].push_back(-0.580034983510499);
+    5489           4 :   parameter_vac_D[LEU].push_back(-281.30910057877514);
+    5490           4 :   parameter_vac_D[LEU].push_back(-66.19427345166183);
+    5491           4 :   parameter_vac_D[LEU].push_back(445.19214155995115);
+    5492           4 :   parameter_vac_D[LEU].push_back(-287.0653610399624);
+    5493           4 :   parameter_vac_D[LEU].push_back(53.86626261066706);
+    5494             : 
+    5495           4 :   parameter_vac_D[MET].push_back(123.83238411920684);
+    5496           4 :   parameter_vac_D[MET].push_back(-0.7698672022751385);
+    5497           4 :   parameter_vac_D[MET].push_back(-251.2481622173618);
+    5498           4 :   parameter_vac_D[MET].push_back(-100.67742019193848);
+    5499           4 :   parameter_vac_D[MET].push_back(641.1563254731632);
+    5500           4 :   parameter_vac_D[MET].push_back(-524.8742634212379);
+    5501           4 :   parameter_vac_D[MET].push_back(135.36487813767542);
+    5502             : 
+    5503           4 :   parameter_vac_D[ASN].push_back(94.12880411921148);
+    5504           4 :   parameter_vac_D[ASN].push_back(-0.22986194121078912);
+    5505           4 :   parameter_vac_D[ASN].push_back(-138.78769705028003);
+    5506           4 :   parameter_vac_D[ASN].push_back(-25.896846049402594);
+    5507           4 :   parameter_vac_D[ASN].push_back(184.55609781654326);
+    5508           4 :   parameter_vac_D[ASN].push_back(-110.14043851975404);
+    5509           4 :   parameter_vac_D[ASN].push_back(18.388834098004153);
+    5510             : 
+    5511           4 :   parameter_vac_D[PRO].push_back(90.51619611920745);
+    5512           4 :   parameter_vac_D[PRO].push_back(-0.0977238494110807);
+    5513           4 :   parameter_vac_D[PRO].push_back(-109.43531311067846);
+    5514           4 :   parameter_vac_D[PRO].push_back(-10.592981104983805);
+    5515           4 :   parameter_vac_D[PRO].push_back(93.64863466237733);
+    5516           4 :   parameter_vac_D[PRO].push_back(-42.348197720920865);
+    5517           4 :   parameter_vac_D[PRO].push_back(3.5854078482704574);
+    5518             : 
+    5519           4 :   parameter_vac_D[GLN].push_back(136.91340111920806);
+    5520           4 :   parameter_vac_D[GLN].push_back(-0.7259026842220699);
+    5521           4 :   parameter_vac_D[GLN].push_back(-257.0347011897067);
+    5522           4 :   parameter_vac_D[GLN].push_back(-89.99600255417684);
+    5523           4 :   parameter_vac_D[GLN].push_back(570.3890595917421);
+    5524           4 :   parameter_vac_D[GLN].push_back(-438.8977029769549);
+    5525           4 :   parameter_vac_D[GLN].push_back(105.48846039376491);
+    5526             : 
+    5527           4 :   parameter_vac_D[SER].push_back(55.20490011583253);
+    5528           4 :   parameter_vac_D[SER].push_back(-0.038078030710377984);
+    5529           4 :   parameter_vac_D[SER].push_back(-58.79085960838952);
+    5530           4 :   parameter_vac_D[SER].push_back(-4.067364063406562);
+    5531           4 :   parameter_vac_D[SER].push_back(41.319899403658475);
+    5532           4 :   parameter_vac_D[SER].push_back(-15.865682241288962);
+    5533           4 :   parameter_vac_D[SER].push_back(0.5028409006168431);
+    5534             : 
+    5535           4 :   parameter_vac_D[THR].push_back(88.90604111920842);
+    5536           4 :   parameter_vac_D[THR].push_back(-0.11566717587697625);
+    5537           4 :   parameter_vac_D[THR].push_back(-114.4541243837681);
+    5538           4 :   parameter_vac_D[THR].push_back(-12.541537413808342);
+    5539           4 :   parameter_vac_D[THR].push_back(106.4974738790947);
+    5540           4 :   parameter_vac_D[THR].push_back(-50.15009912825225);
+    5541           4 :   parameter_vac_D[THR].push_back(4.719349514074467);
+    5542             : 
+    5543           4 :   parameter_vac_D[VAL].push_back(117.67910411920792);
+    5544           4 :   parameter_vac_D[VAL].push_back(-0.18187311248567883);
+    5545           4 :   parameter_vac_D[VAL].push_back(-162.8697844894754);
+    5546           4 :   parameter_vac_D[VAL].push_back(-19.769248288711825);
+    5547           4 :   parameter_vac_D[VAL].push_back(162.59270939168965);
+    5548           4 :   parameter_vac_D[VAL].push_back(-79.37261506441627);
+    5549           4 :   parameter_vac_D[VAL].push_back(8.230771959393175);
+    5550             : 
+    5551           4 :   parameter_vac_D[ALA].push_back(46.92250011448002);
+    5552           4 :   parameter_vac_D[ALA].push_back(-0.020339064649444412);
+    5553           4 :   parameter_vac_D[ALA].push_back(-44.41584945233503);
+    5554           4 :   parameter_vac_D[ALA].push_back(-2.1483754537886113);
+    5555           4 :   parameter_vac_D[ALA].push_back(25.713667829058785);
+    5556           4 :   parameter_vac_D[ALA].push_back(-8.222782061575268);
+    5557           4 :   parameter_vac_D[ALA].push_back(-0.2521732728817875);
+    5558             : 
+    5559           4 :   parameter_vac_D[GLY].push_back(23.532201119209795);
+    5560           4 :   parameter_vac_D[GLY].push_back(-0.00628609590047614);
+    5561           4 :   parameter_vac_D[GLY].push_back(-17.28421910139733);
+    5562           4 :   parameter_vac_D[GLY].push_back(-0.6641226821159686);
+    5563           4 :   parameter_vac_D[GLY].push_back(8.536119110048007);
+    5564           4 :   parameter_vac_D[GLY].push_back(-2.5438638688361466);
+    5565           4 :   parameter_vac_D[GLY].push_back(-0.11165675928832643);
+    5566             : 
+    5567           4 :   parameter_vac_D[HIS].push_back(145.41948111920982);
+    5568           4 :   parameter_vac_D[HIS].push_back(-0.8548328183368781);
+    5569           4 :   parameter_vac_D[HIS].push_back(-290.8653238004162);
+    5570           4 :   parameter_vac_D[HIS].push_back(-107.85375269366395);
+    5571           4 :   parameter_vac_D[HIS].push_back(685.7025818759361);
+    5572           4 :   parameter_vac_D[HIS].push_back(-538.2592043545858);
+    5573           4 :   parameter_vac_D[HIS].push_back(132.17357375729733);
+    5574             : 
+    5575             :   // NUCLEIC ACIDS
+    5576             : 
+    5577           4 :   parameter_mix_D[BB_PO2].push_back(80.12660011920252);
+    5578           4 :   parameter_mix_D[BB_PO2].push_back(-0.02788855519820236);
+    5579           4 :   parameter_mix_D[BB_PO2].push_back(-60.53219491822279);
+    5580           4 :   parameter_mix_D[BB_PO2].push_back(-2.9768829034096806);
+    5581           4 :   parameter_mix_D[BB_PO2].push_back(33.30645116638123);
+    5582           4 :   parameter_mix_D[BB_PO2].push_back(-11.601573219761375);
+    5583           4 :   parameter_mix_D[BB_PO2].push_back(0.12551046492022438);
+    5584             : 
+    5585           4 :   parameter_mix_D[BB_DNA].push_back(2835.3195201193003);
+    5586           4 :   parameter_mix_D[BB_DNA].push_back(-7.954301723608173);
+    5587           4 :   parameter_mix_D[BB_DNA].push_back(-4509.325563460958);
+    5588           4 :   parameter_mix_D[BB_DNA].push_back(-909.1870692311344);
+    5589           4 :   parameter_mix_D[BB_DNA].push_back(6375.156903893768);
+    5590           4 :   parameter_mix_D[BB_DNA].push_back(-3956.4787847570715);
+    5591           4 :   parameter_mix_D[BB_DNA].push_back(708.9872879613656);
+    5592             : 
+    5593           4 :   parameter_mix_D[BB_DNA_5].push_back(3136.73358011921);
+    5594           4 :   parameter_mix_D[BB_DNA_5].push_back(-10.023435855160427);
+    5595           4 :   parameter_mix_D[BB_DNA_5].push_back(-5208.921666368173);
+    5596           4 :   parameter_mix_D[BB_DNA_5].push_back(-1160.4403539440214);
+    5597           4 :   parameter_mix_D[BB_DNA_5].push_back(7962.598421448727);
+    5598           4 :   parameter_mix_D[BB_DNA_5].push_back(-5149.059857691847);
+    5599           4 :   parameter_mix_D[BB_DNA_5].push_back(984.5217027570121);
+    5600             : 
+    5601           4 :   parameter_mix_D[BB_DNA_3].push_back(3136.73358011921);
+    5602           4 :   parameter_mix_D[BB_DNA_3].push_back(-9.618834865806274);
+    5603           4 :   parameter_mix_D[BB_DNA_3].push_back(-5164.249220443828);
+    5604           4 :   parameter_mix_D[BB_DNA_3].push_back(-1103.2721475326382);
+    5605           4 :   parameter_mix_D[BB_DNA_3].push_back(7633.46089052312);
+    5606           4 :   parameter_mix_D[BB_DNA_3].push_back(-4826.171688395644);
+    5607           4 :   parameter_mix_D[BB_DNA_3].push_back(888.1820863683546);
+    5608             : 
+    5609           4 :   parameter_mix_D[BB_RNA].push_back(3192.5955601188807);
+    5610           4 :   parameter_mix_D[BB_RNA].push_back(-11.475781582628308);
+    5611           4 :   parameter_mix_D[BB_RNA].push_back(-5486.264576931735);
+    5612           4 :   parameter_mix_D[BB_RNA].push_back(-1344.2878288415961);
+    5613           4 :   parameter_mix_D[BB_RNA].push_back(9035.26109892441);
+    5614           4 :   parameter_mix_D[BB_RNA].push_back(-6068.471909763036);
+    5615           4 :   parameter_mix_D[BB_RNA].push_back(1226.3696076463866);
+    5616             : 
+    5617           4 :   parameter_mix_D[BB_RNA_5].push_back(3512.1630401192215);
+    5618           4 :   parameter_mix_D[BB_RNA_5].push_back(-14.191020069433975);
+    5619           4 :   parameter_mix_D[BB_RNA_5].push_back(-6293.687102187508);
+    5620           4 :   parameter_mix_D[BB_RNA_5].push_back(-1689.3688494490984);
+    5621           4 :   parameter_mix_D[BB_RNA_5].push_back(11193.448566821942);
+    5622           4 :   parameter_mix_D[BB_RNA_5].push_back(-7806.9064399949375);
+    5623           4 :   parameter_mix_D[BB_RNA_5].push_back(1662.4594983069844);
+    5624             : 
+    5625           4 :   parameter_mix_D[BB_RNA_3].push_back(3512.1630401192215);
+    5626           4 :   parameter_mix_D[BB_RNA_3].push_back(-12.978118135595812);
+    5627           4 :   parameter_mix_D[BB_RNA_3].push_back(-6149.290195451877);
+    5628           4 :   parameter_mix_D[BB_RNA_3].push_back(-1515.8309761505627);
+    5629           4 :   parameter_mix_D[BB_RNA_3].push_back(10176.605450440278);
+    5630           4 :   parameter_mix_D[BB_RNA_3].push_back(-6813.250569884159);
+    5631           4 :   parameter_mix_D[BB_RNA_3].push_back(1366.823518955858);
+    5632             : 
+    5633           4 :   parameter_mix_D[BASE_A].push_back(2464.736500119229);
+    5634           4 :   parameter_mix_D[BASE_A].push_back(-12.127452038444783);
+    5635           4 :   parameter_mix_D[BASE_A].push_back(-4710.661256689607);
+    5636           4 :   parameter_mix_D[BASE_A].push_back(-1462.6964141954452);
+    5637           4 :   parameter_mix_D[BASE_A].push_back(9451.725575888277);
+    5638           4 :   parameter_mix_D[BASE_A].push_back(-6883.018479948857);
+    5639           4 :   parameter_mix_D[BASE_A].push_back(1540.1526599737797);
+    5640             : 
+    5641           4 :   parameter_mix_D[BASE_C].push_back(1797.2697601191685);
+    5642           4 :   parameter_mix_D[BASE_C].push_back(-5.963855532295215);
+    5643           4 :   parameter_mix_D[BASE_C].push_back(-2955.077717756034);
+    5644           4 :   parameter_mix_D[BASE_C].push_back(-689.4543508746372);
+    5645           4 :   parameter_mix_D[BASE_C].push_back(4665.914740532565);
+    5646           4 :   parameter_mix_D[BASE_C].push_back(-3051.4605913706982);
+    5647           4 :   parameter_mix_D[BASE_C].push_back(590.2201952719585);
+    5648             : 
+    5649           4 :   parameter_mix_D[BASE_G].push_back(2804.271480119049);
+    5650           4 :   parameter_mix_D[BASE_G].push_back(-16.928072935469974);
+    5651           4 :   parameter_mix_D[BASE_G].push_back(-5989.82519987899);
+    5652           4 :   parameter_mix_D[BASE_G].push_back(-2275.490326521775);
+    5653           4 :   parameter_mix_D[BASE_G].push_back(15007.832401865428);
+    5654           4 :   parameter_mix_D[BASE_G].push_back(-12287.520690325606);
+    5655           4 :   parameter_mix_D[BASE_G].push_back(3172.98306575258);
+    5656             : 
+    5657           4 :   parameter_mix_D[BASE_T].push_back(2545.0860001192113);
+    5658           4 :   parameter_mix_D[BASE_T].push_back(-10.975141620541738);
+    5659           4 :   parameter_mix_D[BASE_T].push_back(-4636.058358764447);
+    5660           4 :   parameter_mix_D[BASE_T].push_back(-1340.3746388296138);
+    5661           4 :   parameter_mix_D[BASE_T].push_back(8850.604320505428);
+    5662           4 :   parameter_mix_D[BASE_T].push_back(-6421.852532013674);
+    5663           4 :   parameter_mix_D[BASE_T].push_back(1443.371517335904);
+    5664             : 
+    5665           4 :   parameter_mix_D[BASE_U].push_back(1608.7389001192062);
+    5666           4 :   parameter_mix_D[BASE_U].push_back(-3.9816849036181434);
+    5667           4 :   parameter_mix_D[BASE_U].push_back(-2411.056432130769);
+    5668           4 :   parameter_mix_D[BASE_U].push_back(-451.8236361945487);
+    5669           4 :   parameter_mix_D[BASE_U].push_back(3220.4418252803644);
+    5670           4 :   parameter_mix_D[BASE_U].push_back(-1944.2515577994325);
+    5671           4 :   parameter_mix_D[BASE_U].push_back(332.9259542628691);
+    5672             : 
+    5673           4 :   parameter_vac_D[BB_PO2].push_back(2.7889001116093284);
+    5674           4 :   parameter_vac_D[BB_PO2].push_back(-0.00011178884266113128);
+    5675           4 :   parameter_vac_D[BB_PO2].push_back(-1.1702605818380654);
+    5676           4 :   parameter_vac_D[BB_PO2].push_back(-0.011278044036819927);
+    5677           4 :   parameter_vac_D[BB_PO2].push_back(0.3214006584089024);
+    5678           4 :   parameter_vac_D[BB_PO2].push_back(-0.04097165983591666);
+    5679           4 :   parameter_vac_D[BB_PO2].push_back(-0.017525098100539684);
+    5680             : 
+    5681           4 :   parameter_vac_D[BB_DNA].push_back(94.75075611920529);
+    5682           4 :   parameter_vac_D[BB_DNA].push_back(-0.13973533952241124);
+    5683           4 :   parameter_vac_D[BB_DNA].push_back(-123.45402430039046);
+    5684           4 :   parameter_vac_D[BB_DNA].push_back(-15.19494522082691);
+    5685           4 :   parameter_vac_D[BB_DNA].push_back(123.34749914811465);
+    5686           4 :   parameter_vac_D[BB_DNA].push_back(-61.038507985345504);
+    5687           4 :   parameter_vac_D[BB_DNA].push_back(6.601587478585944);
+    5688             : 
+    5689           4 :   parameter_vac_D[BB_DNA_5].push_back(108.18080111920679);
+    5690           4 :   parameter_vac_D[BB_DNA_5].push_back(-0.2055953690887981);
+    5691           4 :   parameter_vac_D[BB_DNA_5].push_back(-150.7924892157235);
+    5692           4 :   parameter_vac_D[BB_DNA_5].push_back(-22.700459516383198);
+    5693           4 :   parameter_vac_D[BB_DNA_5].push_back(172.2599851655527);
+    5694           4 :   parameter_vac_D[BB_DNA_5].push_back(-93.4983124807692);
+    5695           4 :   parameter_vac_D[BB_DNA_5].push_back(12.867661230942868);
+    5696             : 
+    5697           4 :   parameter_vac_D[BB_DNA_3].push_back(108.18080111920537);
+    5698           4 :   parameter_vac_D[BB_DNA_3].push_back(-0.18263717534168372);
+    5699           4 :   parameter_vac_D[BB_DNA_3].push_back(-148.5918817744255);
+    5700           4 :   parameter_vac_D[BB_DNA_3].push_back(-19.90799847398835);
+    5701           4 :   parameter_vac_D[BB_DNA_3].push_back(157.55184203379557);
+    5702           4 :   parameter_vac_D[BB_DNA_3].push_back(-80.28471270058103);
+    5703           4 :   parameter_vac_D[BB_DNA_3].push_back(9.313712500298278);
+    5704             : 
+    5705           4 :   parameter_vac_D[BB_RNA].push_back(106.37859611922117);
+    5706           4 :   parameter_vac_D[BB_RNA].push_back(-0.2380766148121975);
+    5707           4 :   parameter_vac_D[BB_RNA].push_back(-153.74131338570024);
+    5708           4 :   parameter_vac_D[BB_RNA].push_back(-26.415436217574932);
+    5709           4 :   parameter_vac_D[BB_RNA].push_back(191.90585451112776);
+    5710           4 :   parameter_vac_D[BB_RNA].push_back(-109.61737794316868);
+    5711           4 :   parameter_vac_D[BB_RNA].push_back(16.663804191332204);
+    5712             : 
+    5713           4 :   parameter_vac_D[BB_RNA_5].push_back(120.58236111920618);
+    5714           4 :   parameter_vac_D[BB_RNA_5].push_back(-0.340258533619014);
+    5715           4 :   parameter_vac_D[BB_RNA_5].push_back(-186.08333929996334);
+    5716           4 :   parameter_vac_D[BB_RNA_5].push_back(-38.493337147644795);
+    5717           4 :   parameter_vac_D[BB_RNA_5].push_back(266.2262415641144);
+    5718           4 :   parameter_vac_D[BB_RNA_5].push_back(-164.73088478359585);
+    5719           4 :   parameter_vac_D[BB_RNA_5].push_back(29.07014157680879);
+    5720             : 
+    5721           4 :   parameter_vac_D[BB_RNA_3].push_back(120.5823611192099);
+    5722           4 :   parameter_vac_D[BB_RNA_3].push_back(-0.274146129206928);
+    5723           4 :   parameter_vac_D[BB_RNA_3].push_back(-179.24499182395388);
+    5724           4 :   parameter_vac_D[BB_RNA_3].push_back(-30.315729372259426);
+    5725           4 :   parameter_vac_D[BB_RNA_3].push_back(222.2645581367648);
+    5726           4 :   parameter_vac_D[BB_RNA_3].push_back(-125.13581171514033);
+    5727           4 :   parameter_vac_D[BB_RNA_3].push_back(18.350308154920107);
+    5728             : 
+    5729           4 :   parameter_vac_D[BASE_A].push_back(114.34024911921);
+    5730           4 :   parameter_vac_D[BASE_A].push_back(-0.4136665918383359);
+    5731           4 :   parameter_vac_D[BASE_A].push_back(-192.33138384655922);
+    5732           4 :   parameter_vac_D[BASE_A].push_back(-46.74428306691412);
+    5733           4 :   parameter_vac_D[BASE_A].push_back(312.9511030981905);
+    5734           4 :   parameter_vac_D[BASE_A].push_back(-199.6349962647333);
+    5735           4 :   parameter_vac_D[BASE_A].push_back(36.15938693202153);
+    5736             : 
+    5737           4 :   parameter_vac_D[BASE_C].push_back(76.17798411921166);
+    5738           4 :   parameter_vac_D[BASE_C].push_back(-0.1444475142707445);
+    5739           4 :   parameter_vac_D[BASE_C].push_back(-102.66873668949485);
+    5740           4 :   parameter_vac_D[BASE_C].push_back(-15.813768367725821);
+    5741           4 :   parameter_vac_D[BASE_C].push_back(119.63436338715553);
+    5742           4 :   parameter_vac_D[BASE_C].push_back(-64.22251971660583);
+    5743           4 :   parameter_vac_D[BASE_C].push_back(8.351952332828862);
+    5744             : 
+    5745           4 :   parameter_vac_D[BASE_G].push_back(127.08052911921965);
+    5746           4 :   parameter_vac_D[BASE_G].push_back(-0.7137457014712297);
+    5747           4 :   parameter_vac_D[BASE_G].push_back(-239.67686838772786);
+    5748           4 :   parameter_vac_D[BASE_G].push_back(-88.53661981200943);
+    5749           4 :   parameter_vac_D[BASE_G].push_back(556.7254485453866);
+    5750           4 :   parameter_vac_D[BASE_G].push_back(-432.0234649577737);
+    5751           4 :   parameter_vac_D[BASE_G].push_back(104.407200463848);
+    5752             : 
+    5753           4 :   parameter_vac_D[BASE_T].push_back(94.09000011920868);
+    5754           4 :   parameter_vac_D[BASE_T].push_back(-0.27147149980458524);
+    5755           4 :   parameter_vac_D[BASE_T].push_back(-143.65649702254174);
+    5756           4 :   parameter_vac_D[BASE_T].push_back(-30.861235738371892);
+    5757           4 :   parameter_vac_D[BASE_T].push_back(212.3643014774958);
+    5758           4 :   parameter_vac_D[BASE_T].push_back(-133.06675501066275);
+    5759           4 :   parameter_vac_D[BASE_T].push_back(23.951588200687073);
+    5760             : 
+    5761           4 :   parameter_vac_D[BASE_U].push_back(59.30540111665979);
+    5762           4 :   parameter_vac_D[BASE_U].push_back(-0.06146929846591808);
+    5763           4 :   parameter_vac_D[BASE_U].push_back(-67.43680950211682);
+    5764           4 :   parameter_vac_D[BASE_U].push_back(-6.625289749170134);
+    5765           4 :   parameter_vac_D[BASE_U].push_back(58.37012229348065);
+    5766           4 :   parameter_vac_D[BASE_U].push_back(-26.23044613101723);
+    5767           4 :   parameter_vac_D[BASE_U].push_back(2.061238351422343);
+    5768             : 
+    5769       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    5770       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    5771       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    5772       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    5773       14294 :     if(Rname=="ALA") {
+    5774         732 :       atoi[residue_atom[i]]=ALA;
+    5775       13562 :     } else if(Rname=="ARG") {
+    5776         864 :       atoi[residue_atom[i]]=ARG;
+    5777       12698 :     } else if(Rname=="ASN") {
+    5778         720 :       atoi[residue_atom[i]]=ASN;
+    5779       11978 :     } else if(Rname=="ASP") {
+    5780         624 :       atoi[residue_atom[i]]=ASP;
+    5781       11354 :     } else if(Rname=="CYS") {
+    5782          48 :       atoi[residue_atom[i]]=CYS;
+    5783       11306 :     } else if(Rname=="GLN") {
+    5784        1064 :       atoi[residue_atom[i]]=GLN;
+    5785       10242 :     } else if(Rname=="GLU") {
+    5786         476 :       atoi[residue_atom[i]]=GLU;
+    5787        9766 :     } else if(Rname=="GLY") {
+    5788         648 :       atoi[residue_atom[i]]=GLY;
+    5789        9118 :     } else if(Rname=="HIS") {
+    5790           0 :       atoi[residue_atom[i]]=HIS;
+    5791        9118 :     } else if(Rname=="HID") {
+    5792           0 :       atoi[residue_atom[i]]=HIS;
+    5793        9118 :     } else if(Rname=="HIE") {
+    5794         144 :       atoi[residue_atom[i]]=HIS;
+    5795        8974 :     } else if(Rname=="HIP") {
+    5796           0 :       atoi[residue_atom[i]]=HIP;
+    5797             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    5798        8974 :     } else if(Rname=="HSD") {
+    5799           0 :       atoi[residue_atom[i]]=HIS;
+    5800        8974 :     } else if(Rname=="HSE") {
+    5801           0 :       atoi[residue_atom[i]]=HIS;
+    5802        8974 :     } else if(Rname=="HSP") {
+    5803           0 :       atoi[residue_atom[i]]=HIP;
+    5804        8974 :     } else if(Rname=="ILE") {
+    5805         864 :       atoi[residue_atom[i]]=ILE;
+    5806        8110 :     } else if(Rname=="LEU") {
+    5807        1520 :       atoi[residue_atom[i]]=LEU;
+    5808        6590 :     } else if(Rname=="LYS") {
+    5809        1040 :       atoi[residue_atom[i]]=LYS;
+    5810        5550 :     } else if(Rname=="MET") {
+    5811         608 :       atoi[residue_atom[i]]=MET;
+    5812        4942 :     } else if(Rname=="PHE") {
+    5813        1008 :       atoi[residue_atom[i]]=PHE;
+    5814        3934 :     } else if(Rname=="PRO") {
+    5815         748 :       atoi[residue_atom[i]]=PRO;
+    5816        3186 :     } else if(Rname=="SER") {
+    5817         528 :       atoi[residue_atom[i]]=SER;
+    5818        2658 :     } else if(Rname=="THR") {
+    5819         504 :       atoi[residue_atom[i]]=THR;
+    5820        2154 :     } else if(Rname=="TRP") {
+    5821           0 :       atoi[residue_atom[i]]=TRP;
+    5822        2154 :     } else if(Rname=="TYR") {
+    5823         528 :       atoi[residue_atom[i]]=TYR;
+    5824        1626 :     } else if(Rname=="VAL") {
+    5825        1088 :       atoi[residue_atom[i]]=VAL;
+    5826             :     }
+    5827             :     // NUCLEIC ACIDS
+    5828             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    5829             :     // RNA - G
+    5830         538 :     else if(Rname=="G") {
+    5831           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5832           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5833           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5834           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5835           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5836           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5837           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5838           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5839           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5840           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5841           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5842           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5843           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5844           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5845           0 :         atoi[residue_atom[i]]=BASE_G;
+    5846           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5847             :       // RNA - G3
+    5848         538 :     } else if(Rname=="G3") {
+    5849           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5850           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5851           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5852           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5853           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5854           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5855           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5856           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5857           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5858           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5859           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5860           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5861           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5862           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5863           0 :         atoi[residue_atom[i]]=BASE_G;
+    5864           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5865             :       // RNA - G5
+    5866         538 :     } else if(Rname=="G5") {
+    5867           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5868           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5869           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5870           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5871           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5872           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5873           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5874           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5875           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5876           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5877           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5878           0 :         atoi[residue_atom[i]]=BASE_G;
+    5879           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5880             :       // RNA - U
+    5881         538 :     } else if(Rname=="U") {
+    5882        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5883        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5884          42 :         atoi [residue_atom[i]]=BB_PO2;
+    5885        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5886        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5887         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5888         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5889         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5890         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5891         224 :         atoi[residue_atom[i]]=BB_RNA;
+    5892         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5893         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5894         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5895         154 :         atoi[residue_atom[i]]=BASE_U;
+    5896           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5897             :       // RNA - U3
+    5898         118 :     } else if(Rname=="U3") {
+    5899         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5900         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5901           6 :         atoi [residue_atom[i]]=BB_PO2;
+    5902         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5903         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5904         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5905         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5906          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5907          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5908          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5909          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5910          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5911          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5912          22 :         atoi[residue_atom[i]]=BASE_U;
+    5913           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5914             :       // RNA - U5
+    5915          56 :     } else if(Rname=="U5") {
+    5916         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5917         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5918         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5919         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5920          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5921          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5922          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5923          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5924          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5925          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5926          22 :         atoi[residue_atom[i]]=BASE_U;
+    5927           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5928             :       // RNA - A
+    5929           0 :     } else if(Rname=="A") {
+    5930           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5931           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5932           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5933           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5934           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5935           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5936           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5937           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5938           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5939           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5940           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5941           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5942           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5943           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5944           0 :         atoi[residue_atom[i]]=BASE_A;
+    5945           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5946             :       // RNA - A3
+    5947           0 :     } else if(Rname=="A3") {
+    5948           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5949           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5950           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5951           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5952           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5953           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5954           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5955           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5956           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5957           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5958           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5959           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5960           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5961           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5962           0 :         atoi[residue_atom[i]]=BASE_A;
+    5963           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5964             :       // RNA - A5
+    5965           0 :     } else if(Rname=="A5") {
+    5966           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5967           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5968           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5969           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5970           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5971           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5972           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5973           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5974           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5975           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5976           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5977           0 :         atoi[residue_atom[i]]=BASE_A;
+    5978           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5979             :       // RNA - C
+    5980           0 :     } else if(Rname=="C") {
+    5981           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5982           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5983           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5984           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5985           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5986           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5987           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5988           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5989           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5990           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5991           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5992           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5993           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5994           0 :         atoi[residue_atom[i]]=BASE_C;
+    5995           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5996             :       // RNA - C3
+    5997           0 :     } else if(Rname=="C3") {
+    5998           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5999           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6000           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6001           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6002           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6003           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6004           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6005           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6006           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6007           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6008           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6009           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6010           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6011           0 :         atoi[residue_atom[i]]=BASE_C;
+    6012           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6013             :       // RNA - C5
+    6014           0 :     } else if(Rname=="C5") {
+    6015           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6016           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6017           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6018           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6019           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6020           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6021           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6022           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6023           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6024           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6025           0 :         atoi[residue_atom[i]]=BASE_C;
+    6026           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6027             :       // DNA - G
+    6028           0 :     } else if(Rname=="DG") {
+    6029           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6030           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6031           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6032           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6033           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6034           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6035           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6036           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6037           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6038           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6039           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6040           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6041           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6042           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6043           0 :         atoi[residue_atom[i]]=BASE_G;
+    6044           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6045             :       // DNA - G3
+    6046           0 :     } else if(Rname=="DG3") {
+    6047           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6048           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6049           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6050           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6051           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6052           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6053           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6054           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6055             :                 Aname=="H3T" ) {
+    6056           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6057           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6058           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6059           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6060           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6061           0 :         atoi[residue_atom[i]]=BASE_G;
+    6062           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6063             :       // DNA - G5
+    6064           0 :     } else if(Rname=="DG5") {
+    6065           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6066           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6067           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6068           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6069           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6070             :           Aname=="H5T" ) {
+    6071           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6072           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6073           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6074           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6075           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6076           0 :         atoi[residue_atom[i]]=BASE_G;
+    6077           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6078             :       // DNA - T
+    6079           0 :     } else if(Rname=="DT") {
+    6080           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6081           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6082           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6083           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6084           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6085           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6086           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6087           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6088           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6089           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6090           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6091           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6092           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6093           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6094           0 :         atoi[residue_atom[i]]=BASE_T;
+    6095           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6096             :       // DNA - T3
+    6097           0 :     } else if(Rname=="DT3") {
+    6098           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6099           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6100           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6101           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6102           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6103           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6104           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6105           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6106             :                 Aname=="H3T" ) {
+    6107           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6108           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6109           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6110           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6111           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6112           0 :         atoi[residue_atom[i]]=BASE_T;
+    6113           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6114             :       // DNA - T5
+    6115           0 :     } else if(Rname=="DT5") {
+    6116           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6117           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6118           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6119           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6120           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6121             :           Aname=="H5T" ) {
+    6122           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6123           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6124           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6125           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6126           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6127           0 :         atoi[residue_atom[i]]=BASE_T;
+    6128           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6129             :       // DNA - A
+    6130           0 :     } else if(Rname=="DA") {
+    6131           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6132           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6133           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6134           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6135           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6136           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6137           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6138           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6139           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6140           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6141           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6142           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6143           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6144           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6145           0 :         atoi[residue_atom[i]]=BASE_A;
+    6146           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6147             :       // DNA - A3
+    6148           0 :     } else if(Rname=="DA3") {
+    6149           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6150           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6151           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6152           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6153           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6154           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6155           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6156           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6157             :                 Aname=="H3T" ) {
+    6158           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6159           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6160           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6161           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6162           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6163           0 :         atoi[residue_atom[i]]=BASE_A;
+    6164           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6165             :       // DNA - A5
+    6166           0 :     } else if(Rname=="DA5") {
+    6167           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6168           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6169           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6170           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6171           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6172             :           Aname=="H5T" ) {
+    6173           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6174           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6175           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6176           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6177           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6178           0 :         atoi[residue_atom[i]]=BASE_A;
+    6179           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6180             :       // DNA - C
+    6181           0 :     } else if(Rname=="DC") {
+    6182           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6183           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6184           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6185           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6186           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6187           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6188           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6189           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6190           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6191           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6192           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6193           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6194           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6195           0 :         atoi[residue_atom[i]]=BASE_C;
+    6196           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6197             :       // DNA - C3
+    6198           0 :     } else if(Rname=="DC3") {
+    6199           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6200           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6201           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6202           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6203           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6204           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6205           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6206           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6207             :                 Aname=="H3T" ) {
+    6208           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6209           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6210           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6211           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6212           0 :         atoi[residue_atom[i]]=BASE_C;
+    6213           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6214             :       // DNA - C5
+    6215           0 :     } else if(Rname=="DC5") {
+    6216           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6217           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6218           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6219           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6220           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6221             :           Aname=="H5T" ) {
+    6222           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6223           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6224           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6225           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6226           0 :         atoi[residue_atom[i]]=BASE_C;
+    6227           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6228           0 :     } else error("Residue not known: "+Rname);
+    6229             :   }
+    6230           4 : }
+    6231             : 
+    6232           4 : double SAXS::calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho)
+    6233             : {
+    6234             :   std::map<std::string, unsigned> AA_map;
+    6235           4 :   AA_map["H"] = H;
+    6236           4 :   AA_map["C"] = C;
+    6237           4 :   AA_map["N"] = N;
+    6238           4 :   AA_map["O"] = O;
+    6239           4 :   AA_map["P"] = P;
+    6240           4 :   AA_map["S"] = S;
+    6241             : 
+    6242             :   std::vector<std::vector<double> > param_a;
+    6243             :   std::vector<std::vector<double> > param_b;
+    6244             :   std::vector<double> param_c;
+    6245             :   std::vector<double> param_v;
+    6246             : 
+    6247           4 :   param_a.resize(NTT, std::vector<double>(5));
+    6248           4 :   param_b.resize(NTT, std::vector<double>(5));
+    6249           4 :   param_c.resize(NTT);
+    6250           4 :   param_v.resize(NTT);
+    6251             : 
+    6252           4 :   param_a[H][0] = 0.493002; param_b[H][0] = 10.5109; param_c[H] = 0.003038;
+    6253           4 :   param_a[H][1] = 0.322912; param_b[H][1] = 26.1257; param_v[H] = 5.15;
+    6254           4 :   param_a[H][2] = 0.140191; param_b[H][2] = 3.14236;
+    6255           4 :   param_a[H][3] = 0.040810; param_b[H][3] = 57.7997;
+    6256           4 :   param_a[H][4] = 0.0;      param_b[H][4] = 1.0;
+    6257             : 
+    6258           4 :   param_a[C][0] = 2.31000; param_b[C][0] = 20.8439; param_c[C] = 0.215600;
+    6259           4 :   param_a[C][1] = 1.02000; param_b[C][1] = 10.2075; param_v[C] = 16.44;
+    6260           4 :   param_a[C][2] = 1.58860; param_b[C][2] = 0.56870;
+    6261           4 :   param_a[C][3] = 0.86500; param_b[C][3] = 51.6512;
+    6262           4 :   param_a[C][4] = 0.0;     param_b[C][4] = 1.0;
+    6263             : 
+    6264           4 :   param_a[N][0] = 12.2126; param_b[N][0] = 0.00570; param_c[N] = -11.529;
+    6265           4 :   param_a[N][1] = 3.13220; param_b[N][1] = 9.89330; param_v[N] = 2.49;
+    6266           4 :   param_a[N][2] = 2.01250; param_b[N][2] = 28.9975;
+    6267           4 :   param_a[N][3] = 1.16630; param_b[N][3] = 0.58260;
+    6268           4 :   param_a[N][4] = 0.0;     param_b[N][4] = 1.0;
+    6269             : 
+    6270           4 :   param_a[O][0] = 3.04850; param_b[O][0] = 13.2771; param_c[O] = 0.250800 ;
+    6271           4 :   param_a[O][1] = 2.28680; param_b[O][1] = 5.70110; param_v[O] = 9.13;
+    6272           4 :   param_a[O][2] = 1.54630; param_b[O][2] = 0.32390;
+    6273           4 :   param_a[O][3] = 0.86700; param_b[O][3] = 32.9089;
+    6274           4 :   param_a[O][4] = 0.0;     param_b[O][4] = 1.0;
+    6275             : 
+    6276           4 :   param_a[P][0] = 6.43450; param_b[P][0] = 1.90670; param_c[P] = 1.11490;
+    6277           4 :   param_a[P][1] = 4.17910; param_b[P][1] = 27.1570; param_v[P] = 5.73;
+    6278           4 :   param_a[P][2] = 1.78000; param_b[P][2] = 0.52600;
+    6279           4 :   param_a[P][3] = 1.49080; param_b[P][3] = 68.1645;
+    6280           4 :   param_a[P][4] = 0.0;     param_b[P][4] = 1.0;
+    6281             : 
+    6282           4 :   param_a[S][0] = 6.90530; param_b[S][0] = 1.46790; param_c[S] = 0.866900;
+    6283           4 :   param_a[S][1] = 5.20340; param_b[S][1] = 22.2151; param_v[S] = 19.86;
+    6284           4 :   param_a[S][2] = 1.43790; param_b[S][2] = 0.25360;
+    6285           4 :   param_a[S][3] = 1.58630; param_b[S][3] = 56.1720;
+    6286           4 :   param_a[S][4] = 0.0;     param_b[S][4] = 1.0;
+    6287             : 
+    6288           4 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6289             : 
+    6290             :   double Iq0=0.;
+    6291           4 :   if( moldat ) {
+    6292             :     // cycle over the atom types
+    6293          28 :     for(unsigned i=0; i<NTT; ++i) {
+    6294          24 :       const double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6295             :       // cycle over q
+    6296         240 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6297         216 :         const double q = q_list[k];
+    6298         216 :         const double s = q / (4. * M_PI);
+    6299         216 :         FF_tmp[k][i] = param_c[i];
+    6300             :         // SUM [a_i * EXP( - b_i * (q/4pi)^2 )] Waasmaier and Kirfel (1995)
+    6301        1080 :         for(unsigned j=0; j<4; ++j) {
+    6302         864 :           FF_tmp[k][i] += param_a[i][j]*std::exp(-param_b[i][j]*s*s);
+    6303             :         }
+    6304             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6305         216 :         FF_tmp[k][i] -= rho*param_v[i]*std::exp(-volr*q*q);
+    6306             :       }
+    6307             :     }
+    6308             :     // cycle over the atoms to assign the atom type and calculate I0
+    6309       14298 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6310             :       // get atom name
+    6311       14294 :       std::string name = moldat->getAtomName(atoms[i]);
+    6312             :       char type;
+    6313             :       // get atom type
+    6314       14294 :       char first = name.at(0);
+    6315             :       // GOLDEN RULE: type is first letter, if not a number
+    6316       14294 :       if (!isdigit(first)) {
+    6317             :         type = first;
+    6318             :         // otherwise is the second
+    6319             :       } else {
+    6320           0 :         type = name.at(1);
+    6321             :       }
+    6322       14294 :       std::string type_s = std::string(1,type);
+    6323       14294 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6324       14294 :         const unsigned index=AA_map[type_s];
+    6325       14294 :         atoi[i] = AA_map[type_s];
+    6326       71470 :         for(unsigned j=0; j<4; ++j) Iq0 += param_a[index][j];
+    6327       14294 :         Iq0 = Iq0 -rho*param_v[index] + param_c[index];
+    6328             :       } else {
+    6329           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6330             :       }
+    6331             :     }
+    6332             :   } else {
+    6333           0 :     error("MOLINFO DATA not found\n");
+    6334             :   }
+    6335             : 
+    6336           4 :   return Iq0;
+    6337           4 : }
+    6338             : 
+    6339           2 : double SAXS::calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc)
+    6340             : {
+    6341             :   std::map<std::string, unsigned> AA_map;
+    6342           2 :   AA_map["H"] = H;
+    6343           2 :   AA_map["C"] = C;
+    6344           2 :   AA_map["N"] = N;
+    6345           2 :   AA_map["O"] = O;
+    6346           2 :   AA_map["P"] = P;
+    6347           2 :   AA_map["S"] = S;
+    6348             : 
+    6349             :   std::vector<double> param_b;
+    6350             :   std::vector<double> param_v;
+    6351             : 
+    6352           2 :   param_b.resize(NTT);
+    6353           2 :   param_v.resize(NTT);
+    6354             : 
+    6355           2 :   param_b[H] = -0.374; param_v[H] = 5.15;
+    6356             :   // param_b[D] = 0.667;
+    6357           2 :   param_b[C] =  0.665;  param_v[C] = 16.44;
+    6358           2 :   param_b[N] =  0.94;   param_v[N] = 2.49;
+    6359           2 :   param_b[O] =  0.580;  param_v[O] = 9.13;
+    6360           2 :   param_b[P] =  0.51;   param_v[P] = 5.73;
+    6361           2 :   param_b[S] =  0.28;   param_v[S] = 19.86;
+    6362             : 
+    6363           2 :   double solv_sc_length = 0.1*(param_b[O] + 2.*((1. - deuter_conc) * param_b[H] + deuter_conc * 0.667)); // per water electron (10 electrons)
+    6364             : 
+    6365           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6366             : 
+    6367             :   double Iq0=0.;
+    6368           2 :   if( moldat ) {
+    6369             :     // cycle over the atom types
+    6370          14 :     for(unsigned i=0; i<NTT; ++i) {
+    6371          12 :       double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6372             :       // cycle over q
+    6373         120 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6374         108 :         const double q = q_list[k];
+    6375         108 :         FF_tmp[k][i] = param_b[i];
+    6376             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6377         108 :         FF_tmp[k][i] -= solv_sc_length*rho*param_v[i]*std::exp(-volr*q*q);
+    6378             :       }
+    6379             :     }
+    6380             :     // cycle over the atoms to assign the atom type and calculate I0
+    6381        6880 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6382             :       // get atom name
+    6383        6878 :       std::string name = moldat->getAtomName(atoms[i]);
+    6384             :       char type;
+    6385             :       // get atom type
+    6386        6878 :       char first = name.at(0);
+    6387             :       // GOLDEN RULE: type is first letter, if not a number
+    6388        6878 :       if (!isdigit(first)) {
+    6389             :         type = first;
+    6390             :         // otherwise is the second
+    6391             :       } else {
+    6392           0 :         type = name.at(1);
+    6393             :       }
+    6394        6878 :       std::string type_s = std::string(1,type);
+    6395        6878 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6396        6878 :         const unsigned index=AA_map[type_s];
+    6397        6878 :         atoi[i] = AA_map[type_s];
+    6398        6878 :         Iq0 += param_b[index]-solv_sc_length*rho*param_v[index];
+    6399             :       } else {
+    6400           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6401             :       }
+    6402             :     }
+    6403             :   } else {
+    6404           0 :     error("MOLINFO DATA not found\n");
+    6405             :   }
+    6406             : 
+    6407           2 :   return Iq0;
+    6408             : }
+    6409             : 
+    6410          10 : std::map<std::string, std::vector<double> > SAXS::setupLCPOparam() {
+    6411             :   std::map<std::string, std::vector<double> > lcpomap;
+    6412             : 
+    6413             :   // We arbitrarily set OC1/OT1 as the charged oxygen.
+    6414             : 
+    6415          10 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6416          10 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6417          10 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6418          10 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6419          10 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6420          10 :   lcpomap["ALA_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6421          10 :   lcpomap["ALA_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6422          10 :   lcpomap["ALA_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6423          10 :   lcpomap["ALA_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6424          10 :   lcpomap["ALA_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6425             : 
+    6426          10 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6427          10 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6428          10 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6429          10 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6430          10 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6431          10 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6432          10 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6433          10 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6434          10 :   lcpomap["ASP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6435          10 :   lcpomap["ASP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6436          10 :   lcpomap["ASP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6437          10 :   lcpomap["ASP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6438          10 :   lcpomap["ASP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6439             : 
+    6440          10 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6441          10 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6442          10 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6443          10 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6444          10 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6445          10 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6446          10 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6447          10 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6448          10 :   lcpomap["ASN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6449          10 :   lcpomap["ASN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6450          10 :   lcpomap["ASN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6451          10 :   lcpomap["ASN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6452          10 :   lcpomap["ASN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6453             : 
+    6454          10 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6455          10 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6456          10 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6457          10 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6458          10 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6459          10 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6460          10 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6461          10 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6462          10 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6463          10 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6464          10 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6465          10 :   lcpomap["ARG_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6466          10 :   lcpomap["ARG_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6467          10 :   lcpomap["ARG_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6468          10 :   lcpomap["ARG_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6469          10 :   lcpomap["ARG_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6470             : 
+    6471          10 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6472          10 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6473          10 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6474          10 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6475          10 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6476          10 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6477          10 :   lcpomap["CYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6478          10 :   lcpomap["CYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6479          10 :   lcpomap["CYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6480          10 :   lcpomap["CYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6481          10 :   lcpomap["CYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6482             : 
+    6483          10 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6484          10 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6485          10 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6486          10 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6487          10 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6488          10 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6489          10 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6490          10 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6491          10 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6492          10 :   lcpomap["GLU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6493          10 :   lcpomap["GLU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6494          10 :   lcpomap["GLU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6495          10 :   lcpomap["GLU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6496          10 :   lcpomap["GLU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6497             : 
+    6498          10 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6499          10 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6500          10 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6501          10 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6502          10 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6503          10 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6504          10 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6505          10 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6506          10 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6507          10 :   lcpomap["GLN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6508          10 :   lcpomap["GLN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6509          10 :   lcpomap["GLN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6510          10 :   lcpomap["GLN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6511          10 :   lcpomap["GLN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6512             : 
+    6513          10 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6514          10 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6515          10 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6516          10 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6517          10 :   lcpomap["GLY_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6518          10 :   lcpomap["GLY_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6519          10 :   lcpomap["GLY_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6520          10 :   lcpomap["GLY_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6521          10 :   lcpomap["GLY_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6522             : 
+    6523          10 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6524          10 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6525          10 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6526          10 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6527          10 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6528          10 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6529          10 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6530          10 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6531          10 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6532          10 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6533          10 :   lcpomap["HIS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6534          10 :   lcpomap["HIS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6535          10 :   lcpomap["HIS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6536             : 
+    6537          10 :   lcpomap["HIE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6538          10 :   lcpomap["HIE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6539          10 :   lcpomap["HIE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6540          10 :   lcpomap["HIE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6541          10 :   lcpomap["HIE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6542          10 :   lcpomap["HIE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6543          10 :   lcpomap["HIE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6544          10 :   lcpomap["HIE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6545          10 :   lcpomap["HIE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6546          10 :   lcpomap["HIE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6547          10 :   lcpomap["HIE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6548          10 :   lcpomap["HIE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6549          10 :   lcpomap["HIE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6550             : 
+    6551          10 :   lcpomap["HSE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6552          10 :   lcpomap["HSE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6553          10 :   lcpomap["HSE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6554          10 :   lcpomap["HSE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6555          10 :   lcpomap["HSE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6556          10 :   lcpomap["HSE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6557          10 :   lcpomap["HSE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6558          10 :   lcpomap["HSE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6559          10 :   lcpomap["HSE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6560          10 :   lcpomap["HSE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6561          10 :   lcpomap["HSE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6562          10 :   lcpomap["HSE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6563          10 :   lcpomap["HSE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6564             : 
+    6565          10 :   lcpomap["HID_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6566          10 :   lcpomap["HID_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6567          10 :   lcpomap["HID_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6568          10 :   lcpomap["HID_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6569          10 :   lcpomap["HID_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6570          10 :   lcpomap["HID_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6571          10 :   lcpomap["HID_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6572          10 :   lcpomap["HID_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6573          10 :   lcpomap["HID_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6574          10 :   lcpomap["HID_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6575          10 :   lcpomap["HID_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6576          10 :   lcpomap["HID_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6577          10 :   lcpomap["HID_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6578             : 
+    6579          10 :   lcpomap["HSD_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6580          10 :   lcpomap["HSD_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6581          10 :   lcpomap["HSD_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6582          10 :   lcpomap["HSD_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6583          10 :   lcpomap["HSD_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6584          10 :   lcpomap["HSD_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6585          10 :   lcpomap["HSD_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6586          10 :   lcpomap["HSD_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6587          10 :   lcpomap["HSD_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6588          10 :   lcpomap["HSD_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6589          10 :   lcpomap["HSD_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6590          10 :   lcpomap["HSD_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6591          10 :   lcpomap["HSD_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6592             : 
+    6593          10 :   lcpomap["HIP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6594          10 :   lcpomap["HIP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6595          10 :   lcpomap["HIP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6596          10 :   lcpomap["HIP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6597          10 :   lcpomap["HIP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6598          10 :   lcpomap["HIP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6599          10 :   lcpomap["HIP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6600          10 :   lcpomap["HIP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6601          10 :   lcpomap["HIP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6602          10 :   lcpomap["HIP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6603          10 :   lcpomap["HIP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6604          10 :   lcpomap["HIP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6605          10 :   lcpomap["HIP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6606             : 
+    6607          10 :   lcpomap["HSP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6608          10 :   lcpomap["HSP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6609          10 :   lcpomap["HSP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6610          10 :   lcpomap["HSP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6611          10 :   lcpomap["HSP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6612          10 :   lcpomap["HSP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6613          10 :   lcpomap["HSP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6614          10 :   lcpomap["HSP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6615          10 :   lcpomap["HSP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6616          10 :   lcpomap["HSP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6617          10 :   lcpomap["HSP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6618          10 :   lcpomap["HSP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6619          10 :   lcpomap["HSP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6620             : 
+    6621          10 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6622          10 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6623          10 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6624          10 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6625          10 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6626          10 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6627          10 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6628          10 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6629          10 :   lcpomap["ILE_CD"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6630          10 :   lcpomap["ILE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6631          10 :   lcpomap["ILE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6632          10 :   lcpomap["ILE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6633          10 :   lcpomap["ILE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6634          10 :   lcpomap["ILE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6635             : 
+    6636          10 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6637          10 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6638          10 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6639          10 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6640          10 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6641          10 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6642          10 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6643          10 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6644          10 :   lcpomap["LEU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6645          10 :   lcpomap["LEU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6646          10 :   lcpomap["LEU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6647          10 :   lcpomap["LEU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6648          10 :   lcpomap["LEU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6649             : 
+    6650          10 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6651          10 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6652          10 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6653          10 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6654          10 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6655          10 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6656          10 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6657          10 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6658          10 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6659          10 :   lcpomap["LYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6660          10 :   lcpomap["LYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6661          10 :   lcpomap["LYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6662          10 :   lcpomap["LYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6663          10 :   lcpomap["LYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6664             : 
+    6665          10 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6666          10 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6667          10 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6668          10 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6669          10 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6670          10 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6671          10 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6672          10 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6673          10 :   lcpomap["MET_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6674          10 :   lcpomap["MET_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6675          10 :   lcpomap["MET_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6676          10 :   lcpomap["MET_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6677          10 :   lcpomap["MET_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6678             : 
+    6679          10 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6680          10 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6681          10 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6682          10 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6683          10 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6684          10 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6685          10 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6686          10 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6687          10 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6688          10 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6689          10 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6690          10 :   lcpomap["PHE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6691          10 :   lcpomap["PHE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6692          10 :   lcpomap["PHE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6693          10 :   lcpomap["PHE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6694          10 :   lcpomap["PHE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6695             : 
+    6696          10 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6697          10 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6698          10 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6699          10 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6700          10 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6701          10 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6702          10 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6703          10 :   lcpomap["PRO_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6704          10 :   lcpomap["PRO_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6705          10 :   lcpomap["PRO_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6706          10 :   lcpomap["PRO_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6707          10 :   lcpomap["PRO_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6708             : 
+    6709          10 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6710          10 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6711          10 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6712          10 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6713          10 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6714          10 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6715          10 :   lcpomap["SER_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6716          10 :   lcpomap["SER_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6717          10 :   lcpomap["SER_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6718          10 :   lcpomap["SER_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6719          10 :   lcpomap["SER_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6720             : 
+    6721          10 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6722          10 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6723          10 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6724          10 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6725          10 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6726          10 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6727          10 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6728          10 :   lcpomap["THR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6729          10 :   lcpomap["THR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6730          10 :   lcpomap["THR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6731          10 :   lcpomap["THR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6732          10 :   lcpomap["THR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6733             : 
+    6734          10 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6735          10 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6736          10 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6737          10 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6738          10 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6739          10 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6740          10 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6741          10 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6742          10 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6743          10 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6744          10 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6745          10 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6746          10 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6747          10 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6748          10 :   lcpomap["TRP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6749          10 :   lcpomap["TRP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6750          10 :   lcpomap["TRP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6751          10 :   lcpomap["TRP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6752          10 :   lcpomap["TRP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6753             : 
+    6754          10 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    6755          10 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6756          10 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6757          10 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6758          10 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6759          10 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6760          10 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6761          10 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6762          10 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6763          10 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6764          10 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6765          10 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6766          10 :   lcpomap["TYR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6767          10 :   lcpomap["TYR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6768          10 :   lcpomap["TYR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6769          10 :   lcpomap["TYR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6770          10 :   lcpomap["TYR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6771             : 
+    6772          10 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    6773          10 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6774          10 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6775          10 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6776          10 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6777          10 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6778          10 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6779          10 :   lcpomap["VAL_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6780          10 :   lcpomap["VAL_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6781          10 :   lcpomap["VAL_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6782          10 :   lcpomap["VAL_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6783          10 :   lcpomap["VAL_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6784             : 
+    6785             :   // nucleic acids - WARNING: ONLY AMBER (OL3-rna/ol15-dna) FORMAT
+    6786             : 
+    6787          10 :   lcpomap["A3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6788          10 :   lcpomap["A3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6789          10 :   lcpomap["A3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6790          10 :   lcpomap["A3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6791          10 :   lcpomap["A3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6792          10 :   lcpomap["A3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6793          10 :   lcpomap["A3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6794          10 :   lcpomap["A3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6795          10 :   lcpomap["A3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6796          10 :   lcpomap["A3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6797          10 :   lcpomap["A3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6798          10 :   lcpomap["A3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6799          10 :   lcpomap["A3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6800          10 :   lcpomap["A3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6801          10 :   lcpomap["A3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6802          10 :   lcpomap["A3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6803          10 :   lcpomap["A3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6804          10 :   lcpomap["A3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6805          10 :   lcpomap["A3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6806          10 :   lcpomap["A3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6807          10 :   lcpomap["A3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6808          10 :   lcpomap["A3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6809          10 :   lcpomap["A3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6810          10 :   lcpomap["A3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6811          10 :   lcpomap["A3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6812          10 :   lcpomap["A3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6813             : 
+    6814          10 :   lcpomap["A5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6815          10 :   lcpomap["A5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6816          10 :   lcpomap["A5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6817          10 :   lcpomap["A5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6818          10 :   lcpomap["A5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6819          10 :   lcpomap["A5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6820          10 :   lcpomap["A5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6821          10 :   lcpomap["A5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6822          10 :   lcpomap["A5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6823          10 :   lcpomap["A5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6824          10 :   lcpomap["A5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6825          10 :   lcpomap["A5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6826          10 :   lcpomap["A5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6827          10 :   lcpomap["A5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6828          10 :   lcpomap["A5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6829          10 :   lcpomap["A5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6830          10 :   lcpomap["A5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6831          10 :   lcpomap["A5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6832          10 :   lcpomap["A5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6833          10 :   lcpomap["A5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6834          10 :   lcpomap["A5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6835          10 :   lcpomap["A5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6836          10 :   lcpomap["A5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6837          10 :   lcpomap["A5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6838          10 :   lcpomap["A5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6839          10 :   lcpomap["A5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6840             : 
+    6841          10 :   lcpomap["A_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6842          10 :   lcpomap["A_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6843          10 :   lcpomap["A_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6844          10 :   lcpomap["A_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6845          10 :   lcpomap["A_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6846          10 :   lcpomap["A_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6847          10 :   lcpomap["A_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6848          10 :   lcpomap["A_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6849          10 :   lcpomap["A_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6850          10 :   lcpomap["A_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6851          10 :   lcpomap["A_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6852          10 :   lcpomap["A_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6853          10 :   lcpomap["A_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6854          10 :   lcpomap["A_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6855          10 :   lcpomap["A_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6856          10 :   lcpomap["A_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6857          10 :   lcpomap["A_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6858          10 :   lcpomap["A_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6859          10 :   lcpomap["A_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6860          10 :   lcpomap["A_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6861          10 :   lcpomap["A_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6862          10 :   lcpomap["A_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6863          10 :   lcpomap["A_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6864          10 :   lcpomap["A_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6865          10 :   lcpomap["A_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6866          10 :   lcpomap["A_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6867             : 
+    6868          10 :   lcpomap["C3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6869          10 :   lcpomap["C3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6870          10 :   lcpomap["C3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6871          10 :   lcpomap["C3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6872          10 :   lcpomap["C3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6873          10 :   lcpomap["C3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6874          10 :   lcpomap["C3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6875          10 :   lcpomap["C3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6876          10 :   lcpomap["C3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6877          10 :   lcpomap["C3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6878          10 :   lcpomap["C3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6879          10 :   lcpomap["C3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6880          10 :   lcpomap["C3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    6881          10 :   lcpomap["C3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6882          10 :   lcpomap["C3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6883          10 :   lcpomap["C3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6884          10 :   lcpomap["C3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6885          10 :   lcpomap["C3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6886          10 :   lcpomap["C3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6887          10 :   lcpomap["C3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6888          10 :   lcpomap["C3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6889          10 :   lcpomap["C3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6890          10 :   lcpomap["C3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6891          10 :   lcpomap["C3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6892             : 
+    6893          10 :   lcpomap["C5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6894          10 :   lcpomap["C5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6895          10 :   lcpomap["C5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6896          10 :   lcpomap["C5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6897          10 :   lcpomap["C5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6898          10 :   lcpomap["C5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6899          10 :   lcpomap["C5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6900          10 :   lcpomap["C5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6901          10 :   lcpomap["C5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6902          10 :   lcpomap["C5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6903          10 :   lcpomap["C5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6904          10 :   lcpomap["C5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6905          10 :   lcpomap["C5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    6906          10 :   lcpomap["C5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6907          10 :   lcpomap["C5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6908          10 :   lcpomap["C5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6909          10 :   lcpomap["C5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6910          10 :   lcpomap["C5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6911          10 :   lcpomap["C5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6912          10 :   lcpomap["C5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6913          10 :   lcpomap["C5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6914          10 :   lcpomap["C5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6915          10 :   lcpomap["C5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6916          10 :   lcpomap["C5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6917             : 
+    6918          10 :   lcpomap["C_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6919          10 :   lcpomap["C_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6920          10 :   lcpomap["C_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6921          10 :   lcpomap["C_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6922          10 :   lcpomap["C_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6923          10 :   lcpomap["C_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6924          10 :   lcpomap["C_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6925          10 :   lcpomap["C_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6926          10 :   lcpomap["C_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6927          10 :   lcpomap["C_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6928          10 :   lcpomap["C_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6929          10 :   lcpomap["C_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6930          10 :   lcpomap["C_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    6931          10 :   lcpomap["C_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6932          10 :   lcpomap["C_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6933          10 :   lcpomap["C_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6934          10 :   lcpomap["C_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6935          10 :   lcpomap["C_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6936          10 :   lcpomap["C_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6937          10 :   lcpomap["C_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6938          10 :   lcpomap["C_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6939          10 :   lcpomap["C_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6940          10 :   lcpomap["C_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6941          10 :   lcpomap["C_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6942             : 
+    6943          10 :   lcpomap["DA3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6944          10 :   lcpomap["DA3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6945          10 :   lcpomap["DA3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6946          10 :   lcpomap["DA3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6947          10 :   lcpomap["DA3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6948          10 :   lcpomap["DA3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6949          10 :   lcpomap["DA3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6950          10 :   lcpomap["DA3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6951          10 :   lcpomap["DA3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6952          10 :   lcpomap["DA3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6953          10 :   lcpomap["DA3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6954          10 :   lcpomap["DA3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6955          10 :   lcpomap["DA3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6956          10 :   lcpomap["DA3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6957          10 :   lcpomap["DA3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6958          10 :   lcpomap["DA3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6959          10 :   lcpomap["DA3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6960          10 :   lcpomap["DA3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6961          10 :   lcpomap["DA3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6962          10 :   lcpomap["DA3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6963          10 :   lcpomap["DA3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6964          10 :   lcpomap["DA3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6965          10 :   lcpomap["DA3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6966          10 :   lcpomap["DA3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6967          10 :   lcpomap["DA3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6968             : 
+    6969          10 :   lcpomap["DA5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6970          10 :   lcpomap["DA5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6971          10 :   lcpomap["DA5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6972          10 :   lcpomap["DA5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6973          10 :   lcpomap["DA5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6974          10 :   lcpomap["DA5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6975          10 :   lcpomap["DA5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6976          10 :   lcpomap["DA5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6977          10 :   lcpomap["DA5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    6978          10 :   lcpomap["DA5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6979          10 :   lcpomap["DA5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6980          10 :   lcpomap["DA5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6981          10 :   lcpomap["DA5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    6982          10 :   lcpomap["DA5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    6983          10 :   lcpomap["DA5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    6984          10 :   lcpomap["DA5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6985          10 :   lcpomap["DA5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6986          10 :   lcpomap["DA5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    6987          10 :   lcpomap["DA5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6988          10 :   lcpomap["DA5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6989          10 :   lcpomap["DA5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6990          10 :   lcpomap["DA5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    6991          10 :   lcpomap["DA5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6992          10 :   lcpomap["DA5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    6993          10 :   lcpomap["DA5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    6994             : 
+    6995          10 :   lcpomap["DA_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6996          10 :   lcpomap["DA_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    6997          10 :   lcpomap["DA_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    6998          10 :   lcpomap["DA_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    6999          10 :   lcpomap["DA_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7000          10 :   lcpomap["DA_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7001          10 :   lcpomap["DA_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7002          10 :   lcpomap["DA_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7003          10 :   lcpomap["DA_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7004          10 :   lcpomap["DA_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7005          10 :   lcpomap["DA_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7006          10 :   lcpomap["DA_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7007          10 :   lcpomap["DA_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7008          10 :   lcpomap["DA_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7009          10 :   lcpomap["DA_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7010          10 :   lcpomap["DA_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7011          10 :   lcpomap["DA_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7012          10 :   lcpomap["DA_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7013          10 :   lcpomap["DA_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7014          10 :   lcpomap["DA_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7015          10 :   lcpomap["DA_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7016          10 :   lcpomap["DA_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7017          10 :   lcpomap["DA_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7018          10 :   lcpomap["DA_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7019          10 :   lcpomap["DA_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7020             : 
+    7021          10 :   lcpomap["DC3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7022          10 :   lcpomap["DC3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7023          10 :   lcpomap["DC3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7024          10 :   lcpomap["DC3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7025          10 :   lcpomap["DC3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7026          10 :   lcpomap["DC3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7027          10 :   lcpomap["DC3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7028          10 :   lcpomap["DC3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7029          10 :   lcpomap["DC3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7030          10 :   lcpomap["DC3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7031          10 :   lcpomap["DC3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7032          10 :   lcpomap["DC3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7033          10 :   lcpomap["DC3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7034          10 :   lcpomap["DC3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7035          10 :   lcpomap["DC3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7036          10 :   lcpomap["DC3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7037          10 :   lcpomap["DC3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7038          10 :   lcpomap["DC3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7039          10 :   lcpomap["DC3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7040          10 :   lcpomap["DC3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7041          10 :   lcpomap["DC3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7042          10 :   lcpomap["DC3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7043          10 :   lcpomap["DC3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7044             : 
+    7045          10 :   lcpomap["DC5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7046          10 :   lcpomap["DC5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7047          10 :   lcpomap["DC5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7048          10 :   lcpomap["DC5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7049          10 :   lcpomap["DC5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7050          10 :   lcpomap["DC5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7051          10 :   lcpomap["DC5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7052          10 :   lcpomap["DC5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7053          10 :   lcpomap["DC5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7054          10 :   lcpomap["DC5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7055          10 :   lcpomap["DC5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7056          10 :   lcpomap["DC5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7057          10 :   lcpomap["DC5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7058          10 :   lcpomap["DC5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7059          10 :   lcpomap["DC5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7060          10 :   lcpomap["DC5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7061          10 :   lcpomap["DC5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7062          10 :   lcpomap["DC5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7063          10 :   lcpomap["DC5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7064          10 :   lcpomap["DC5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7065          10 :   lcpomap["DC5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7066          10 :   lcpomap["DC5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7067          10 :   lcpomap["DC5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7068             : 
+    7069          10 :   lcpomap["DC_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7070          10 :   lcpomap["DC_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7071          10 :   lcpomap["DC_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7072          10 :   lcpomap["DC_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7073          10 :   lcpomap["DC_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7074          10 :   lcpomap["DC_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7075          10 :   lcpomap["DC_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7076          10 :   lcpomap["DC_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7077          10 :   lcpomap["DC_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7078          10 :   lcpomap["DC_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7079          10 :   lcpomap["DC_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7080          10 :   lcpomap["DC_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7081          10 :   lcpomap["DC_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7082          10 :   lcpomap["DC_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7083          10 :   lcpomap["DC_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7084          10 :   lcpomap["DC_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7085          10 :   lcpomap["DC_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7086          10 :   lcpomap["DC_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7087          10 :   lcpomap["DC_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7088          10 :   lcpomap["DC_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7089          10 :   lcpomap["DC_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7090          10 :   lcpomap["DC_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7091          10 :   lcpomap["DC_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7092             : 
+    7093          10 :   lcpomap["DG3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7094          10 :   lcpomap["DG3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7095          10 :   lcpomap["DG3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7096          10 :   lcpomap["DG3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7097          10 :   lcpomap["DG3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7098          10 :   lcpomap["DG3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7099          10 :   lcpomap["DG3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7100          10 :   lcpomap["DG3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7101          10 :   lcpomap["DG3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7102          10 :   lcpomap["DG3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7103          10 :   lcpomap["DG3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7104          10 :   lcpomap["DG3_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7105          10 :   lcpomap["DG3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7106          10 :   lcpomap["DG3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7107          10 :   lcpomap["DG3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7108          10 :   lcpomap["DG3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7109          10 :   lcpomap["DG3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7110          10 :   lcpomap["DG3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7111          10 :   lcpomap["DG3_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7112          10 :   lcpomap["DG3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7113          10 :   lcpomap["DG3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7114          10 :   lcpomap["DG3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7115          10 :   lcpomap["DG3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7116          10 :   lcpomap["DG3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7117          10 :   lcpomap["DG3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7118          10 :   lcpomap["DG3_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7119             : 
+    7120          10 :   lcpomap["DG5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7121          10 :   lcpomap["DG5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7122          10 :   lcpomap["DG5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7123          10 :   lcpomap["DG5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7124          10 :   lcpomap["DG5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7125          10 :   lcpomap["DG5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7126          10 :   lcpomap["DG5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7127          10 :   lcpomap["DG5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7128          10 :   lcpomap["DG5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7129          10 :   lcpomap["DG5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7130          10 :   lcpomap["DG5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7131          10 :   lcpomap["DG5_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7132          10 :   lcpomap["DG5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7133          10 :   lcpomap["DG5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7134          10 :   lcpomap["DG5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7135          10 :   lcpomap["DG5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7136          10 :   lcpomap["DG5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7137          10 :   lcpomap["DG5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7138          10 :   lcpomap["DG5_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7139          10 :   lcpomap["DG5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7140          10 :   lcpomap["DG5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7141          10 :   lcpomap["DG5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7142          10 :   lcpomap["DG5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7143          10 :   lcpomap["DG5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7144          10 :   lcpomap["DG5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7145          10 :   lcpomap["DG5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7146             : 
+    7147          10 :   lcpomap["DG_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7148          10 :   lcpomap["DG_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7149          10 :   lcpomap["DG_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7150          10 :   lcpomap["DG_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7151          10 :   lcpomap["DG_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7152          10 :   lcpomap["DG_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7153          10 :   lcpomap["DG_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7154          10 :   lcpomap["DG_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7155          10 :   lcpomap["DG_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7156          10 :   lcpomap["DG_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7157          10 :   lcpomap["DG_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7158          10 :   lcpomap["DG_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7159          10 :   lcpomap["DG_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7160          10 :   lcpomap["DG_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7161          10 :   lcpomap["DG_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7162          10 :   lcpomap["DG_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7163          10 :   lcpomap["DG_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7164          10 :   lcpomap["DG_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7165          10 :   lcpomap["DG_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7166          10 :   lcpomap["DG_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7167          10 :   lcpomap["DG_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7168          10 :   lcpomap["DG_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7169          10 :   lcpomap["DG_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7170          10 :   lcpomap["DG_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7171          10 :   lcpomap["DG_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7172          10 :   lcpomap["DG_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7173             : 
+    7174          10 :   lcpomap["DT3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7175          10 :   lcpomap["DT3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7176          10 :   lcpomap["DT3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7177          10 :   lcpomap["DT3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7178          10 :   lcpomap["DT3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7179          10 :   lcpomap["DT3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7180          10 :   lcpomap["DT3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7181          10 :   lcpomap["DT3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7182          10 :   lcpomap["DT3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7183          10 :   lcpomap["DT3_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7184          10 :   lcpomap["DT3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7185          10 :   lcpomap["DT3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7186          10 :   lcpomap["DT3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7187          10 :   lcpomap["DT3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7188          10 :   lcpomap["DT3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7189          10 :   lcpomap["DT3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7190          10 :   lcpomap["DT3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7191          10 :   lcpomap["DT3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7192          10 :   lcpomap["DT3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7193          10 :   lcpomap["DT3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7194          10 :   lcpomap["DT3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7195          10 :   lcpomap["DT3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7196          10 :   lcpomap["DT3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7197          10 :   lcpomap["DT3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7198             : 
+    7199          10 :   lcpomap["DT5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7200          10 :   lcpomap["DT5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7201          10 :   lcpomap["DT5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7202          10 :   lcpomap["DT5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7203          10 :   lcpomap["DT5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7204          10 :   lcpomap["DT5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7205          10 :   lcpomap["DT5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7206          10 :   lcpomap["DT5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7207          10 :   lcpomap["DT5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7208          10 :   lcpomap["DT5_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7209          10 :   lcpomap["DT5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7210          10 :   lcpomap["DT5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7211          10 :   lcpomap["DT5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7212          10 :   lcpomap["DT5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7213          10 :   lcpomap["DT5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7214          10 :   lcpomap["DT5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7215          10 :   lcpomap["DT5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7216          10 :   lcpomap["DT5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7217          10 :   lcpomap["DT5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7218          10 :   lcpomap["DT5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7219          10 :   lcpomap["DT5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7220          10 :   lcpomap["DT5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7221          10 :   lcpomap["DT5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7222          10 :   lcpomap["DT5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7223             : 
+    7224          10 :   lcpomap["DT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7225          10 :   lcpomap["DT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7226          10 :   lcpomap["DT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7227          10 :   lcpomap["DT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7228          10 :   lcpomap["DT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7229          10 :   lcpomap["DT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7230          10 :   lcpomap["DT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7231          10 :   lcpomap["DT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7232          10 :   lcpomap["DT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7233          10 :   lcpomap["DT_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7234          10 :   lcpomap["DT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7235          10 :   lcpomap["DT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7236          10 :   lcpomap["DT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7237          10 :   lcpomap["DT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7238          10 :   lcpomap["DT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7239          10 :   lcpomap["DT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7240          10 :   lcpomap["DT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7241          10 :   lcpomap["DT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7242          10 :   lcpomap["DT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7243          10 :   lcpomap["DT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7244          10 :   lcpomap["DT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7245          10 :   lcpomap["DT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7246          10 :   lcpomap["DT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7247          10 :   lcpomap["DT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7248             : 
+    7249          10 :   lcpomap["G3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7250          10 :   lcpomap["G3_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7251          10 :   lcpomap["G3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7252          10 :   lcpomap["G3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7253          10 :   lcpomap["G3_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7254          10 :   lcpomap["G3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7255          10 :   lcpomap["G3_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7256          10 :   lcpomap["G3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7257          10 :   lcpomap["G3_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7258          10 :   lcpomap["G3_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7259          10 :   lcpomap["G3_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7260          10 :   lcpomap["G3_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7261          10 :   lcpomap["G3_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7262          10 :   lcpomap["G3_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7263          10 :   lcpomap["G3_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7264          10 :   lcpomap["G3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7265          10 :   lcpomap["G3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7266          10 :   lcpomap["G3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7267          10 :   lcpomap["G3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7268          10 :   lcpomap["G3_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7269          10 :   lcpomap["G3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7270          10 :   lcpomap["G3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7271          10 :   lcpomap["G3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7272          10 :   lcpomap["G3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7273          10 :   lcpomap["G3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7274          10 :   lcpomap["G3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7275          10 :   lcpomap["G3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7276             : 
+    7277          10 :   lcpomap["G5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7278          10 :   lcpomap["G5_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7279          10 :   lcpomap["G5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7280          10 :   lcpomap["G5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7281          10 :   lcpomap["G5_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7282          10 :   lcpomap["G5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7283          10 :   lcpomap["G5_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7284          10 :   lcpomap["G5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7285          10 :   lcpomap["G5_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7286          10 :   lcpomap["G5_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7287          10 :   lcpomap["G5_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7288          10 :   lcpomap["G5_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7289          10 :   lcpomap["G5_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7290          10 :   lcpomap["G5_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7291          10 :   lcpomap["G5_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7292          10 :   lcpomap["G5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7293          10 :   lcpomap["G5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7294          10 :   lcpomap["G5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7295          10 :   lcpomap["G5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7296          10 :   lcpomap["G5_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7297          10 :   lcpomap["G5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7298          10 :   lcpomap["G5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7299          10 :   lcpomap["G5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7300          10 :   lcpomap["G5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7301          10 :   lcpomap["G5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7302          10 :   lcpomap["G5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7303          10 :   lcpomap["G5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7304             : 
+    7305          10 :   lcpomap["G_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7306          10 :   lcpomap["G_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7307          10 :   lcpomap["G_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7308          10 :   lcpomap["G_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7309          10 :   lcpomap["G_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7310          10 :   lcpomap["G_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7311          10 :   lcpomap["G_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7312          10 :   lcpomap["G_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7313          10 :   lcpomap["G_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7314          10 :   lcpomap["G_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7315          10 :   lcpomap["G_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7316          10 :   lcpomap["G_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7317          10 :   lcpomap["G_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7318          10 :   lcpomap["G_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7319          10 :   lcpomap["G_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7320          10 :   lcpomap["G_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7321          10 :   lcpomap["G_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7322          10 :   lcpomap["G_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7323          10 :   lcpomap["G_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7324          10 :   lcpomap["G_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7325          10 :   lcpomap["G_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7326          10 :   lcpomap["G_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7327          10 :   lcpomap["G_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7328          10 :   lcpomap["G_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7329          10 :   lcpomap["G_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7330          10 :   lcpomap["G_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7331          10 :   lcpomap["G_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7332             : 
+    7333          10 :   lcpomap["U3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7334          10 :   lcpomap["U3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7335          10 :   lcpomap["U3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7336          10 :   lcpomap["U3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7337          10 :   lcpomap["U3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7338          10 :   lcpomap["U3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7339          10 :   lcpomap["U3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7340          10 :   lcpomap["U3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7341          10 :   lcpomap["U3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7342          10 :   lcpomap["U3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7343          10 :   lcpomap["U3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7344          10 :   lcpomap["U3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7345          10 :   lcpomap["U3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7346          10 :   lcpomap["U3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7347          10 :   lcpomap["U3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7348          10 :   lcpomap["U3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7349          10 :   lcpomap["U3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7350          10 :   lcpomap["U3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7351          10 :   lcpomap["U3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7352          10 :   lcpomap["U3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7353          10 :   lcpomap["U3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7354          10 :   lcpomap["U3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7355          10 :   lcpomap["U3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7356          10 :   lcpomap["U3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7357             : 
+    7358          10 :   lcpomap["U5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7359          10 :   lcpomap["U5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7360          10 :   lcpomap["U5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7361          10 :   lcpomap["U5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7362          10 :   lcpomap["U5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7363          10 :   lcpomap["U5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7364          10 :   lcpomap["U5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7365          10 :   lcpomap["U5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7366          10 :   lcpomap["U5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7367          10 :   lcpomap["U5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7368          10 :   lcpomap["U5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7369          10 :   lcpomap["U5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7370          10 :   lcpomap["U5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7371          10 :   lcpomap["U5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7372          10 :   lcpomap["U5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7373          10 :   lcpomap["U5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7374          10 :   lcpomap["U5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7375          10 :   lcpomap["U5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7376          10 :   lcpomap["U5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7377          10 :   lcpomap["U5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7378          10 :   lcpomap["U5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7379          10 :   lcpomap["U5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7380          10 :   lcpomap["U5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7381          10 :   lcpomap["U5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7382             : 
+    7383          10 :   lcpomap["U_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7384          10 :   lcpomap["U_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7385          10 :   lcpomap["U_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7386          10 :   lcpomap["U_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7387          10 :   lcpomap["U_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7388          10 :   lcpomap["U_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7389          10 :   lcpomap["U_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7390          10 :   lcpomap["U_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7391          10 :   lcpomap["U_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7392          10 :   lcpomap["U_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7393          10 :   lcpomap["U_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7394          10 :   lcpomap["U_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7395          10 :   lcpomap["U_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7396          10 :   lcpomap["U_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7397          10 :   lcpomap["U_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7398          10 :   lcpomap["U_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7399          10 :   lcpomap["U_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7400          10 :   lcpomap["U_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7401          10 :   lcpomap["U_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7402          10 :   lcpomap["U_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7403          10 :   lcpomap["U_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7404          10 :   lcpomap["U_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7405          10 :   lcpomap["U_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7406          10 :   lcpomap["U_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7407             : 
+    7408          10 :   return lcpomap;
+    7409             : }
+    7410             : 
+    7411             : // assigns LCPO parameters to each atom reading from database
+    7412          10 : void SAXS::readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms)
+    7413             : {
+    7414          10 :   std::map<std::string, std::vector<double> > lcpomap = setupLCPOparam();
+    7415             : 
+    7416       35476 :   for(unsigned i=0; i<natoms; ++i)
+    7417             :   {
+    7418       35466 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S' || (AtomResidueName[0][i][0]=='P'))) {
+    7419       16548 :       std::string identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+    7420       16548 :       std::vector<double> LCPOparamVector = lcpomap.at(identifier);
+    7421             :       double rs = 0.14;
+    7422       16548 :       LCPOparam[i].push_back(LCPOparamVector[0]+rs*10.);
+    7423       16548 :       LCPOparam[i].push_back(LCPOparamVector[1]);
+    7424       16548 :       LCPOparam[i].push_back(LCPOparamVector[2]);
+    7425       16548 :       LCPOparam[i].push_back(LCPOparamVector[3]);
+    7426       16548 :       LCPOparam[i].push_back(LCPOparamVector[4]);
+    7427             :     }
+    7428             :   }
+    7429             : 
+    7430       35476 :   for(unsigned i=0; i<natoms; ++i) {
+    7431       35466 :     if (LCPOparam[i].size()==0 ) {
+    7432       18918 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S') || (AtomResidueName[0][i][0]=='P')) {
+    7433           0 :         std::cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << std::endl;
+    7434           0 :         error ("missing LCPO parameters\n");
+    7435             :       }
+    7436             :     }
+    7437             :   }
+    7438             : 
+    7439          10 :   if (AtomResidueName[0][0] == "N") {
+    7440          10 :     LCPOparam[0][1] = 7.3511e-01;
+    7441          10 :     LCPOparam[0][2] = -2.2116e-01;
+    7442          10 :     LCPOparam[0][3] = -8.9148e-04;
+    7443          10 :     LCPOparam[0][4] = 2.5230e-04;
+    7444             :   }
+    7445             : 
+    7446          10 :   if (AtomResidueName[0][natoms-1] == "O") {
+    7447           0 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+    7448           0 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+    7449           0 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+    7450           0 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+    7451             :   }
+    7452          10 : }
+    7453             : 
+    7454             : 
+    7455             : }//namespace isdb
+    7456             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func-sort-c.html b/coverage/isdb/Select.cpp.func-sort-c.html new file mode 100644 index 0000000000..624690668c --- /dev/null +++ b/coverage/isdb/Select.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe796createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe79C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe79D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func.html b/coverage/isdb/Select.cpp.func.html new file mode 100644 index 0000000000..c056b5a1b9 --- /dev/null +++ b/coverage/isdb/Select.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe796createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe79C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_118SelectRegisterMe79D2Ev4168
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.gcov.html b/coverage/isdb/Select.cpp.gcov.html new file mode 100644 index 0000000000..758daeb4f8 --- /dev/null +++ b/coverage/isdb/Select.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + 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-05-27 13:05: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 SELECTOR.
+      35             : 
+      36             : You should read the documentation for \ref SELECTOR to understand this action better.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : In this example we use a simulated-tempering like approach activated by the \ref RESCALE action.
+      41             : For each value of the scale parameter, we perform an independent Parallel Bias Metadynamics
+      42             : simulation (see \ref PBMETAD). At each moment of the simulation, only one of the \ref PBMETAD
+      43             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      44             : The \ref SELECT action can then be used to print out the value of the (active) \ref PBMETAD bias potential.
+      45             : 
+      46             : \plumedfile
+      47             : ene:  ENERGY
+      48             : d: DISTANCE ATOMS=1,2
+      49             : 
+      50             : SELECTOR NAME=GAMMA VALUE=0
+      51             : 
+      52             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      53             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      54             : 
+      55             : RESCALE ...
+      56             : LABEL=res ARG=ene,pbmetad0.bias,pbmetad1.bias TEMP=300
+      57             : SELECTOR=GAMMA MAX_RESCALE=1.2 NOT_RESCALED=2 NBIN=2
+      58             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      59             : ...
+      60             : 
+      61             : pbactive: SELECT ARG=pbmetad0.bias,pbmetad1.bias SELECTOR=GAMMA
+      62             : 
+      63             : PRINT ARG=pbactive STRIDE=100 FILE=COLVAR
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : class Select : public function::Function
+      70             : {
+      71             :   std::string selector_;
+      72             : 
+      73             : public:
+      74             :   explicit Select(const ActionOptions&);
+      75             :   void calculate();
+      76             :   static void registerKeywords(Keywords& keys);
+      77             : };
+      78             : 
+      79       12508 : PLUMED_REGISTER_ACTION(Select,"SELECT")
+      80             : 
+      81           4 : void Select::registerKeywords(Keywords& keys) {
+      82           4 :   Function::registerKeywords(keys);
+      83           4 :   keys.use("ARG");
+      84           8 :   keys.add("compulsory","SELECTOR","name of the variable used to select");
+      85           4 : }
+      86             : 
+      87           2 : Select::Select(const ActionOptions&ao):
+      88           2 :   Action(ao), Function(ao)
+      89             : {
+      90             :   // name of selector
+      91           2 :   parse("SELECTOR", selector_);
+      92             : 
+      93           2 :   addValueWithDerivatives(); setNotPeriodic();
+      94           2 :   checkRead();
+      95             : 
+      96           2 :   log.printf("  select based on %s\n",selector_.c_str());
+      97           4 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+      98             : 
+      99           2 : }
+     100             : 
+     101           8 : void Select::calculate()
+     102             : {
+     103           8 :   unsigned iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     104             : 
+     105             :   // check if iselect is smaller than the number of arguments
+     106           8 :   if(iselect>=getNumberOfArguments()) error("the value of the SELECTOR is greater than the number of arguments!");
+     107             : 
+     108             :   // put all the derivatives to zero
+     109          24 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) setDerivative(i, 0.0);
+     110             : 
+     111             :   // set value and derivative for selected argument
+     112           8 :   setValue(getArgument(iselect));
+     113           8 :   setDerivative(iselect, 1.0);
+     114           8 : }
+     115             : 
+     116             : }
+     117             : }
+     118             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func-sort-c.html b/coverage/isdb/Selector.cpp.func-sort-c.html new file mode 100644 index 0000000000..cf39c10211 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe726createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func.html b/coverage/isdb/Selector.cpp.func.html new file mode 100644 index 0000000000..540ee5bd88 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe726createERKNS_13ActionOptionsE2
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72C2Ev4168
_ZN4PLMD4isdb12_GLOBAL__N_120SelectorRegisterMe72D2Ev4168
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.gcov.html b/coverage/isdb/Selector.cpp.gcov.html new file mode 100644 index 0000000000..dd91580bb6 --- /dev/null +++ b/coverage/isdb/Selector.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(Selector,"SELECTOR")
+      73             : 
+      74           4 : void Selector::registerKeywords( Keywords& keys ) {
+      75           4 :   Action::registerKeywords(keys);
+      76           8 :   keys.add("compulsory","NAME","name of the SELECTOR");
+      77           8 :   keys.add("compulsory","VALUE","set (initial) value of the SELECTOR");
+      78           4 : }
+      79             : 
+      80           2 : Selector::Selector(const ActionOptions&ao):
+      81           2 :   Action(ao)
+      82             : {
+      83             :   std::string name;
+      84           2 :   parse("NAME", name);
+      85             :   double value;
+      86           2 :   parse("VALUE", value);
+      87           2 :   plumed.passMap[name] = value;
+      88           2 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index-sort-f.html b/coverage/isdb/index-sort-f.html new file mode 100644 index 0000000000..01c969a254 --- /dev/null +++ b/coverage/isdb/index-sort-f.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:86451059581.6 %
Date:2024-05-27 13:05:14Functions:19824381.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
FretEfficiency.cpp +
94.7%94.7%
+
94.7 %36 / 3885.7 %6 / 7
Select.cpp +
100.0%
+
100.0 %21 / 2185.7 %6 / 7
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10487.5 %7 / 8
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17287.5 %7 / 8
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12987.5 %7 / 8
Metainference.cpp +
84.2%84.2%
+
84.2 %741 / 88090.0 %27 / 30
SAXS.cpp +
80.1%80.1%
+
80.1 %4808 / 600591.7 %22 / 24
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.16
+
+ + + diff --git a/coverage/isdb/index-sort-l.html b/coverage/isdb/index-sort-l.html new file mode 100644 index 0000000000..261e3c7fbc --- /dev/null +++ b/coverage/isdb/index-sort-l.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:86451059581.6 %
Date:2024-05-27 13:05:14Functions:19824381.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
SAXS.cpp +
80.1%80.1%
+
80.1 %4808 / 600591.7 %22 / 24
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
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.16
+
+ + + diff --git a/coverage/isdb/index.html b/coverage/isdb/index.html new file mode 100644 index 0000000000..48e233d576 --- /dev/null +++ b/coverage/isdb/index.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:86451059581.6 %
Date:2024-05-27 13:05:14Functions:19824381.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 +
80.1%80.1%
+
80.1 %4808 / 600591.7 %22 / 24
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.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func-sort-c.html b/coverage/logmfd/LogMFD.cpp.func-sort-c.html new file mode 100644 index 0000000000..d85ee943d3 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe4586createERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe458C2Ev4168
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe458D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func.html b/coverage/logmfd/LogMFD.cpp.func.html new file mode 100644 index 0000000000..c464271f97 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe4586createERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe458C2Ev4168
_ZN4PLMD6logmfd12_GLOBAL__N_119LogMFDRegisterMe458D2Ev4168
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.gcov.html b/coverage/logmfd/LogMFD.cpp.gcov.html new file mode 100644 index 0000000000..7df2c6dfb0 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.gcov.html @@ -0,0 +1,1324 @@ + + + + + + + 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:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019
+       3             : National Institute of Advanced Industrial Science and Technology (AIST), Japan.
+       4             : This file contains module for LogMFD method proposed by Tetsuya Morishita(AIST).
+       5             : 
+       6             : The LogMFD module is free software: you can redistribute it and/or modify
+       7             : it under the terms of the GNU Lesser General Public License as published by
+       8             : the Free Software Foundation, either version 3 of the License, or
+       9             : (at your option) any later version.
+      10             : 
+      11             : The LogMFD module is distributed in the hope that it will be useful,
+      12             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             : GNU Lesser General Public License for more details.
+      15             : 
+      16             : You should have received a copy of the GNU Lesser General Public License
+      17             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : 
+      20             : //+PLUMEDOC LOGMFDMOD_BIAS LOGMFD
+      21             : /*
+      22             : Used to perform LogMFD, LogPD, and TAMD/d-AFED.
+      23             : 
+      24             : \section LogMFD LogMFD
+      25             : 
+      26             : Consider a physical system of \f$N_q\f$ particles, for which the Hamiltonian is given as
+      27             : 
+      28             : \f[
+      29             :   {H_{\rm MD}}\left( {\bf{\Gamma}} \right) = \sum\limits_{j = 1}^{{N_q}} {\frac{{{\bf{p}}_j^2}}{{2{m_j}}}}  + \Phi \left( {\bf{q}} \right)
+      30             : \f]
+      31             : 
+      32             : where \f${\bf q}_j\f$, \f${\bf p}_j\f$ (\f$\bf{\Gamma}={\bf q},{\bf p}\f$), and \f$m_j\f$ are the position, momentum, and mass of particle \f$j\f$ respectively,
+      33             : and \f$\Phi\f$ is the potential energy function for \f${\bf q}\f$.
+      34             : The free energy \f$F({\bf X})\f$ as a function of a set of \f$N\f$ collective variables (CVs) is given as
+      35             : 
+      36             : \f{eqnarray*}{
+      37             :   F\left( {{\bf X}} \right) &=&  - {k_B}T\log \int {\exp \left[ { - \beta {H_{\rm MD}}} \right]\prod\limits_{i = 1}^N {\delta \left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)} d{\bf{\Gamma }}} \\
+      38             :   &\simeq&  - {k_B}T\log \int {\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}
+      39             : \f}
+      40             : 
+      41             : where \f$\bf{s}\f$ are the CVs, \f$k_B\f$ is Boltzmann constant, \f$\beta=1/k_BT\f$,
+      42             : and \f$K_i\f$ is the spring constant which is large enough to invoke
+      43             : 
+      44             : \f[
+      45             :  \delta \left( x \right) = \lim_{k \to \infty } \sqrt {\beta k/2\pi} \exp \left( -\beta kx^2/2 \right)
+      46             : \f]
+      47             : 
+      48             : In mean-force dynamics, \f${\bf X}\f$ are treated as fictitious dynamical variables, which are associated with the following Hamiltonian,
+      49             : 
+      50             : \f[
+      51             :  {H_{\rm log}} = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{2{M_i}}} + \Psi \left( {{\bf X}} \right)}
+      52             : \f]
+      53             : 
+      54             : where \f${P_{{X_i}}}\f$  and \f$M_i\f$ are the momentum and mass of \f$X_i\f$, respectively, and \f$\Psi\f$ is the potential function for \f${\bf X}\f$.
+      55             : We assume that \f$\Psi\f$ is a functional of \f$F({\bf X})\f$; \f$Ψ[F({\bf X})]\f$. The simplest form of \f$\Psi\f$ is \f$\Psi = F({\bf X})\f$,
+      56             : which corresponds to TAMD/d-AFED \cite AbramsJ2008, \cite Maragliano2006 (or the extended Lagrangian dynamics in the limit of the adiabatic decoupling between \f$\bf{q}\f$ and \f${\bf X}\f$).
+      57             :  In the case of LogMFD, the following form of \f$\Psi\f$ is introduced \cite MorishitaLogMFD;
+      58             : 
+      59             : 
+      60             : \f[
+      61             :   {\Psi _{\rm log}}\left( {{\bf X}} \right) = \gamma \log \left[ {\alpha F\left( {{\bf X}} \right) + 1} \right]
+      62             : \f]
+      63             : 
+      64             : where \f$\alpha\f$ (ALPHA) and \f$\gamma\f$ (GAMMA) are positive parameters. The logarithmic form of \f$\Psi_{\rm log}\f$ ensures the dynamics of \f${\bf X}\f$ on a much smoother energy surface [i.e., \f$\Psi_{\rm log}({\bf X})\f$] than \f$F({\bf X})\f$, thus enhancing the sampling in the \f${\bf X}\f$-space. The parameters \f$\alpha\f$ and \f$\gamma\f$ determine the degree of flatness of \f$\Psi_{\rm log}\f$, but adjusting only \f$\alpha\f$ is normally sufficient to have a relatively flat surface (with keeping the relation \f$\gamma=1/\alpha\f$).
+      65             : 
+      66             : The equation of motion for \f$X_i\f$ in LogMFD (no thermostat) is
+      67             : 
+      68             : \f[
+      69             :  {M_i}{\ddot X_i} =  - \left( {\frac{{\alpha \gamma }}{{\alpha F + 1}}} \right)\frac{{\partial F}}{{\partial {X_i}}}
+      70             : \f]
+      71             : 
+      72             : where \f$-\partial F/\partial X_i\f$  is evaluated as a canonical average under the condition that \f${\bf X}\f$ is fixed;
+      73             : 
+      74             : \f{eqnarray*}{
+      75             :  - \frac{{\partial F}}{{\partial {X_i}}} &\simeq& \frac{1}{Z}\int {{K_i}\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}\\
+      76             :  &\equiv& {\left\langle {{K_i}\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)} \right\rangle _{{\bf X}}}
+      77             : \f}
+      78             : 
+      79             : where
+      80             : 
+      81             : \f[
+      82             :  Z = \int {\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}
+      83             : \f]
+      84             : 
+      85             : The mean-force (MF) is practically evaluated by performing a shot-time canonical MD run of \f$N_m\f$ steps each time \f${\bf X}\f$ is updated according to the equation of motion for \f${\bf X}\f$.
+      86             : 
+      87             : If the canonical average for the MF is effectively converged, the dynamical variables \f${\bf q}\f$ and \f${\bf X}\f$ are decoupled and they evolve adiabatically, which can be exploited for the on-the-fly evaluation of \f$F({\bf X})\f$. I.e., \f$H_{\rm log}\f$ should be a constant of motion in this case, thus \f$F({\bf X})\f$ can be evaluated each time \f${\bf X}\f$ is updated as
+      88             : 
+      89             : 
+      90             : \f[
+      91             :  F\left( {{{\bf X}}\left( t \right)} \right) = \frac{1}{\alpha} \left[
+      92             :   \exp \frac{1}{\gamma} \left\{ \left( H_{\rm log} - \sum_i \frac{P_{X_i}^2}{2M_i} \right) \right\} - 1 \right]
+      93             : \f]
+      94             : 
+      95             : 
+      96             : This means that \f$F({\bf X})\f$ can be constructed without post processing (on-the-fly free energy reconstruction). Note that the on-the-fly free energy reconstruction is also possible in TAMD/d-AFED if the Hamiltonian-like conserved quantity is available (e.g., the Nose-Hoover type dynamics).
+      97             : 
+      98             : 
+      99             : 
+     100             : \section LogPD LogPD
+     101             : 
+     102             : 
+     103             : The accuracy in the MF is critical to the on-the-fly free energy reconstruction. To improve the evaluation of the MF, parallel-dynamics (PD) is incorporated into LogMFD, leading to logarithmic parallel-dynamics (LogPD) \cite MorishitaLogPD.
+     104             : 
+     105             : 
+     106             : In PD, the MF is evaluated by a non-equilibrium path-ensemble based on the Crooks-Jarzynski non-equilibrium work relation. To this end, multiple replicas of the MD system which run in parallel are introduced. The CVs [\f${\bf s}({\bf q})\f$] in each replica is restrained to the same value of \f${\bf X}(t)\f$. A canonical MD run with \f$N_m\f$ steps is performed in each replica, then the MF on \f$X_i\f$ is evaluated using the MD trajectories from all replicas.
+     107             : The MF is practically calculated as
+     108             : 
+     109             : 
+     110             : \f[
+     111             :  - \frac{{\partial F}}{{\partial {X_i}}} = \sum\limits_{k = 1}^{{N_r}} {{W_k}} \sum\limits_{n = 1}^{{N_m}} {\frac{1}{{{N_m}}}{K_i}\left[ {{s_i}\left( {{{\bf q}}_n^k} \right) - {X_i}} \right]}
+     112             : \f]
+     113             : 
+     114             : 
+     115             : 
+     116             : where \f${\bf q}^k_n\f$  indicates the \f${\bf q}\f$-configuration at time step \f$n\f$ in the \f$N_m\f$-step shot-time MD run in the \f$k\f$th replica among \f$N_r\f$ replicas. \f$W_k\f$ is given as
+     117             : 
+     118             : \f[
+     119             :  {W_k} = \frac{{{e^{ - \beta {w_k}\left( t \right)}}}}{{\sum\limits_{k=1}^{{N_r}} {{e^{ - \beta {w_k}\left( t \right)}}} }}
+     120             : \f]
+     121             : 
+     122             : 
+     123             : where
+     124             : 
+     125             : 
+     126             : \f[
+     127             :  {w_k}\left( t \right) = \int\limits_{{X_0}}^{X\left( t \right)} {\sum\limits_{i=1}^N {\frac{{\partial H_{\rm MD}^k}}{{\partial {X_i}}}d{X_i}} }
+     128             : \f]
+     129             : 
+     130             : \f[
+     131             :  H_{\rm MD}^k\left( {{\bf{\Gamma }},{{\bf X}}} \right) = {H_{\rm MD}}\left( {{{\bf{\Gamma }}^k}} \right) + \sum\limits_{i = 1}^N {\frac{{{K_i}}}{2}{{\left( {s_i^k - {X_i}} \right)}^2}}
+     132             : \f]
+     133             : 
+     134             : and \f$s^k_i\f$ is the \f$i\f$th CV in the \f$k\f$th replica.
+     135             : 
+     136             : \f$W_k\f$ comes from the Crooks-Jarzynski non-equilibrium work relation by which we can evaluate an equilibrium ensemble average from a set of non-equilibrium trajectories. Note that, to avoid possible numerical errors in the exponential function, the following form of \f$W_k\f$ is instead used in PLUMED,
+     137             : 
+     138             : \f[
+     139             :  {W_k}\left( t \right) = \frac{{\exp \left[ { - \beta \left\{ {{w_k}\left( t \right) - {w_{\min }}\left( t \right)} \right\}} \right]}}{{\sum\nolimits_k {\exp \left[ { - \beta \left\{ {{w_k}\left( t \right) - {w_{\min }}\left( t \right)} \right\}} \right]} }}
+     140             : \f]
+     141             : 
+     142             : where
+     143             : 
+     144             : \f[
+     145             :  {w_{\min }}\left( t \right) = {\rm Min}_k\left[ {{w_k}\left( t \right)} \right]
+     146             : \f]
+     147             : 
+     148             : 
+     149             : With the MF evaluated using the PD approach, free energy profiles can be reconstructed more efficiently (requiring less elapsed computing time) in LogPD than with a single MD system in LogMFD. In the case that there exist more than one stable state separated by high energy barriers in the hidden subspace orthogonal to the CV-subspace, LogPD is particularly of use to incorporate all the contributions from such hidden states with appropriate weights (in the limit \f$N_r\to\infty\f$ ).
+     150             : 
+     151             : Note that LogPD calculations should always be initiated with an equilibrium \f${\bf q}\f$-configuration in each replica, because the Crooks-Jarzynski non-equilibrium work relation is invoked. Also note that LogPD is currently available only with Gromacs, while LogMFD can be performed with LAMMPS, Gromacs, Quantum Espresso, NAMD, and so on.
+     152             : 
+     153             : \section Thermostat Using LogMFD/PD with a thermostat
+     154             : 
+     155             : Introducing a thermostat on \f${\bf X}\f$ is often recommended in LogMFD/PD to maintain the adiabatic decoupling between \f${\bf q}\f$ and \f${\bf X}\f$. In the framework of the LogMFD approach, the Nose-Hoover type thermostat and the Gaussian isokinetic (velocity scaling) thermostat can be used to control the kinetic energy of \f${\bf X}\f$.
+     156             : 
+     157             : \subsection Nose-Hoover Nose-Hoover LogMFD/PD
+     158             : 
+     159             : The equation of motion for \f$X_i\f$ coupled to a Nose-Hoover thermostat variable \f$\eta\f$ (single heat bath) is
+     160             : 
+     161             : \f[
+     162             :  {M_i}{\ddot X_i} =  - \left( {\frac{{\alpha \gamma }}{{\alpha F + 1}}} \right)\frac{{\partial F}}{{\partial {X_i}}} - {M_i}{\dot X_i}\dot \eta
+     163             : \f]
+     164             : 
+     165             : The equation of motion for \f$\eta\f$ is
+     166             : 
+     167             : \f[
+     168             :  Q\ddot \eta  = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{{M_i}}} - N{k_B}T}
+     169             : \f]
+     170             : 
+     171             : where \f$N\f$ is the number of the CVs. Since the following pseudo-Hamiltonian is a constant of motion in Nose-Hoover LogMFD/PD,
+     172             : 
+     173             : \f[
+     174             :  H_{\rm log}^{\rm NH} = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{2{M_i}}} + \gamma \log \left[ {\alpha F\left( {{\bf X}} \right) + 1} \right] + \frac{1}{2}Q{{\dot \eta }^2} + N{k_B}T\eta}
+     175             : \f]
+     176             : 
+     177             : \f$F({\bf X}(t))\f$ is obtained at each MFD step as
+     178             : 
+     179             : \f[
+     180             :  F\left( {{{\bf X}}\left( t \right)} \right) = \frac{1}{\alpha }\left[ {\exp \left\{ {{{ \frac{1}{\gamma} \left( {H_{\rm log}^{\rm NH} - \sum_i {\frac{{P_{{X_i}}^2}}{{2{M_i}}}}  - \frac{1}{2}Q{{\dot \eta }^2} - N{k_B}T\eta} \right)}  }} \right\} - 1} \right]
+     181             : \f]
+     182             : 
+     183             : 
+     184             : 
+     185             : \subsection VS Velocity scaling LogMFD/PD
+     186             : 
+     187             : The velocity scaling algorithm (which is equivalent to the Gaussian isokinetic dynamics in the limit \f$\Delta t\to 0\f$) can also be employed to control the velocity of \f${\bf X}\f$, \f$\bf{V}_x\f$.
+     188             : 
+     189             : The following algorithm is introduced to perform isokinetic LogMFD calculations \cite MorishitaVsLogMFD;
+     190             : 
+     191             : \f{eqnarray*}{
+     192             : {V_{{X_i}}}\left( {{t_{n + 1}}} \right)
+     193             : &=&
+     194             :  V_{X_i}^\prime \left( {{t_n}} \right) + \Delta t \left[
+     195             :   { - \left( {\frac{{\alpha \gamma }}{{\alpha F\left( {{t_n}} \right) + 1}}} \right)
+     196             :   \frac{{\partial F\left( {{t_n}} \right)}}{{\partial {X_i}}}}
+     197             :  \right]\\
+     198             : S\left( {{t_{n + 1}}} \right)
+     199             : &=&
+     200             :  \sqrt {\frac{{N{k_B}T}}{{\sum\limits_i {{M_i}V_{{X_i}}^2\left( {{t_{n + 1}}} \right)} }}} \\
+     201             : {V_{{X_i}}}^\prime \left( {{t_{n + 1}}} \right)
+     202             : &=&
+     203             : S\left( {{t_{n + 1}}} \right){V_{{X_i}}}\left( {{t_{n + 1}}} \right)\\
+     204             : {X_i}\left( {{t_{n + 1}}} \right)
+     205             : &=&
+     206             : {X_i}\left( {{t_n}} \right) + \Delta t V_{X_i}^\prime \left( {{t_{n + 1}}} \right)\\
+     207             : {\Psi_{\rm log}}\left( {{t_{n + 1}}} \right)
+     208             : &=&
+     209             : N{k_B}T\log S\left( {{t_{n + 1}}} \right) + {\Psi_{\rm log}}\left( {{t_n}} \right)\\
+     210             : F\left( {{t_{n + 1}}} \right)
+     211             : &=&
+     212             : \frac{1}{\alpha} \left[
+     213             :   \exp \left\{ \Psi_{\rm log} \left( t_{n+1} \right) / \gamma \right\} - 1
+     214             : \right]
+     215             : \f}
+     216             : 
+     217             : Note that \f$V_{X_i}^\prime\left( {{t_0}} \right)\f$ is assumed to be initially given, which meets the following relation,
+     218             : 
+     219             : \f[
+     220             :   \sum\limits_{i = 1}^N M_i V_{X_i}^{\prime 2} \left( t_0 \right)  = N{k_B}{T}
+     221             : \f]
+     222             : 
+     223             : It should be stressed that, in the same way as in the NVE and Nose-Hoover LogMFD/PD, \f$F({\bf X}(t))\f$ can be evaluated at each MFD step (on-the-fly free energy reconstruction) in Velocity Scaling LogMFD/PD.
+     224             : 
+     225             : 
+     226             : \par Examples
+     227             : \section Examples Examples
+     228             : 
+     229             : \subsection Example-LoGMFD Example of LogMFD
+     230             : 
+     231             : The following input file tells plumed to restrain collective variables
+     232             : to the fictitious dynamical variables in LogMFD/PD.
+     233             : 
+     234             : plumed.dat
+     235             : \plumedfile
+     236             : UNITS TIME=fs LENGTH=1.0 ENERGY=kcal/mol MASS=1.0 CHARGE=1.0
+     237             : phi: TORSION ATOMS=5,7,9,15
+     238             : psi: TORSION ATOMS=7,9,15,17
+     239             : 
+     240             : # LogMFD
+     241             : LOGMFD ...
+     242             : LABEL=logmfd
+     243             : ARG=phi,psi
+     244             : KAPPA=1000.0,1000.0
+     245             : DELTA_T=1.0
+     246             : INTERVAL=200
+     247             : TEMP=300.0
+     248             : FLOG=2.0
+     249             : MFICT=5000000,5000000
+     250             : VFICT=3.5e-4,3.5e-4
+     251             : ALPHA=4.0
+     252             : THERMOSTAT=NVE
+     253             : FICT_MAX=3.15,3.15
+     254             : FICT_MIN=-3.15,-3.15
+     255             : ... LOGMFD
+     256             : \endplumedfile
+     257             : 
+     258             : To submit this simulation with Gromacs, use the following command line
+     259             : to execute a LogMFD run with Gromacs-MD.
+     260             : Here topol.tpr is the input file
+     261             : which contains atomic coordinates and Gromacs parameters.
+     262             : 
+     263             : \verbatim
+     264             : gmx_mpi mdrun -s topol.tpr -plumed
+     265             : \endverbatim
+     266             : 
+     267             : This command will output files named logmfd.out and replica.out.
+     268             : 
+     269             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     270             : 
+     271             : logmfd.out
+     272             : 
+     273             : \verbatim
+     274             : # LogMFD
+     275             : # CVs : phi psi
+     276             : # Mass for CV particles : 5000000.000000 5000000.000000
+     277             : # Mass for thermostat   :   11923.224809
+     278             : # 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     279             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     280             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     281             :        0       2.000000     308.221983       0.000000       0.000000      -2.442363       0.000350       5.522717       2.426650       0.000350       7.443177
+     282             :        1       1.995466     308.475775       0.000000       0.000000      -2.442013       0.000350      -4.406246       2.427000       0.000350      11.531345
+     283             :        2       1.992970     308.615664       0.000000       0.000000      -2.441663       0.000350      -3.346513       2.427350       0.000350      15.763196
+     284             :        3       1.988619     308.859946       0.000000       0.000000      -2.441313       0.000350       6.463092       2.427701       0.000351       6.975422
+     285             : ...
+     286             : \endverbatim
+     287             : 
+     288             : The output file replica.out records all collective variables at every MFD step.
+     289             : 
+     290             : replica.out
+     291             : 
+     292             : \verbatim
+     293             :  Replica No. 0 of 1.
+     294             : # 1:iter_mfd, 2:work, 3:weight,
+     295             : # 4:phi(q)
+     296             : # 5:psi(q)
+     297             :        0    0.000000e+00     1.000000e+00       -2.436841       2.434093
+     298             :        1   -4.539972e-03     1.000000e+00       -2.446420       2.438531
+     299             :        2   -7.038516e-03     1.000000e+00       -2.445010       2.443114
+     300             :        3   -1.139672e-02     1.000000e+00       -2.434850       2.434677
+     301             : ...
+     302             : \endverbatim
+     303             : 
+     304             : \subsection Example-LogPD Example of LogPD
+     305             : 
+     306             : Use the following command line to execute a LogPD run using two MD replicas (note that only Gromacs is currently available for LogPD).
+     307             : Here 0/topol.tpr and 1/topol.tpr are the input files,
+     308             : each containing the atomic coordinates for the corresponding replica and Gromacs parameters. All the directories, 0/ and 1/, should contain the same plumed.dat.
+     309             : 
+     310             : \verbatim
+     311             : mpirun -np 2 gmx_mpi mdrun -s topol -plumed -multidir 0 1
+     312             : \endverbatim
+     313             : 
+     314             : This command will output files named logmfd.out in 0/, and replica.out.0 and replica.out.1 in 0/ and 1/, respectively.
+     315             : 
+     316             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     317             : 
+     318             : logmfd.out
+     319             : 
+     320             : \verbatim
+     321             : # LogPD, replica parallel of LogMFD
+     322             : # number of replica : 2
+     323             : # CVs : phi psi
+     324             : # Mass for CV particles : 5000000.000000 5000000.000000
+     325             : # Mass for thermostat   :   11923.224809
+     326             : # 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     327             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     328             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     329             :        0       2.000000     308.221983       0.000000       0.000000      -2.417903       0.000350       4.930899       2.451475       0.000350      -3.122024
+     330             :        1       1.999367     308.257404       0.000000       0.000000      -2.417552       0.000350       0.851133       2.451825       0.000350      -1.552718
+     331             :        2       1.999612     308.243683       0.000000       0.000000      -2.417202       0.000350      -1.588175       2.452175       0.000350       1.601274
+     332             :        3       1.999608     308.243922       0.000000       0.000000      -2.416852       0.000350       4.267745       2.452525       0.000350      -4.565621
+     333             : ...
+     334             : \endverbatim
+     335             : 
+     336             : 
+     337             : The output file replica.out.0 records all collective variables and the Jarzynski weight of replica No.0 at every MFD step.
+     338             : 
+     339             : replica.out.0
+     340             : 
+     341             : \verbatim
+     342             : # Replica No. 0 of 2.
+     343             : # 1:iter_mfd, 2:work, 3:weight,
+     344             : # 4:phi(q)
+     345             : # 5:psi(q)
+     346             :        0    0.000000e+00     5.000000e-01       -2.412607       2.446191
+     347             :        1   -4.649101e-06     4.994723e-01       -2.421403       2.451318
+     348             :        2    1.520985e-03     4.983996e-01       -2.420269       2.455049
+     349             :        3    1.588855e-03     4.983392e-01       -2.411081       2.447394
+     350             : ...
+     351             : \endverbatim
+     352             : 
+     353             : The output file replica.out.1 records all collective variables and the Jarzynski weight of replica No.1 at every MFD step.
+     354             : 
+     355             : replica.out.1
+     356             : 
+     357             : \verbatim
+     358             : # Replica No. 1 of 2.
+     359             : # 1:iter_mfd, 2:work, 3:weight,
+     360             : # 4:phi(q)
+     361             : # 5:psi(q)
+     362             :        0    0.000000e+00     5.000000e-01       -2.413336       2.450516
+     363             :        1   -1.263077e-03     5.005277e-01       -2.412009       2.449229
+     364             :        2   -2.295444e-03     5.016004e-01       -2.417322       2.452512
+     365             :        3   -2.371507e-03     5.016608e-01       -2.414078       2.448521
+     366             : ...
+     367             : \endverbatim
+     368             : 
+     369             : */
+     370             : //+ENDPLUMEDOC
+     371             : 
+     372             : #include "bias/Bias.h"
+     373             : #include "core/ActionRegister.h"
+     374             : #include "core/Atoms.h"
+     375             : #include "core/PlumedMain.h"
+     376             : 
+     377             : #include <iostream>
+     378             : 
+     379             : using namespace std;
+     380             : using namespace PLMD;
+     381             : using namespace bias;
+     382             : 
+     383             : namespace PLMD {
+     384             : namespace logmfd {
+     385             : /**
+     386             :    \brief class for LogMFD parameters, variables and subroutines.
+     387             :  */
+     388             : class LogMFD : public Bias {
+     389             :   bool firsttime;               ///< flag that indicates first MFD step or not.
+     390             :   int    step_initial;          ///< initial MD step.
+     391             :   int    interval;              ///< input parameter, period of MD steps when fictitious dynamical variables are evolved.
+     392             :   double delta_t;               ///< input parameter, one time step of MFD when fictitious dynamical variables are evolved.
+     393             :   string thermostat;            ///< input parameter, type of thermostat for canonical dyanamics.
+     394             :   double kbt;                   ///< k_B*temperature
+     395             :   double kbtpd;                   ///< k_B*temperature for PD
+     396             : 
+     397             :   int    TAMD;                  ///< input parameter, perform TAMD instead of LogMFD.
+     398             :   double alpha;                 ///< input parameter, alpha parameter for LogMFD.
+     399             :   double gamma;                 ///< input parameter, gamma parameter for LogMFD.
+     400             :   std::vector<double> kappa;    ///< input parameter, strength of the harmonic restraining potential.
+     401             : 
+     402             :   std::vector<double> fict_max; ///< input parameter, maximum of each fictitous dynamical variable.
+     403             :   std::vector<double> fict_min; ///< input parameter, minimum of each fictitous dynamical variable.
+     404             : 
+     405             : 
+     406             :   std::vector<double>  fict;    ///< current values of each fictitous dynamical variable.
+     407             :   std::vector<double> vfict;    ///< current velocity of each fictitous dynamical variable.
+     408             :   std::vector<double> mfict;    ///< mass of each fictitous dynamical variable.
+     409             : 
+     410             :   double xeta;                  ///< current eta variable of thermostat.
+     411             :   double veta;                  ///< current velocity of eta variable of thermostat.
+     412             :   double meta;                  ///< mass of eta variable of thermostat.
+     413             : 
+     414             :   double phivs;                 ///< potential used in VS method
+     415             :   double work;                  ///< current works done by fictitious dynamical variables in this replica.
+     416             :   double weight;                ///< current weight of this replica.
+     417             :   double flog;                  ///< current free energy
+     418             :   double hlog;                  ///< value invariant
+     419             : 
+     420             :   struct {
+     421             :     std::vector<double>  fict;
+     422             :     std::vector<double> vfict;
+     423             :     std::vector<double> ffict;
+     424             :     double xeta;
+     425             :     double veta;
+     426             :     double phivs;
+     427             :     double work;
+     428             :     double weight;
+     429             :   } backup;
+     430             : 
+     431             :   std::vector<double> ffict;    ///< current force of each fictitous dynamical variable.
+     432             :   std::vector<double> fict_ave; ///< averaged values of each collective variable.
+     433             : 
+     434             :   std::vector<Value*>  fictValue; ///< pointers to fictitious dynamical variables
+     435             :   std::vector<Value*> vfictValue; ///< pointers to velocity of fictitious dynamical variables
+     436             : 
+     437             : public:
+     438             :   static void registerKeywords(Keywords& keys);
+     439             : 
+     440             :   explicit LogMFD(const ActionOptions&);
+     441             :   void calculate();
+     442             :   void update();
+     443             :   void updateNVE();
+     444             :   void updateNVT();
+     445             :   void updateVS();
+     446             :   void updateWork();
+     447             :   void calcMeanForce();
+     448             :   double calcEkin();
+     449             :   double calcFlog();
+     450             :   double calcClog();
+     451             : 
+     452             : private:
+     453             :   double sgn( double x ) {
+     454          55 :     return x>0.0 ? 1.0 : x<0.0 ? -1.0 : 0.0;
+     455             :   }
+     456             : };
+     457             : 
+     458       12510 : PLUMED_REGISTER_ACTION(LogMFD,"LOGMFD")
+     459             : 
+     460             : /**
+     461             :    \brief instruction of parameters for Plumed manual.
+     462             : */
+     463           5 : void LogMFD::registerKeywords(Keywords& keys) {
+     464           5 :   Bias::registerKeywords(keys);
+     465           5 :   keys.use("ARG");
+     466          10 :   keys.add("compulsory","INTERVAL",
+     467             :            "Period of MD steps (\\f$N_m\\f$) to update fictitious dynamical variables." );
+     468          10 :   keys.add("compulsory","DELTA_T",
+     469             :            "Time step for the fictitious dynamical variables (DELTA_T=1 often works)." );
+     470          10 :   keys.add("compulsory","THERMOSTAT",
+     471             :            "Type of thermostat for the fictitious dynamical variables. NVE, NVT, VS are available." );
+     472          10 :   keys.add("optional","TEMP",
+     473             :            "Target temperature for the fictitious dynamical variables in LogMFD/PD. "
+     474             :            "It is recommended to set TEMP to be the same as "
+     475             :            "the temperature of the MD system in any thermostated LogMFD/PD run. "
+     476             :            "If not provided, it will be taken from the temperature of the MD system (Gromacs only)." );
+     477             : 
+     478          10 :   keys.add("optional","TAMD",
+     479             :            "When TAMD=1, TAMD/d-AFED calculations can be performed instead of LogMFD. Otherwise, the LogMFD protocol is switched on (default)." );
+     480             : 
+     481          10 :   keys.add("optional","ALPHA",
+     482             :            "Alpha parameter for LogMFD. "
+     483             :            "If not provided or provided as 0, it will be taken as 1/gamma. "
+     484             :            "If gamma is also not provided, Alpha is set as 4, which is a sensible value when the unit of kcal/mol is used." );
+     485          10 :   keys.add("optional","GAMMA",
+     486             :            "Gamma parameter for LogMFD. "
+     487             :            "If not provided or provided as 0, it will be taken as 1/alpha. "
+     488             :            "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." );
+     489          10 :   keys.add("compulsory","KAPPA",
+     490             :            "Spring constant of the harmonic restraining potential." );
+     491             : 
+     492          10 :   keys.add("compulsory","FICT_MAX",
+     493             :            "Maximum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     494          10 :   keys.add("compulsory","FICT_MIN",
+     495             :            "Minimum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     496             : 
+     497          10 :   keys.add("optional","FICT",
+     498             :            "The initial values of the fictitious dynamical variables. "
+     499             :            "If not provided, they are set equal to their corresponding CVs for the initial atomic configuration." );
+     500          10 :   keys.add("optional","VFICT",
+     501             :            "The initial velocities of the fictitious dynamical variables. "
+     502             :            "If not provided, they will be taken as 0. "
+     503             :            "If THERMOSTAT=VS, they are instead automatically adjusted according to TEMP. "  );
+     504          10 :   keys.add("optional","MFICT",
+     505             :            "Masses of each fictitious dynamical variable. "
+     506             :            "If not provided, they will be taken as 10000." );
+     507             : 
+     508          10 :   keys.add("optional","XETA",
+     509             :            "The initial eta variable of the Nose-Hoover thermostat "
+     510             :            "for the fictitious dynamical variables. "
+     511             :            "If not provided, it will be taken as 0." );
+     512          10 :   keys.add("optional","VETA",
+     513             :            "The initial velocity of eta variable. "
+     514             :            "If not provided, it will be taken as 0." );
+     515          10 :   keys.add("optional","META",
+     516             :            "Mass of eta variable. "
+     517             :            "If not provided, it will be taken as \\f$N*kb*T*100*100\\f$." );
+     518             : 
+     519          10 :   keys.add("compulsory","FLOG",
+     520             :            "The initial free energy value in the LogMFD/PD run."
+     521             :            "The origin of the free energy profile is adjusted by FLOG to "
+     522             :            "realize \\f$F({\\bf X}(t)) > 0\\f$ at any \\f${\\bf X}(t)\\f$, "
+     523             :            "resulting in enhanced barrier-crossing. "
+     524             :            "(The value of \\f$H_{\\rm log}\\f$ is automatically "
+     525             :            "set according to FLOG). "
+     526             :            "In fact, \\f$F({\\bf X}(t))\\f$ is correctly "
+     527             :            "estimated in PLUMED even when \\f$F({\\bf X}(t)) < 0\\f$ in "
+     528             :            "the LogMFD/PD run." );
+     529             : 
+     530          10 :   keys.add("optional","WORK",
+     531             :            "The initial value of the work done by fictitious dynamical "
+     532             :            "variables in each replica. "
+     533             :            "If not provided, it will be taken as 0.");
+     534             : 
+     535          10 :   keys.add("optional","TEMPPD",
+     536             :            "Temperature of the Boltzmann factor in the Jarzynski weight in LogPD (Gromacs only). "
+     537             :            "TEMPPD should be the same as the "
+     538             :            "temperature of the MD system, while TEMP may be (in principle) different from it. "
+     539             :            "If not provided, TEMPPD is set to be the same value as TEMP." );
+     540             : 
+     541           5 :   componentsAreNotOptional(keys);
+     542          10 :   keys.addOutputComponent("_fict","default",
+     543             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     544             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, "
+     545             :                           "the associated fictitious dynamical variable can be specified as "
+     546             :                           "PRINT ARG=dist12,logmfd.dist12_fict FILE=COLVAR");
+     547          10 :   keys.addOutputComponent("_vfict","default",
+     548             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     549             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, the "
+     550             :                           "velocity of the associated fictitious dynamical variable can be specified as "
+     551             :                           "PRINT ARG=dist12,logmfd.dist12_vfict FILE=COLVAR");
+     552           5 : }
+     553             : 
+     554             : 
+     555             : /**
+     556             :    \brief constructor of LogMFD class
+     557             :    \details This constructor initializes all parameters and variables,
+     558             :    reads input file and set value of parameters and initial value of variables,
+     559             :    and writes messages as Plumed log.
+     560             : */
+     561           3 : LogMFD::LogMFD( const ActionOptions& ao ):
+     562             :   PLUMED_BIAS_INIT(ao),
+     563           3 :   firsttime(true),
+     564           3 :   step_initial(0),
+     565           3 :   interval(10),
+     566           3 :   delta_t(1.0),
+     567           6 :   thermostat("NVE"),
+     568           3 :   kbt(-1.0),
+     569           3 :   kbtpd(-1.0),
+     570           3 :   TAMD(0),
+     571           3 :   alpha(0.0),
+     572           3 :   gamma(0.0),
+     573           3 :   kappa(getNumberOfArguments(),0.0),
+     574           3 :   fict_max(getNumberOfArguments(),0.0),
+     575           3 :   fict_min(getNumberOfArguments(),0.0),
+     576           3 :   fict (getNumberOfArguments(),-999.0), // -999 means no initial values given in plumed.dat
+     577           3 :   vfict(getNumberOfArguments(),0.0),
+     578           3 :   mfict(getNumberOfArguments(),10000.0),
+     579           3 :   xeta(0.0),
+     580           3 :   veta(0.0),
+     581           3 :   meta(0.0),
+     582           3 :   flog(0.0),
+     583           3 :   hlog(0.0),
+     584           3 :   phivs(0.0),
+     585           3 :   work(0.0),
+     586           3 :   weight(0.0),
+     587           3 :   ffict(getNumberOfArguments(),0.0),
+     588           3 :   fict_ave(getNumberOfArguments(),0.0),
+     589           3 :   fictValue(getNumberOfArguments(),NULL),
+     590           9 :   vfictValue(getNumberOfArguments(),NULL)
+     591             : {
+     592           3 :   backup.fict.resize(getNumberOfArguments(),0.0);
+     593           3 :   backup.vfict.resize(getNumberOfArguments(),0.0);
+     594           3 :   backup.ffict.resize(getNumberOfArguments(),0.0);
+     595           3 :   backup.xeta = 0.0;
+     596           3 :   backup.veta = 0.0;
+     597           3 :   backup.phivs = 0.0;
+     598           3 :   backup.work = 0.0;
+     599           3 :   backup.weight = 0.0;
+     600             : 
+     601           3 :   parse("INTERVAL",interval);
+     602           3 :   parse("DELTA_T",delta_t);
+     603           3 :   parse("THERMOSTAT",thermostat);
+     604           3 :   parse("TEMP",kbt); // read as temperature
+     605           3 :   parse("TEMPPD",kbtpd); // read as temperature
+     606             : 
+     607           3 :   parse("TAMD",TAMD);
+     608           3 :   parse("ALPHA",alpha);
+     609           3 :   parse("GAMMA",gamma);
+     610           3 :   parseVector("KAPPA",kappa);
+     611             : 
+     612           3 :   parseVector("FICT_MAX",fict_max);
+     613           3 :   parseVector("FICT_MIN",fict_min);
+     614             : 
+     615           3 :   parseVector("FICT",fict);
+     616           3 :   parseVector("VFICT",vfict);
+     617           3 :   parseVector("MFICT",mfict);
+     618             : 
+     619           3 :   parse("XETA",xeta);
+     620           3 :   parse("VETA",veta);
+     621           3 :   parse("META",meta);
+     622             : 
+     623           3 :   parse("FLOG",flog);
+     624             : 
+     625             :   // read initial value of work for each replica of LogPD
+     626           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     627           0 :     vector<double> vwork(multi_sim_comm.Get_size(),0.0);
+     628           0 :     parseVector("WORK",vwork);
+     629             :     // initial work of this replica
+     630           0 :     work = vwork[multi_sim_comm.Get_rank()];
+     631             :   }
+     632             :   else {
+     633           3 :     work = 0.0;
+     634             :   }
+     635             : 
+     636           3 :   if( kbt>=0.0 ) {
+     637           3 :     kbt *= plumed.getAtoms().getKBoltzmann();
+     638             :   }
+     639             :   else {
+     640           0 :     kbt = plumed.getAtoms().getKbT();
+     641             :   }
+     642             : 
+     643           3 :   if( kbtpd>=0.0 ) {
+     644           0 :     kbtpd *= plumed.getAtoms().getKBoltzmann();
+     645             :   }
+     646             :   else {
+     647           3 :     kbtpd = kbt;
+     648             :   }
+     649             : 
+     650           3 :   if( meta == 0.0 ) {
+     651           2 :     const double nkt = getNumberOfArguments()*kbt;
+     652           2 :     meta = nkt*100.0*100.0;
+     653             :   }
+     654             : 
+     655           3 :   if(alpha == 0.0 && gamma == 0.0) {
+     656           0 :     alpha = 4.0;
+     657           0 :     gamma = 1 / alpha;
+     658             :   }
+     659           3 :   else if(alpha != 0.0 && gamma == 0.0) {
+     660           3 :     gamma = 1 / alpha;
+     661             :   }
+     662           0 :   else if(alpha == 0.0 && gamma != 0.0) {
+     663           0 :     alpha = 1 / gamma;
+     664             :   }
+     665             : 
+     666           3 :   checkRead();
+     667             : 
+     668             :   // output messaages to Plumed's log file
+     669           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     670           0 :     if( TAMD ) {
+     671           0 :       log.printf("TAMD-PD, replica parallel of TAMD, no logarithmic flattening.\n");
+     672             :     }
+     673             :     else {
+     674           0 :       log.printf("LogPD, replica parallel of LogMFD.\n");
+     675             :     }
+     676           0 :     log.printf("number of replica : %d.\n", multi_sim_comm.Get_size() );
+     677             :   }
+     678             :   else {
+     679           3 :     if( TAMD ) {
+     680           0 :       log.printf("TAMD, no logarithmic flattening.\n");
+     681             :     }
+     682             :     else {
+     683           3 :       log.printf("LogMFD, logarithmic flattening.\n");
+     684             :     }
+     685             :   }
+     686             : 
+     687           3 :   log.printf("  with harmonic force constant      ");
+     688           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     689           3 :   log.printf("\n");
+     690             : 
+     691           3 :   log.printf("  with interval of cv(ideal) update ");
+     692           3 :   log.printf(" %d", interval);
+     693           3 :   log.printf("\n");
+     694             : 
+     695           3 :   log.printf("  with time step of cv(ideal) update ");
+     696           3 :   log.printf(" %f", delta_t);
+     697           3 :   log.printf("\n");
+     698             : 
+     699           3 :   if( !TAMD ) {
+     700           3 :     log.printf("  with alpha, gamma                 ");
+     701           3 :     log.printf(" %f %f", alpha, gamma);
+     702           3 :     log.printf("\n");
+     703             :   }
+     704             : 
+     705           3 :   log.printf("  with Thermostat for cv(ideal)     ");
+     706           3 :   log.printf(" %s", thermostat.c_str());
+     707           3 :   log.printf("\n");
+     708             : 
+     709           3 :   log.printf("  with initial free energy          ");
+     710           3 :   log.printf(" %f", flog);
+     711           3 :   log.printf("\n");
+     712             : 
+     713           3 :   log.printf("  with mass of cv(ideal)");
+     714           6 :   for(unsigned i=0; i<mfict.size(); i++) log.printf(" %f", mfict[i]);
+     715           3 :   log.printf("\n");
+     716             : 
+     717           3 :   log.printf("  with initial value of cv(ideal)");
+     718           6 :   for(unsigned i=0; i<fict.size(); i++) log.printf(" %f", fict[i]);
+     719           3 :   log.printf("\n");
+     720             : 
+     721           3 :   log.printf("  with initial velocity of cv(ideal)");
+     722           6 :   for(unsigned i=0; i<vfict.size(); i++) log.printf(" %f", vfict[i]);
+     723           3 :   log.printf("\n");
+     724             : 
+     725           3 :   log.printf("  with maximum value of cv(ideal)    ");
+     726           6 :   for(unsigned i=0; i<fict_max.size(); i++) log.printf(" %f",fict_max[i]);
+     727           3 :   log.printf("\n");
+     728             : 
+     729           3 :   log.printf("  with minimum value of cv(ideal)    ");
+     730           6 :   for(unsigned i=0; i<fict_min.size(); i++) log.printf(" %f",fict_min[i]);
+     731           3 :   log.printf("\n");
+     732             : 
+     733           3 :   log.printf("  and kbt                           ");
+     734           3 :   log.printf(" %f\n",kbt);
+     735           3 :   log.printf(" kbt for PD %f\n",kbtpd);
+     736             : 
+     737             :   // setup Value* variables
+     738           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     739           3 :     std::string comp = getPntrToArgument(i)->getName()+"_fict";
+     740           3 :     addComponentWithDerivatives(comp);
+     741             : 
+     742           3 :     if(getPntrToArgument(i)->isPeriodic()) {
+     743             :       std::string a,b;
+     744           0 :       getPntrToArgument(i)->getDomain(a,b);
+     745           0 :       componentIsPeriodic(comp,a,b);
+     746             :     }
+     747             :     else {
+     748           3 :       componentIsNotPeriodic(comp);
+     749             :     }
+     750           3 :     fictValue[i] = getPntrToComponent(comp);
+     751             : 
+     752           3 :     comp = getPntrToArgument(i)->getName()+"_vfict";
+     753           3 :     addComponent(comp);
+     754             : 
+     755           3 :     componentIsNotPeriodic(comp);
+     756           3 :     vfictValue[i] = getPntrToComponent(comp);
+     757             :   }
+     758           3 : }
+     759             : 
+     760             : /**
+     761             :    \brief calculate forces for fictitious variables at every MD steps.
+     762             :    \details This function calculates initial values of fictitious variables
+     763             :    and write header messages to LogMFD log files at the first MFD step,
+     764             :    calculates restraining fources comes from difference between the fictitious variable
+     765             :    and collective variable at every MD steps.
+     766             : */
+     767        1500 : void LogMFD::calculate() {
+     768        1500 :   if( firsttime ) {
+     769           3 :     firsttime = false;
+     770             : 
+     771           3 :     step_initial = getStep();
+     772             : 
+     773             :     // set initial values of fictitious variables if they were not specified.
+     774           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     775           3 :       if( fict[i] != -999.0 ) continue; // -999 means no initial values given in plumed.dat
+     776             : 
+     777             :       // use the collective variables as the initial of the fictitious variable.
+     778           0 :       fict[i] = getArgument(i);
+     779             : 
+     780             :       // average values of fictitious variables by all replica.
+     781           0 :       if( multi_sim_comm.Get_size()>1 ) {
+     782           0 :         multi_sim_comm.Sum(fict[i]);
+     783           0 :         fict[i] /= multi_sim_comm.Get_size();
+     784             :       }
+     785             :     }
+     786             : 
+     787             :     // initialize accumulation value to zero
+     788           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     789           3 :       fict_ave[i] = 0.0;
+     790             :     }
+     791             : 
+     792             :     // calculate invariant for NVE
+     793           3 :     if(thermostat == "NVE") {
+     794             :       // kinetic energy
+     795           1 :       const double ekin = calcEkin();
+     796             :       // potential energy
+     797           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     798             :       // invariant
+     799           1 :       hlog = pot + ekin;
+     800             :     }
+     801           2 :     else if(thermostat == "NVT") {
+     802           1 :       const double nkt = getNumberOfArguments()*kbt;
+     803             :       // kinetic energy
+     804           1 :       const double ekin = calcEkin();
+     805             :       // bath energy
+     806           1 :       const double ekin_bath = 0.5*veta*veta*meta + xeta*nkt;
+     807             :       // potential energy
+     808           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     809             :       // invariant
+     810           1 :       hlog = pot + ekin + ekin_bath;
+     811             :     }
+     812           1 :     else if(thermostat == "VS") {
+     813             :       // kinetic energy
+     814           1 :       const double ekin = calcEkin();
+     815           1 :       if( ekin == 0.0 ) { // this means VFICT is not given.
+     816             :         // initial velocities
+     817           2 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     818           1 :           vfict[i] = sqrt(kbt/mfict[i]);
+     819             :         }
+     820             :       }
+     821             :       else {
+     822           0 :         const double nkt = getNumberOfArguments()*kbt;
+     823           0 :         const double svs = sqrt(nkt/ekin/2);
+     824           0 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     825           0 :           vfict[i] *= svs; // scale velocities
+     826             :         }
+     827             :       }
+     828             :       // initial VS potential
+     829           1 :       phivs = TAMD ? flog : sgn(flog)* gamma*std::log1p( alpha*fabs(flog) );
+     830             : 
+     831             :       // invariant
+     832           1 :       hlog = 0.0;
+     833             :     }
+     834             : 
+     835           3 :     weight = 1.0; // for replica parallel
+     836             : 
+     837             :     // open LogMFD's log file
+     838           3 :     if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     839           3 :       FILE *outlog = std::fopen("logmfd.out", "w");
+     840             : 
+     841             :       // output messages to LogMFD's log file
+     842           3 :       if( multi_sim_comm.Get_size()>1 ) {
+     843             :         fprintf(outlog, "# LogPD, replica parallel of LogMFD\n");
+     844           0 :         fprintf(outlog, "# number of replica : %d\n", multi_sim_comm.Get_size() );
+     845             :       }
+     846             :       else {
+     847             :         fprintf(outlog, "# LogMFD\n");
+     848             :       }
+     849             : 
+     850             :       fprintf(outlog, "# CVs :");
+     851           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     852             :         fprintf(outlog, " %s",  getPntrToArgument(i)->getName().c_str() );
+     853             :       }
+     854             :       fprintf(outlog, "\n");
+     855             : 
+     856             :       fprintf(outlog, "# Mass for CV particles :");
+     857           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     858           3 :         fprintf(outlog, "%15.6f", mfict[i]);
+     859             :       }
+     860             :       fprintf(outlog, "\n");
+     861             : 
+     862             :       fprintf(outlog, "# Mass for thermostat   :");
+     863           3 :       fprintf(outlog, "%15.6f", meta);
+     864             :       fprintf(outlog, "\n");
+     865             :       fprintf(outlog, "# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,\n");
+     866             : 
+     867           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     868           3 :         fprintf(outlog, "# %u:%s_fict(t), %u:%s_vfict(t), %u:%s_force(t),\n",
+     869             :                 6+i*3, getPntrToArgument(i)->getName().c_str(),
+     870             :                 7+i*3, getPntrToArgument(i)->getName().c_str(),
+     871           3 :                 8+i*3, getPntrToArgument(i)->getName().c_str() );
+     872             :       }
+     873           3 :       fclose(outlog);
+     874             :     }
+     875             : 
+     876           3 :     if( comm.Get_rank()==0 ) {
+     877             :       // the number of replica is added to file name to distingwish replica.
+     878           3 :       FILE *outlog2 = fopen("replica.out", "w");
+     879           6 :       fprintf(outlog2, "# Replica No. %d of %d.\n",
+     880           3 :               multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     881             : 
+     882             :       fprintf(outlog2, "# 1:iter_mfd, 2:work, 3:weight,\n");
+     883           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     884           3 :         fprintf(outlog2, "# %u:%s(q)\n",
+     885             :                 4+i, getPntrToArgument(i)->getName().c_str() );
+     886             :       }
+     887           3 :       fclose(outlog2);
+     888             :     }
+     889             : 
+     890             :     // output messages to Plumed's log file
+     891             :     //    log.printf("LOGMFD thermostat parameters Xeta Veta Meta");
+     892             :     //    log.printf(" %f %f %f", xeta, veta, meta);
+     893             :     //    log.printf("\n");
+     894             :     //    log.printf("# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,");
+     895             :     //    log.printf("# 6:X1(t), 7:V1(t), 8:F1(t), 9:X2(t), 10:V2(t), 11:F2(t), ...");
+     896             : 
+     897             :   } // firsttime
+     898             : 
+     899             :   // calculate force for fictitious variable
+     900             :   double ene=0.0;
+     901        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     902             :     // difference between fictitious variable and collective variable.
+     903        1500 :     const double diff = difference(i,fict[i],getArgument(i));
+     904             :     // restraining force.
+     905        1500 :     const double f = -kappa[i]*diff;
+     906             :     setOutputForce(i,f);
+     907             : 
+     908             :     // restraining energy.
+     909        1500 :     ene += 0.5*kappa[i]*diff*diff;
+     910             : 
+     911             :     // accumulate force, later it will be averaged.
+     912        1500 :     ffict[i] += -f;
+     913             : 
+     914             :     // accumulate varience of collective variable, later it will be averaged.
+     915        1500 :     fict_ave[i] += diff;
+     916             :   }
+     917             : 
+     918             :   setBias(ene);
+     919        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     920             :     // correct fict so that it is inside [min:max].
+     921        1500 :     double tmp = fict[i];
+     922        1500 :     fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     923        1500 :     fictValue[i]->set(fict[i]);
+     924        1500 :     vfictValue[i]->set(vfict[i]);
+     925             :   }
+     926        1500 : } // calculate
+     927             : 
+     928             : /**
+     929             :    \brief update fictitious variables.
+     930             :    \details This function manages evolution of fictitious variables.
+     931             :    This function calculates mean force, updates fictitious variables by one MFD step,
+     932             :    bounces back variables, updates free energy, and record logs.
+     933             : */
+     934        1500 : void LogMFD::update() {
+     935        1500 :   if( (getStep()-step_initial)%interval != interval-1 ) return;
+     936             : 
+     937          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     938          15 :     backup.fict[i]  =  fict[i];
+     939          15 :     backup.vfict[i] = vfict[i];
+     940             :   }
+     941          15 :   backup.xeta = xeta;
+     942          15 :   backup.veta = veta;
+     943          15 :   backup.phivs = phivs;
+     944          15 :   backup.work = work;
+     945          15 :   backup.weight = weight;
+     946             : 
+     947             :   // calc mean force for fictitious variables
+     948          15 :   calcMeanForce();
+     949             : 
+     950             :   // record log for fictitious variables
+     951          15 :   if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     952          15 :     const double ekin = calcEkin();
+     953          15 :     const double temp = 2.0*ekin/getNumberOfArguments()/plumed.getAtoms().getKBoltzmann();
+     954             : 
+     955          15 :     FILE *outlog = std::fopen("logmfd.out", "a");
+     956          15 :     fprintf(outlog, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     957          15 :     fprintf(outlog, "%15.6f", flog);
+     958             :     fprintf(outlog, "%15.6f", temp);
+     959          15 :     fprintf(outlog, "%15.6f", xeta);
+     960          15 :     fprintf(outlog, "%15.6f", veta);
+     961          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     962          15 :       fprintf(outlog, "%15.6f", fict[i]);
+     963          15 :       fprintf(outlog, "%15.6f", vfict[i]);
+     964          15 :       fprintf(outlog, "%15.6f", ffict[i]);
+     965             :     }
+     966             :     fprintf(outlog," \n");
+     967          15 :     fclose(outlog);
+     968             :   }
+     969             : 
+     970             :   // record log for collective variables
+     971          15 :   if( comm.Get_rank()==0 ) {
+     972             :     // the number of replica is added to file name to distingwish replica.
+     973          15 :     FILE *outlog2 = fopen("replica.out", "a");
+     974          15 :     fprintf(outlog2, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     975          15 :     fprintf(outlog2, "%16.6e ", work);
+     976          15 :     fprintf(outlog2, "%16.6e ", weight);
+     977          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     978          15 :       fprintf(outlog2, "%15.6f", fict_ave[i]);
+     979             :     }
+     980             :     fprintf(outlog2," \n");
+     981          15 :     fclose(outlog2);
+     982             :   }
+     983             : 
+     984             :   // update fictitious variables
+     985          15 :   if(thermostat == "NVE") {
+     986           5 :     updateNVE();
+     987             :   }
+     988          10 :   else if(thermostat == "NVT") {
+     989           5 :     updateNVT();
+     990             :   }
+     991           5 :   else if(thermostat == "VS") {
+     992           5 :     updateVS();
+     993             :   }
+     994             : 
+     995             :   // update work done by fictitious dynamical variables
+     996          15 :   updateWork();
+     997             : 
+     998             :   // check boundary
+     999             :   bool reject = false;
+    1000          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1001          15 :     if( fict[i] < fict_min[i] || fict_max[i] < fict[i] ) {
+    1002             :       reject = true;
+    1003           0 :       backup.vfict[i] *= -1.0;
+    1004             :     }
+    1005             :   }
+    1006          15 :   if( reject ) {
+    1007           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1008           0 :       fict[i] = backup.fict[i];
+    1009           0 :       vfict[i] = backup.vfict[i];
+    1010             :     }
+    1011           0 :     xeta = backup.xeta;
+    1012           0 :     veta = backup.veta;
+    1013           0 :     phivs = backup.phivs;
+    1014           0 :     work = backup.work;
+    1015           0 :     weight = backup.weight;
+    1016             :   }
+    1017             : 
+    1018             :   // update free energy
+    1019          15 :   flog = calcFlog();
+    1020             : 
+    1021             :   // reset mean force
+    1022          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1023          15 :     ffict[i] = 0.0;
+    1024          15 :     fict_ave[i] = 0.0;
+    1025             :   }
+    1026             : 
+    1027             : } // update
+    1028             : 
+    1029             : /**
+    1030             :    \brief update fictitious variables by NVE mechanics.
+    1031             :    \details This function updates ficitious variables by one NVE-MFD step using mean forces
+    1032             :    and flattening coefficient and free energy.
+    1033             :  */
+    1034           5 : void LogMFD::updateNVE() {
+    1035           5 :   const double dt = delta_t;
+    1036             : 
+    1037             :   // get latest free energy and flattening coefficient
+    1038           5 :   flog = calcFlog();
+    1039           5 :   const double clog = calcClog();
+    1040             : 
+    1041             :   // update all ficitious variables by one MFD step
+    1042          10 :   for( unsigned i=0; i<getNumberOfArguments(); ++i ) {
+    1043             :     // update velocity (full step)
+    1044           5 :     vfict[i]+=clog*ffict[i]*dt/mfict[i];
+    1045             :     // update position (full step)
+    1046             :     fict[i]+=vfict[i]*dt;
+    1047             :   }
+    1048           5 : } // updateNVE
+    1049             : 
+    1050             : /**
+    1051             :    \brief update fictitious variables by NVT mechanics.
+    1052             :    \details This function updates ficitious variables by one NVT-MFD step using mean forces
+    1053             :    and flattening coefficient and free energy.
+    1054             :  */
+    1055           5 : void LogMFD::updateNVT() {
+    1056           5 :   const double dt = delta_t;
+    1057           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1058             : 
+    1059             :   // backup vfict
+    1060          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1061           5 :     backup.vfict[i] = vfict[i];
+    1062             :   }
+    1063             : 
+    1064             :   const int niter=5;
+    1065          30 :   for(unsigned j=0; j<niter; ++j) {
+    1066             :     // get latest free energy and flattening coefficient
+    1067          25 :     flog = calcFlog();
+    1068          25 :     const double clog = calcClog();
+    1069             : 
+    1070             :     // restore vfict from backup.vfict
+    1071          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1072          25 :       vfict[i] = backup.vfict[i];
+    1073             :     }
+    1074             : 
+    1075             :     // evolve vfict from backup.vfict by dt/2
+    1076          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1077          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1078          25 :       vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1079          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1080             :     }
+    1081             :   }
+    1082             : 
+    1083             :   // get latest free energy and flattening coefficient
+    1084           5 :   flog = calcFlog();
+    1085           5 :   const double clog = calcClog();
+    1086             : 
+    1087             :   // evolve vfict by dt/2, and evolve fict by dt
+    1088          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1089           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1090           5 :     vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1091           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1092           5 :     fict[i]  += dt*vfict[i];
+    1093             :   }
+    1094             : 
+    1095             :   // evolve xeta and veta by dt
+    1096           5 :   xeta += 0.5*dt*veta;
+    1097           5 :   const double ekin = calcEkin();
+    1098           5 :   veta += dt*(2.0*ekin-nkt)/meta;
+    1099           5 :   xeta += 0.5*dt*veta;
+    1100           5 : } // updateNVT
+    1101             : 
+    1102             : /**
+    1103             :    \brief update fictitious variables by VS mechanics.
+    1104             :    \details This function updates ficitious variables by one VS-MFD step using mean forces
+    1105             :    and flattening coefficient and free energy.
+    1106             :  */
+    1107           5 : void LogMFD::updateVS() {
+    1108           5 :   const double dt = delta_t;
+    1109           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1110             : 
+    1111             :   // get latest free energy and flattening coefficient
+    1112           5 :   flog = calcFlog();
+    1113           5 :   const double clog = calcClog();
+    1114             : 
+    1115          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1116             :     // update velocity (full step)
+    1117           5 :     vfict[i] += clog*ffict[i]*dt/mfict[i];
+    1118             :   }
+    1119             : 
+    1120           5 :   const double ekin = calcEkin();
+    1121           5 :   const double svs = sqrt(nkt/ekin/2);
+    1122             : 
+    1123          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1124             :     // update position (full step)
+    1125           5 :     vfict[i] *= svs;
+    1126           5 :     fict[i] += vfict[i]*dt;
+    1127             :   }
+    1128             : 
+    1129             :   // evolve VS potential
+    1130           5 :   phivs += nkt*std::log(svs);
+    1131           5 : } // updateVS
+    1132             : 
+    1133             : /**
+    1134             :    \brief update work done by fictious variables.
+    1135             :    \details This function updates work done by ficitious variables.
+    1136             :  */
+    1137          15 : void LogMFD::updateWork() {
+    1138             :   // accumulate work, it was initialized as 0.0
+    1139          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1140          15 :     work -= backup.ffict[i] * vfict[i] * delta_t;
+    1141             :   }
+    1142          15 : } // updateWork
+    1143             : 
+    1144             : /**
+    1145             :    \brief calculate mean force for fictitious variables.
+    1146             :    \details This function calculates mean forces by averaging forces accumulated during one MFD step,
+    1147             :    update work variables done by fictitious variables by one MFD step,
+    1148             :    calculate weight variable of this replica for LogPD.
+    1149             : */
+    1150          15 : void LogMFD::calcMeanForce() {
+    1151             :   // cale temporal mean force for each CV
+    1152          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1153          15 :     ffict[i] /= interval;
+    1154             :     // backup force of replica
+    1155          15 :     backup.ffict[i] = ffict[i];
+    1156             :     // average of diff (getArgument(i)-fict[i])
+    1157          15 :     fict_ave[i] /= interval;
+    1158             :     // average of getArgument(i)
+    1159          15 :     fict_ave[i] += fict[i];
+    1160             : 
+    1161             :     // correct fict_ave so that it is inside [min:max].
+    1162          15 :     fict_ave[i] = fictValue[i]->bringBackInPbc(fict_ave[i]);
+    1163             :   }
+    1164             : 
+    1165             :   // for replica parallel
+    1166          15 :   if( multi_sim_comm.Get_size()>1 ) {
+    1167             :     // find the minimum work among all replicas
+    1168           0 :     double work_min = work;
+    1169           0 :     multi_sim_comm.Min(work_min);
+    1170             : 
+    1171             :     // weight of this replica.
+    1172             :     // here, work is reduced by work_min to avoid all exp(-work/kbt)s disconverge
+    1173           0 :     if( kbtpd == 0.0 ) {
+    1174           0 :       weight = work==work_min ? 1.0 : 0.0;
+    1175             :     }
+    1176             :     else {
+    1177           0 :       weight = exp(-(work-work_min)/kbtpd);
+    1178             :     }
+    1179             : 
+    1180             :     // normalize the weight
+    1181           0 :     double sum_weight = weight;
+    1182           0 :     multi_sim_comm.Sum(sum_weight);
+    1183           0 :     weight /= sum_weight;
+    1184             : 
+    1185             :     // weighting force of this replica
+    1186           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1187           0 :       ffict[i] *= weight;
+    1188             :     }
+    1189             : 
+    1190             :     // averaged mean forces of all replica.
+    1191           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1192           0 :       multi_sim_comm.Sum(ffict[i]);
+    1193             :     }
+    1194             :     // now, mean force is obtained.
+    1195             :   }
+    1196          15 : } // calcMeanForce
+    1197             : 
+    1198             : /**
+    1199             :    \brief calculate kinetic energy of fictitious variables.
+    1200             :    \retval kinetic energy.
+    1201             :    \details This function calculates sum of kinetic energy of all fictitious variables.
+    1202             :  */
+    1203          83 : double LogMFD::calcEkin() {
+    1204             :   double ekin=0.0;
+    1205         166 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1206          83 :     ekin += mfict[i]*vfict[i]*vfict[i]*0.5;
+    1207             :   }
+    1208          83 :   return ekin;
+    1209             : } // calcEkin
+    1210             : 
+    1211             : /**
+    1212             :    \brief calculate free energy of fictitious variables.
+    1213             :    \retval free energy.
+    1214             :    \details This function calculates free energy by using invariant of canonical mechanics.
+    1215             :  */
+    1216          55 : double LogMFD::calcFlog() {
+    1217          55 :   const double nkt = getNumberOfArguments()*kbt;
+    1218          55 :   const double ekin = calcEkin();
+    1219             :   double pot;
+    1220             : 
+    1221          55 :   if (thermostat == "NVE") {
+    1222          10 :     pot = hlog - ekin;
+    1223             :   }
+    1224          45 :   else if (thermostat == "NVT") {
+    1225          35 :     const double ekin_bath = 0.5*veta*veta*meta+xeta*nkt;
+    1226          35 :     pot = hlog - ekin - ekin_bath;
+    1227             :   }
+    1228          10 :   else if (thermostat == "VS") {
+    1229          10 :     pot = phivs;
+    1230             :   }
+    1231             :   else {
+    1232             :     pot = 0.0; // never occurs
+    1233             :   }
+    1234             : 
+    1235         110 :   return TAMD ? pot : sgn(pot)*expm1(fabs(pot)/gamma)/alpha;
+    1236             : } // calcFlog
+    1237             : 
+    1238             : /**
+    1239             :    \brief calculate coefficient for flattening.
+    1240             :    \retval flattering coefficient.
+    1241             :    \details This function returns 1.0 for TAMD, flattening coefficient for LogMFD.
+    1242             :  */
+    1243          40 : double LogMFD::calcClog() {
+    1244          40 :   return TAMD ? 1.0 : alpha*gamma/(alpha*fabs(flog)+1.0);
+    1245             : } // calcClog
+    1246             : 
+    1247             : } // logmfd
+    1248             : } // PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index-sort-f.html b/coverage/logmfd/index-sort-f.html new file mode 100644 index 0000000000..f1d1353f15 --- /dev/null +++ b/coverage/logmfd/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.6%87.6%
+
87.6 %326 / 37293.8 %15 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index-sort-l.html b/coverage/logmfd/index-sort-l.html new file mode 100644 index 0000000000..39eb6cfcd5 --- /dev/null +++ b/coverage/logmfd/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.6%87.6%
+
87.6 %326 / 37293.8 %15 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index.html b/coverage/logmfd/index.html new file mode 100644 index 0000000000..f96bcefb95 --- /dev/null +++ b/coverage/logmfd/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637287.6 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.6%87.6%
+
87.6 %326 / 37293.8 %15 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index-sort-f.html b/coverage/main/index-sort-f.html new file mode 100644 index 0000000000..83aed4d6d8 --- /dev/null +++ b/coverage/main/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/main/index-sort-l.html b/coverage/main/index-sort-l.html new file mode 100644 index 0000000000..3725710bdf --- /dev/null +++ b/coverage/main/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/main/index.html b/coverage/main/index.html new file mode 100644 index 0000000000..0954b82faa --- /dev/null +++ b/coverage/main/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/main/main.cpp.func-sort-c.html b/coverage/main/main.cpp.func-sort-c.html new file mode 100644 index 0000000000..0c88f4ce3f --- /dev/null +++ b/coverage/main/main.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main4133
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.func.html b/coverage/main/main.cpp.func.html new file mode 100644 index 0000000000..1ec152c603 --- /dev/null +++ b/coverage/main/main.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main4133
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.gcov.html b/coverage/main/main.cpp.gcov.html new file mode 100644 index 0000000000..336850c5f8 --- /dev/null +++ b/coverage/main/main.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + 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-05-27 13:05: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        4133 : int main(int argc,char**argv) {
+      37             : #ifdef __PLUMED_HAS_MPI
+      38             :   bool nompi=false;
+      39        8566 :   for(unsigned iarg=1; iarg<argc; iarg++) {
+      40        7928 :     if(!std::strcmp(argv[iarg],"--no-mpi")) nompi=true;
+      41        7928 :     if(!std::strcmp(argv[iarg],"--mpi"))    nompi=false;
+      42             : // stop at first non-option
+      43        7928 :     if(argv[iarg] && argv[iarg][0]!='-') break;
+      44             :   }
+      45        4133 :   if(!nompi) MPI_Init(&argc,&argv);
+      46             : #endif
+      47        4133 :   int ret=0;
+      48             : 
+      49             :   try {
+      50             :     PLMD::Plumed p;
+      51             :     p.cmd("CLTool setArgc",&argc);
+      52        4133 :     p.cmd("CLTool setArgv",argv);
+      53             : #ifdef __PLUMED_HAS_MPI
+      54        4133 :     if(!nompi) {
+      55             :       MPI_Comm comm;
+      56         338 :       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        4133 :   if(!nompi) MPI_Finalize();
+      69             : #endif
+      70        4133 :   return ret;
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.func-sort-c.html b/coverage/manyrestraints/LWalls.cpp.func-sort-c.html new file mode 100644 index 0000000000..bea6b56681 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71C2Ev4168
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.func.html b/coverage/manyrestraints/LWalls.cpp.func.html new file mode 100644 index 0000000000..51b2feb1f4 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:3742.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe716createERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71C2Ev4168
_ZN4PLMD14manyrestraints12_GLOBAL__N_118LWallsRegisterMe71D2Ev4168
_ZN4PLMD14manyrestraints6LWalls16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD14manyrestraints6LWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6LWalls13calcPotentialERKdRd0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.gcov.html b/coverage/manyrestraints/LWalls.cpp.gcov.html new file mode 100644 index 0000000000..782ca71e69 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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 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       12504 : PLUMED_REGISTER_ACTION(LWalls,"LWALLS")
+      72             : 
+      73           2 : void LWalls::registerKeywords( Keywords& keys ) {
+      74           2 :   ManyRestraintsBase::registerKeywords( keys );
+      75           4 :   keys.add("compulsory","AT","the radius of the sphere");
+      76           4 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      77           4 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      78           4 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      79           4 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      80           2 : }
+      81             : 
+      82           0 : LWalls::LWalls(const ActionOptions& ao):
+      83             :   Action(ao),
+      84           0 :   ManyRestraintsBase(ao)
+      85             : {
+      86           0 :   parse("AT",at);
+      87           0 :   parse("OFFSET",offset);
+      88           0 :   parse("EPS",eps);
+      89           0 :   parse("EXP",exp);
+      90           0 :   parse("KAPPA",kappa);
+      91           0 :   checkRead();
+      92           0 : }
+      93             : 
+      94           0 : double LWalls::calcPotential( const double& val, double& df ) const {
+      95           0 :   double uscale = (val - at + offset)/eps;
+      96           0 :   if( uscale < 0. ) {
+      97           0 :     double power = pow( uscale, exp );
+      98           0 :     df = ( kappa / eps ) * exp * power / uscale;
+      99             : 
+     100           0 :     return kappa*power;
+     101             :   }
+     102             : 
+     103             :   return 0.0;
+     104             : }
+     105             : 
+     106             : }
+     107             : }
+     108             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..a85b42bc52 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html new file mode 100644 index 0000000000..1ac96e591b --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html new file mode 100644 index 0000000000..f8b5275566 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05: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           6 : void ManyRestraintsBase::registerKeywords( Keywords& keys ) {
+      29           6 :   Action::registerKeywords( keys );
+      30           6 :   ActionWithValue::registerKeywords( keys );
+      31           6 :   ActionWithVessel::registerKeywords( keys );
+      32           6 :   ActionWithInputVessel::registerKeywords( keys );
+      33           6 :   ActionPilot::registerKeywords( keys );
+      34          12 :   keys.add("hidden","STRIDE","the frequency with which the forces due to the bias should be calculated.  This can be used to correctly set up multistep algorithms");
+      35           6 :   keys.remove("TOL");
+      36          12 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potentials");
+      37           6 : }
+      38             : 
+      39           2 : ManyRestraintsBase::ManyRestraintsBase(const ActionOptions& ao):
+      40             :   Action(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionPilot(ao),
+      43             :   ActionWithVessel(ao),
+      44           2 :   ActionWithInputVessel(ao)
+      45             : {
+      46             :   // Read in the vessel we are action on
+      47           2 :   readArgument("bridge");
+      48           2 :   aves=dynamic_cast<ActionWithVessel*>( getDependencies()[0] );
+      49             : 
+      50           2 :   plumed_assert( getDependencies().size()==1 && aves );
+      51           2 :   log.printf("  adding restraints on variables calculated by %s action with label %s\n",
+      52           2 :              aves->getName().c_str(),aves->getLabel().c_str());
+      53             : 
+      54             :   // Add a task list in order to avoid problems
+      55          42 :   for(unsigned i=0; i<aves->getFullNumberOfTasks(); ++i) addTaskToList( aves->getTaskCode(i) );
+      56             :   // And turn on the derivatives (note problems here because of ActionWithValue)
+      57           2 :   turnOnDerivatives(); needsDerivatives();
+      58             : 
+      59             :   // Now create the vessel
+      60           2 :   std::string fake_input="LABEL=bias";
+      61           2 :   addVessel( "SUM", fake_input, 0 );
+      62           2 :   readVesselKeywords();
+      63           2 : }
+      64             : 
+      65         740 : void ManyRestraintsBase::doJobsRequiredBeforeTaskList() {
+      66         740 :   ActionWithVessel::doJobsRequiredBeforeTaskList();
+      67         740 :   ActionWithValue::clearDerivatives();
+      68         740 : }
+      69             : 
+      70       14800 : void ManyRestraintsBase::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+      71             :   outvals.setValue( 0, invals.get(0) );
+      72             : 
+      73             :   // Get the potential
+      74       14800 :   double dval=0, val=calcPotential( invals.get(1), dval );
+      75             : 
+      76             :   outvals.setValue( 1, val );
+      77      236800 :   for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      78      222000 :     unsigned jder=invals.getActiveIndex(i);
+      79      222000 :     outvals.addDerivative( 1, jder, dval*invals.getDerivative( 1, jder ) );
+      80             :   }
+      81             : 
+      82             :   // Now update the outvals derivatives lists
+      83             :   outvals.emptyActiveMembers();
+      84      236800 :   for(unsigned j=0; j<invals.getNumberActive(); ++j) outvals.updateIndex( invals.getActiveIndex(j) );
+      85             :   outvals.completeUpdate();
+      86       14800 :   return;
+      87             : }
+      88             : 
+      89          10 : void ManyRestraintsBase::apply() {
+      90             :   plumed_dbg_assert( getNumberOfComponents()==1 );
+      91          10 :   getPntrToComponent(0)->addForce( -1.0*getStride() );
+      92          10 : }
+      93             : 
+      94             : }
+      95             : }
+      96             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html b/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html new file mode 100644 index 0000000000..a38783fae3 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.func.html b/coverage/manyrestraints/ManyRestraintsBase.h.func.html new file mode 100644 index 0000000000..c5aae9aa3e --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html new file mode 100644 index 0000000000..345b0b254d --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html @@ -0,0 +1,152 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.func-sort-c.html b/coverage/manyrestraints/UWalls.cpp.func-sort-c.html new file mode 100644 index 0000000000..71c05c1522 --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75C2Ev4168
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75D2Ev4168
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.func.html b/coverage/manyrestraints/UWalls.cpp.func.html new file mode 100644 index 0000000000..22142ff2fa --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75C2Ev4168
_ZN4PLMD14manyrestraints12_GLOBAL__N_118UWallsRegisterMe75D2Ev4168
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.gcov.html b/coverage/manyrestraints/UWalls.cpp.gcov.html new file mode 100644 index 0000000000..95b632714a --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + 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-05-27 13:05: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 UPPER_WALL 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       12508 : PLUMED_REGISTER_ACTION(UWalls,"UWALLS")
+      76             : 
+      77           4 : void UWalls::registerKeywords( Keywords& keys ) {
+      78           4 :   ManyRestraintsBase::registerKeywords( keys );
+      79           8 :   keys.add("compulsory","AT","the radius of the sphere");
+      80           8 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      81           8 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      82           8 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      83           8 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      84           4 : }
+      85             : 
+      86           2 : UWalls::UWalls(const ActionOptions& ao):
+      87             :   Action(ao),
+      88           2 :   ManyRestraintsBase(ao)
+      89             : {
+      90           2 :   parse("AT",at);
+      91           2 :   parse("OFFSET",offset);
+      92           2 :   parse("EPS",eps);
+      93           2 :   parse("EXP",exp);
+      94           2 :   parse("KAPPA",kappa);
+      95           2 :   checkRead();
+      96           2 : }
+      97             : 
+      98       14800 : double UWalls::calcPotential( const double& val, double& df ) const {
+      99       14800 :   double uscale = (val - at + offset)/eps;
+     100       14800 :   if( uscale > 0. ) {
+     101        1036 :     double power = pow( uscale, exp );
+     102        1036 :     df = ( kappa / eps ) * exp * power / uscale;
+     103             : 
+     104        1036 :     return kappa*power;
+     105             :   }
+     106             : 
+     107             :   return 0.0;
+     108             : }
+     109             : 
+     110             : }
+     111             : }
+     112             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/index-sort-f.html b/coverage/manyrestraints/index-sort-f.html new file mode 100644 index 0000000000..93ea92dd01 --- /dev/null +++ b/coverage/manyrestraints/index-sort-f.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:759281.5 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/manyrestraints/index-sort-l.html b/coverage/manyrestraints/index-sort-l.html new file mode 100644 index 0000000000..a320273ef2 --- /dev/null +++ b/coverage/manyrestraints/index-sort-l.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:759281.5 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/manyrestraints/index.html b/coverage/manyrestraints/index.html new file mode 100644 index 0000000000..414b0cbb71 --- /dev/null +++ b/coverage/manyrestraints/index.html @@ -0,0 +1,123 @@ + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:759281.5 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func-sort-c.html b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html new file mode 100644 index 0000000000..3f186e8109 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func.html b/coverage/mapping/AdaptivePath.cpp.func.html new file mode 100644 index 0000000000..e6441725eb --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe1136createERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_125AdaptivePathRegisterMe113D2Ev4168
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.gcov.html b/coverage/mapping/AdaptivePath.cpp.gcov.html new file mode 100644 index 0000000000..21042c9de0 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.gcov.html @@ -0,0 +1,335 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(AdaptivePath,"ADAPTIVE_PATH")
+     114             : 
+     115           3 : void AdaptivePath::registerKeywords( Keywords& keys ) {
+     116           3 :   Mapping::registerKeywords( keys ); keys.remove("PROPERTY");
+     117           6 :   keys.add("compulsory","FIXED","the positions in the list of input frames of the two path nodes whose positions remain fixed during the path optimization");
+     118           6 :   keys.add("compulsory","HALFLIFE","-1","the number of MD steps after which a previously measured path distance weighs only 50% in the average. This option may increase convergence by allowing to forget the memory of a bad initial guess path. The default is to set this to infinity");
+     119           6 :   keys.add("compulsory","UPDATE","the frequency with which the path should be updated");
+     120           6 :   keys.add("compulsory","TOLERANCE","1E-6","the tolerance to use for the path updating algorithm that makes all frames equidistant");
+     121           6 :   keys.add("optional","WFILE","file on which to write out the path");
+     122           6 :   keys.add("compulsory","FMT","%f","the format to use for output files");
+     123           6 :   keys.add("optional","WSTRIDE","frequency with which to write out the path");
+     124           3 : }
+     125             : 
+     126           1 : AdaptivePath::AdaptivePath(const ActionOptions& ao):
+     127             :   Action(ao),
+     128             :   Mapping(ao),
+     129           1 :   fixedn(2),
+     130           2 :   displacement(ReferenceConfigurationOptions("DIRECTION")),
+     131           3 :   displacement2(ReferenceConfigurationOptions("DIRECTION"))
+     132             : {
+     133           2 :   setLowMemOption( true ); parseVector("FIXED",fixedn);
+     134           1 :   if( fixedn[0]<1 || fixedn[1]>getNumberOfReferencePoints() ) error("fixed nodes must be in range from 0 to number of nodes");
+     135           1 :   if( fixedn[0]>=fixedn[1] ) error("invalid selection for fixed nodes first index provided must be smaller than second index");
+     136           1 :   log.printf("  fixing position of frames numbered %u and %u \n",fixedn[0],fixedn[1]);
+     137           1 :   fixedn[0]--; fixedn[1]--;   // Set fixed notes with c++ indexing starting from zero
+     138           2 :   parse("UPDATE",update_str); if( update_str<1 ) error("update frequency for path should be greater than or equal to one");
+     139           1 :   log.printf("  updating path every %u MD steps \n",update_str);
+     140             : 
+     141           1 :   double halflife; parse("HALFLIFE",halflife);
+     142           1 :   if( halflife<0 ) fadefact=1.0;
+     143             :   else {
+     144           0 :     fadefact = exp( -0.693147180559945 / static_cast<double>(halflife) );
+     145           0 :     log.printf("  weight of contribution to frame halves every %f steps \n",halflife);
+     146             :   }
+     147             : 
+     148             :   // Create the list of tasks (and reset projections of frames)
+     149           1 :   PDB mypdb; mypdb.setAtomNumbers( getAbsoluteIndexes() ); mypdb.addBlockEnd( getAbsoluteIndexes().size() );
+     150           1 :   std::vector<std::string> argument_names( getNumberOfArguments() );
+     151           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName();
+     152           1 :   if( argument_names.size()>0 ) mypdb.setArgumentNames( argument_names );
+     153           1 :   displacement.read( mypdb ); displacement2.read( mypdb );
+     154          21 :   for(int i=0; i<getNumberOfReferencePoints(); ++i) {
+     155          40 :     addTaskToList( i ); pdisplacements.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")) );
+     156          40 :     property.find("spath")->second[i] = static_cast<double>( i - static_cast<int>(fixedn[0]) ) / static_cast<double>( fixedn[1] - fixedn[0] );
+     157          20 :     pdisplacements[i].read( mypdb ); wsum.push_back( 0.0 );
+     158             :   }
+     159           2 :   plumed_assert( getPropertyValue( fixedn[0], "spath" )==0.0 && getPropertyValue( fixedn[1], "spath" )==1.0 );
+     160             :   // And activate them all
+     161           1 :   deactivateAllTasks();
+     162          21 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     163           1 :   lockContributors();
+     164             : 
+     165             :   // Setup the vessel to hold the trig path
+     166           1 :   std::string input; addVessel("GPATH", input, -1 );
+     167           1 :   readVesselKeywords();
+     168             :   // Check that there is only one vessel - the one holding the trig path
+     169             :   plumed_dbg_assert( getNumberOfVessels()==1 );
+     170             :   // Retrieve the path vessel
+     171           1 :   mypathv = dynamic_cast<TrigonometricPathVessel*>( getPntrToVessel(0) );
+     172           1 :   plumed_assert( mypathv );
+     173             : 
+     174             :   // Information for write out
+     175           2 :   std::string wfilename; parse("WFILE",wfilename);
+     176           1 :   if( wfilename.length()>0 ) {
+     177           2 :     wstride=0; parse("WSTRIDE",wstride); parse("FMT",ofmt);
+     178           1 :     pathfile.link(*this); pathfile.open( wfilename ); pathfile.setHeavyFlush();
+     179           1 :     if( wstride<update_str ) error("makes no sense to write out path more frequently than update stride");
+     180           1 :     log.printf("  writing path out every %u steps to file named %s with format %s \n",wstride,wfilename.c_str(),ofmt.c_str());
+     181             :   }
+     182           2 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+     183           1 : }
+     184             : 
+     185         101 : void AdaptivePath::calculate() {
+     186         101 :   runAllTasks();
+     187         101 : }
+     188             : 
+     189        2020 : void AdaptivePath::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     190             :   // This builds a pack to hold the derivatives
+     191        2020 :   ReferenceValuePack mypack( getNumberOfArguments(), getNumberOfAtoms(), myvals );
+     192        2020 :   finishPackSetup( current, mypack );
+     193             :   // Calculate the distance from the frame
+     194        2020 :   double val=calculateDistanceFunction( current, mypack, true );
+     195             :   // Put the element value in element zero
+     196             :   myvals.setValue( 0, val ); myvals.setValue( 1, 1.0 );
+     197        2020 :   return;
+     198        2020 : }
+     199             : 
+     200        2020 : double AdaptivePath::transformHD( const double& dist, double& df ) const {
+     201        2020 :   df=1.0; return dist;
+     202             : }
+     203             : 
+     204         101 : void AdaptivePath::update() {
+     205         101 :   double weight2 = -1.*mypathv->dx;
+     206         101 :   double weight1 = 1.0 + mypathv->dx;
+     207         101 :   if( weight1>1.0 ) {
+     208           0 :     weight1=1.0; weight2=0.0;
+     209         101 :   } else if( weight2>1.0 ) {
+     210           0 :     weight1=0.0; weight2=1.0;
+     211             :   }
+     212             :   // Add projections to dispalcement accumulators
+     213         101 :   ReferenceConfiguration* myref = getReferenceConfiguration( mypathv->iclose1 );
+     214         101 :   myref->extractDisplacementVector( getPositions(), getArguments(), mypathv->cargs, false, displacement );
+     215         101 :   getReferenceConfiguration( mypathv->iclose2 )->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), false, displacement2 );
+     216         101 :   displacement.addDirection( -mypathv->dx, displacement2 );
+     217         101 :   pdisplacements[mypathv->iclose1].addDirection( weight1, displacement );
+     218         101 :   pdisplacements[mypathv->iclose2].addDirection( weight2, displacement );
+     219             :   // Update weight accumulators
+     220         101 :   wsum[mypathv->iclose1] *= fadefact;
+     221         101 :   wsum[mypathv->iclose2] *= fadefact;
+     222         101 :   wsum[mypathv->iclose1] += weight1;
+     223         101 :   wsum[mypathv->iclose2] += weight2;
+     224             : 
+     225             :   // This does the update of the path if it is time to
+     226         101 :   if( (getStep()>0) && (getStep()%update_str==0) ) {
+     227           2 :     wsum[fixedn[0]]=wsum[fixedn[1]]=0.;
+     228          42 :     for(unsigned inode=0; inode<getNumberOfReferencePoints(); ++inode) {
+     229          40 :       if( wsum[inode]>0 ) {
+     230             :         // First displace the node by the weighted direction
+     231           6 :         getReferenceConfiguration( inode )->displaceReferenceConfiguration( 1./wsum[inode], pdisplacements[inode] );
+     232             :         // Reset the displacement
+     233           6 :         pdisplacements[inode].zeroDirection();
+     234             :       }
+     235             :     }
+     236             :     // Now ensure all the nodes of the path are equally spaced
+     237           2 :     PathReparameterization myspacings( getPbc(), getArguments(), getAllReferenceConfigurations() );
+     238           2 :     myspacings.reparameterize( fixedn[0], fixedn[1], tolerance );
+     239           2 :   }
+     240         101 :   if( (getStep()>0) && (getStep()%wstride==0) ) {
+     241           2 :     pathfile<<"# PATH AT STEP "<<getStep();
+     242           2 :     pathfile.printf(" TIME %f \n",getTime());
+     243             :     std::vector<std::unique_ptr<ReferenceConfiguration>>& myconfs=getAllReferenceConfigurations();
+     244           2 :     auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     245           2 :     std::vector<std::string> argument_names( getNumberOfArguments() );
+     246           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName();
+     247           2 :     PDB mypdb; mypdb.setArgumentNames( argument_names );
+     248          42 :     for(unsigned i=0; i<myconfs.size(); ++i) {
+     249          80 :       pathfile.printf("REMARK TYPE=%s\n", myconfs[i]->getName().c_str() );
+     250          40 :       mypdb.setAtomPositions( myconfs[i]->getReferencePositions() );
+     251         120 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) mypdb.setArgumentValue( getPntrToArgument(j)->getName(), myconfs[i]->getReferenceArgument(j) );
+     252          40 :       mypdb.print( 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.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.func-sort-c.html b/coverage/mapping/Mapping.cpp.func-sort-c.html new file mode 100644 index 0000000000..75e4ba4f6f --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZZN4PLMD7mapping7MappingC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_10
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.func.html b/coverage/mapping/Mapping.cpp.func.html new file mode 100644 index 0000000000..017e64832d --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
_ZZN4PLMD7mapping7MappingC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.gcov.html b/coverage/mapping/Mapping.cpp.gcov.html new file mode 100644 index 0000000000..a0f7a21e17 --- /dev/null +++ b/coverage/mapping/Mapping.cpp.gcov.html @@ -0,0 +1,289 @@ + + + + + + + LCOV - plumed test coverage - mapping/Mapping.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8210578.1 %
Date:2024-05-27 13:05: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             : #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          16 : void Mapping::registerKeywords( Keywords& keys ) {
+      35          16 :   Action::registerKeywords( keys );
+      36          16 :   ActionWithValue::registerKeywords( keys );
+      37          16 :   ActionWithArguments::registerKeywords( keys );
+      38          16 :   ActionAtomistic::registerKeywords( keys );
+      39          16 :   vesselbase::ActionWithVessel::registerKeywords( keys );
+      40          32 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+      41          32 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      42          32 :   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          32 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      46          16 : }
+      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             : 
+      72          10 :   FILE* fp=this->fopen(reference.c_str(),"r");
+      73          10 :   if(!fp) error("could not open reference file " + reference );
+      74             : 
+      75             :   // call fclose when exiting this block
+      76          10 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+      77             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+      78             : 
+      79             :   // Read all reference configurations
+      80             :   bool do_read=true; unsigned nfram=0; double wnorm=0., ww;
+      81         426 :   while (do_read) {
+      82             :     // Read the pdb file
+      83         852 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+      84             :     // Break if we are done
+      85         426 :     if( !do_read ) break ;
+      86             :     // Check for required properties
+      87         416 :     if( !ispath ) {
+      88             :       double prop;
+      89         378 :       for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+      90         252 :         if( !mypdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+      91         252 :         it->second.push_back(prop);
+      92             :       }
+      93             :     } else {
+      94         580 :       property.find("spath")->second.push_back( myframes.size()+1 );
+      95             :     }
+      96             :     // Fix argument names
+      97         416 :     expandArgKeywordInPDB( mypdb );
+      98             :     // And read the frame
+      99         416 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, mypdb ) );
+     100         832 :     if( !mypdb.getArgumentValue( "WEIGHT", ww ) ) ww=1.0;
+     101         416 :     weights.push_back( ww ); wnorm+=ww; nfram++;
+     102         426 :   }
+     103             : 
+     104          10 :   if(nfram==0 ) error("no reference configurations were specified");
+     105          10 :   log.printf("  found %u configurations in file %s\n",nfram,reference.c_str() );
+     106         426 :   for(unsigned i=0; i<weights.size(); ++i) weights[i] = weights[i]/wnorm;
+     107             : 
+     108             :   // Finish the setup of the mapping object
+     109             :   // Get the arguments and atoms that are required
+     110             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     111         426 :   for(unsigned i=0; i<myframes.size(); ++i) { myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     112          10 :   std::vector<Value*> req_args; interpretArgumentList( args, req_args );
+     113          10 :   if( req_args.size()>0 && atoms.size()>0 ) error("cannot mix atoms and arguments");
+     114          10 :   if( req_args.size()>0 ) requestArguments( req_args );
+     115          10 :   if( atoms.size()>0 ) {
+     116           8 :     log.printf("  found %zu atoms in input \n",atoms.size());
+     117           8 :     log.printf("  with indices : ");
+     118         112 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     119         104 :       if(i%25==0) log<<"\n";
+     120         104 :       log.printf("%d ",atoms[i].serial());
+     121             :     }
+     122           8 :     log.printf("\n");
+     123           8 :     requestAtoms( atoms );
+     124             :   }
+     125             :   // Duplicate all frames (duplicates are used by sketch-map)
+     126             :   // mymap->duplicateFrameList();
+     127             :   // fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 );
+     128             :   // plumed_assert( !mymap->mappingNeedsSetup() );
+     129             :   // Resize all derivative arrays
+     130             :   // mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() );
+     131             :   // Resize forces array
+     132          10 :   if( getNumberOfAtoms()>0 ) {
+     133           8 :     forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() );
+     134             :   } else {
+     135           2 :     forcesToApply.resize( getNumberOfArguments() );
+     136             :   }
+     137          30 : }
+     138             : 
+     139          19 : void Mapping::turnOnDerivatives() {
+     140          19 :   ActionWithValue::turnOnDerivatives();
+     141          19 :   needsDerivatives();
+     142          19 : }
+     143             : 
+     144           0 : double Mapping::getLambda() {
+     145           0 :   plumed_merror("lambda is not defined in this mapping type");
+     146             : }
+     147             : 
+     148           0 : std::string Mapping::getArgumentName( unsigned& iarg ) {
+     149           0 :   if( iarg < getNumberOfArguments() ) return getPntrToArgument(iarg)->getName();
+     150           0 :   unsigned iatom=iarg - getNumberOfArguments();
+     151           0 :   std::string atnum; Tools::convert( getAbsoluteIndex(iatom).serial(),atnum);
+     152           0 :   unsigned icomp=iatom%3;
+     153           0 :   if(icomp==0) return "pos" + atnum + "x";
+     154           0 :   if(icomp==1) return "pos" + atnum + "y";
+     155           0 :   return "pos" + atnum + "z";
+     156             : }
+     157             : 
+     158      172372 : void Mapping::finishPackSetup( const unsigned& ifunc, ReferenceValuePack& mypack ) const {
+     159             :   mypack.setValIndex(0);
+     160      172372 :   unsigned nargs2=myframes[ifunc]->getNumberOfReferenceArguments();
+     161      172372 :   unsigned nat2=myframes[ifunc]->getNumberOfReferencePositions();
+     162      172372 :   if( mypack.getNumberOfAtoms()!=nat2 || mypack.getNumberOfArguments()!=nargs2 ) mypack.resize( nargs2, nat2 );
+     163      172372 :   if( nat2>0 ) {
+     164      137592 :     ReferenceAtoms* myat2=dynamic_cast<ReferenceAtoms*>( myframes[ifunc].get() ); plumed_dbg_assert( myat2 );
+     165     1926288 :     for(unsigned i=0; i<nat2; ++i) mypack.setAtomIndex( i, myat2->getAtomIndex(i) );
+     166             :   }
+     167      172372 : }
+     168             : 
+     169      172372 : double Mapping::calculateDistanceFunction( const unsigned& ifunc, ReferenceValuePack& myder, const bool& squared ) const {
+     170             :   // Calculate the distance
+     171      172372 :   double dd = myframes[ifunc]->calculate( getPositions(), getPbc(), getArguments(), myder, squared );
+     172             :   // Transform distance by whatever
+     173      172372 :   double df, ff=transformHD( dd, df ); myder.scaleAllDerivatives( df );
+     174             :   // And the virial
+     175      172372 :   if( getNumberOfAtoms()>0 && !myder.virialWasSet() ) {
+     176      137592 :     Tensor tvir; tvir.zero();
+     177     1926288 :     for(unsigned i=0; i<myder.getNumberOfAtoms(); ++i) tvir +=-1.0*Tensor( getPosition( myder.getAtomIndex(i) ), myder.getAtomDerivative(i) );
+     178      137592 :     myder.addBoxDerivatives( tvir );
+     179             :   }
+     180      172372 :   return ff;
+     181             : }
+     182             : 
+     183       13175 : ReferenceConfiguration* Mapping::getReferenceConfiguration( const unsigned& ifunc ) {
+     184       13175 :   return myframes[ifunc].get();
+     185             : }
+     186             : 
+     187           0 : void Mapping::calculateNumericalDerivatives( ActionWithValue* a ) {
+     188           0 :   if( getNumberOfArguments()>0 ) {
+     189           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     190             :   }
+     191           0 :   if( getNumberOfAtoms()>0 ) {
+     192           0 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     193           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     194           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     195             :     }
+     196           0 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     197           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     198           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     199             :     }
+     200             :   }
+     201           0 : }
+     202             : 
+     203        5015 : void Mapping::apply() {
+     204        5015 :   if( getForcesFromVessels( forcesToApply ) ) {
+     205           0 :     addForcesOnArguments( forcesToApply );
+     206           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     207             :   }
+     208        5015 : }
+     209             : 
+     210             : }
+     211             : }
+     212             : 
+     213             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.func-sort-c.html b/coverage/mapping/Mapping.h.func-sort-c.html new file mode 100644 index 0000000000..ea6bd07604 --- /dev/null +++ b/coverage/mapping/Mapping.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.func.html b/coverage/mapping/Mapping.h.func.html new file mode 100644 index 0000000000..6fb39bd74e --- /dev/null +++ b/coverage/mapping/Mapping.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.gcov.html b/coverage/mapping/Mapping.h.gcov.html new file mode 100644 index 0000000000..4a60f4934a --- /dev/null +++ b/coverage/mapping/Mapping.h.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func-sort-c.html b/coverage/mapping/PCAVars.cpp.func-sort-c.html new file mode 100644 index 0000000000..ebaffdf48a --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe1976createERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZZN4PLMD7mapping7PCAVarsC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_5
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func.html b/coverage/mapping/PCAVars.cpp.func.html new file mode 100644 index 0000000000..00ee9efd0e --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe1976createERKNS_13ActionOptionsE5
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_120PCAVarsRegisterMe197D2Ev4168
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZZN4PLMD7mapping7PCAVarsC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.gcov.html b/coverage/mapping/PCAVars.cpp.gcov.html new file mode 100644 index 0000000000..21a309f91f --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.gcov.html @@ -0,0 +1,535 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.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 "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       12514 : PLUMED_REGISTER_ACTION(PCAVars,"PCAVARS")
+     198             : 
+     199           7 : void PCAVars::registerKeywords( Keywords& keys ) {
+     200           7 :   Action::registerKeywords( keys );
+     201           7 :   ActionWithValue::registerKeywords( keys );
+     202           7 :   ActionAtomistic::registerKeywords( keys );
+     203           7 :   ActionWithArguments::registerKeywords( keys );
+     204           7 :   componentsAreNotOptional(keys); keys.use("ARG");
+     205          14 :   keys.addOutputComponent("eig","default","the projections on each eigenvalue are stored on values labeled eig-1, eig-2, ...");
+     206          14 :   keys.addOutputComponent("residual","default","the distance of the configuration from the linear subspace defined "
+     207             :                           "by the vectors, eig-1, eig2, ... that are contained in the rows of A.");
+     208          14 :   keys.add("compulsory","REFERENCE","a pdb file containing the reference configuration and configurations that define the directions for each eigenvector");
+     209          14 :   keys.add("compulsory","TYPE","OPTIMAL","The method we are using for alignment to the reference structure");
+     210          14 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     211           7 : }
+     212             : 
+     213           5 : PCAVars::PCAVars(const ActionOptions& ao):
+     214             :   Action(ao),
+     215             :   ActionWithValue(ao),
+     216             :   ActionAtomistic(ao),
+     217             :   ActionWithArguments(ao),
+     218          10 :   myvals(1,0),
+     219           5 :   mypack(0,0,myvals),
+     220          10 :   nopbc(false)
+     221             : {
+     222             : 
+     223             :   // What type of distance are we calculating
+     224           5 :   std::string mtype; parse("TYPE",mtype);
+     225             : 
+     226          10 :   parseFlag("NOPBC",nopbc);
+     227             : 
+     228             :   // Open reference file
+     229          10 :   std::string reference; parse("REFERENCE",reference);
+     230           5 :   FILE* fp=this->fopen(reference.c_str(),"r");
+     231           5 :   if(!fp) error("could not open reference file " + reference );
+     232             : 
+     233             :   // call fclose when exiting this block
+     234           5 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+     235             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     236             : 
+     237             :   // Read all reference configurations
+     238             :   // MultiReferenceBase myframes( "", false );
+     239             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+     240             :   bool do_read=true; unsigned nfram=0;
+     241          20 :   while (do_read) {
+     242          20 :     PDB mypdb;
+     243             :     // Read the pdb file
+     244          40 :     do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     245             :     // Fix argument names
+     246          20 :     if(do_read) {
+     247          15 :       if( nfram==0 ) {
+     248          10 :         myref=metricRegister().create<ReferenceConfiguration>( mtype, mypdb );
+     249           5 :         Direction* tdir = dynamic_cast<Direction*>( myref.get() );
+     250           5 :         if( tdir ) error("first frame should be reference configuration - not direction of vector");
+     251           5 :         if( !myref->pcaIsEnabledForThisReference() ) error("can't do PCA with reference type " + mtype );
+     252             :         // std::vector<std::string> remarks( mypdb.getRemark() ); std::string rtype;
+     253             :         // bool found=Tools::parse( remarks, "TYPE", rtype );
+     254             :         // if(!found){ std::vector<std::string> newrem(1); newrem[0]="TYPE="+mtype; mypdb.addRemark(newrem); }
+     255             :         // myframes.push_back( metricRegister().create<ReferenceConfiguration>( "", mypdb ) );
+     256             :       } else {
+     257          10 :         auto mymsd = metricRegister().create<ReferenceConfiguration>( "", mypdb );
+     258          10 :         myframes.emplace_back( std::move(mymsd) );
+     259          10 :       }
+     260          15 :       nfram++;
+     261             :     } else {
+     262             :       break;
+     263             :     }
+     264          20 :   }
+     265             : 
+     266           5 :   if( nfram<=1 ) error("no eigenvectors were specified");
+     267           5 :   log.printf("  found %u eigenvectors in file %s \n",nfram-1,reference.c_str() );
+     268             : 
+     269             :   // Finish the setup of the mapping object
+     270             :   // Get the arguments and atoms that are required
+     271           5 :   std::vector<AtomNumber> atoms; myref->getAtomRequests( atoms, false );
+     272           5 :   std::vector<std::string> args; myref->getArgumentRequests( args, false );
+     273           5 :   if( atoms.size()>0 ) {
+     274           5 :     log.printf("  found %zu atoms in input \n",atoms.size());
+     275           5 :     log.printf("  with indices : ");
+     276          40 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     277          35 :       if(i%25==0) log<<"\n";
+     278          35 :       log.printf("%d ",atoms[i].serial());
+     279             :     }
+     280           5 :     log.printf("\n");
+     281             :   }
+     282           5 :   requestAtoms( atoms ); std::vector<Value*> req_args;
+     283           5 :   interpretArgumentList( args, req_args ); requestArguments( req_args );
+     284             : 
+     285             :   // And now check that the atoms/arguments are the same in all the eigenvalues
+     286          15 :   for(unsigned i=0; i<myframes.size(); ++i) { myframes[i]->getAtomRequests( atoms, false ); myframes[i]->getArgumentRequests( args, false ); }
+     287             : 
+     288             :   // Setup the derivative pack
+     289           5 :   if( atoms.size()>0 ) myvals.resize( 1, args.size() + 3*atoms.size() + 9 );
+     290           0 :   else myvals.resize( 1, args.size() );
+     291           5 :   mypack.resize( args.size(), atoms.size() );
+     292          40 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     293             :   /// This sets up all the storage data required by PCA in the pack
+     294           5 :   myref->setupPCAStorage( mypack );
+     295             : 
+     296             :   // Check there are no periodic arguments
+     297           5 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     298           0 :     if( getPntrToArgument(i)->isPeriodic() ) error("cannot use periodic variables in pca projections");
+     299             :   }
+     300             :   // Work out if the user wants to normalise the input vector
+     301           5 :   checkRead();
+     302             : 
+     303           5 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     304           4 :   else      log.printf("  using periodic boundary conditions\n");
+     305             : 
+     306             :   // Resize the matrices that will hold our eivenvectors
+     307           5 :   PDB mypdb; mypdb.setAtomNumbers( atoms ); mypdb.addBlockEnd( atoms.size() );
+     308           5 :   if( args.size()>0 ) mypdb.setArgumentNames( args );
+     309             :   // Resize the matrices that will hold our eivenvectors
+     310          15 :   for(unsigned i=0; i<myframes.size(); ++i) {
+     311          20 :     directions.push_back( Direction(ReferenceConfigurationOptions("DIRECTION"))); directions[i].read( mypdb );
+     312             :   }
+     313             : 
+     314             :   // Create fake periodic boundary condition (these would only be used for DRMSD which is not allowed)
+     315             :   // Now calculate the eigenvectors
+     316          15 :   for(unsigned i=0; i<myframes.size(); ++i) {
+     317             :     // Calculate distance from reference configuration
+     318          10 :     myframes[i]->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), true, directions[i] );
+     319             :     // Create a component to store the output
+     320          10 :     std::string num; Tools::convert( i+1, num );
+     321          30 :     addComponentWithDerivatives("eig-"+num); componentIsNotPeriodic("eig-"+num);
+     322             :   }
+     323          15 :   addComponentWithDerivatives("residual"); componentIsNotPeriodic("residual");
+     324             : 
+     325             :   // Get appropriate number of derivatives
+     326             :   unsigned nder;
+     327           5 :   if( getNumberOfAtoms()>0 ) {
+     328           5 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     329             :   } else {
+     330             :     nder = getNumberOfArguments();
+     331             :   }
+     332             : 
+     333             :   // Resize all derivative arrays
+     334           5 :   forces.resize( nder ); forcesToApply.resize( nder );
+     335          20 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     336          20 : }
+     337             : 
+     338          36 : unsigned PCAVars::getNumberOfDerivatives() {
+     339          36 :   if( getNumberOfAtoms()>0 ) {
+     340          36 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     341             :   }
+     342           0 :   return getNumberOfArguments();
+     343             : }
+     344             : 
+     345          55 : void PCAVars::lockRequests() {
+     346             :   ActionWithArguments::lockRequests();
+     347             :   ActionAtomistic::lockRequests();
+     348          55 : }
+     349             : 
+     350          55 : void PCAVars::unlockRequests() {
+     351             :   ActionWithArguments::unlockRequests();
+     352             :   ActionAtomistic::unlockRequests();
+     353          55 : }
+     354             : 
+     355          55 : void PCAVars::calculate() {
+     356             : 
+     357          55 :   if(!nopbc && getNumberOfAtoms()>0) makeWhole();
+     358             : 
+     359             :   // Clear the reference value pack
+     360          55 :   mypack.clear();
+     361             :   // Calculate distance between instaneous configuration and reference
+     362          55 :   double dist = myref->calculate( getPositions(), getPbc(), getArguments(), mypack, true );
+     363             : 
+     364             :   // Start accumulating residual by adding derivatives of distance
+     365          55 :   Value* resid=getPntrToComponent( getNumberOfComponents()-1 ); unsigned nargs=getNumberOfArguments();
+     366          55 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->addDerivative( j, mypack.getArgumentDerivative(j) );
+     367         440 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     368         385 :     Vector ader=mypack.getAtomDerivative( j );
+     369        1540 :     for(unsigned k=0; k<3; ++k) resid->addDerivative( nargs +3*j+k, ader[k] );
+     370             :   }
+     371             :   // Retrieve the values of all arguments
+     372          55 :   std::vector<double> args( getNumberOfArguments() ); for(unsigned i=0; i<getNumberOfArguments(); ++i) args[i]=getArgument(i);
+     373             : 
+     374             :   // Now calculate projections on pca vectors
+     375          55 :   Vector adif, ader; Tensor fvir, tvir;
+     376         165 :   for(int i=0; i<getNumberOfComponents()-1; ++i) { // One less component as we also have residual
+     377         110 :     double proj=myref->projectDisplacementOnVector( directions[i], getArguments(), args, mypack );
+     378             :     // And now accumulate derivatives
+     379         110 :     Value* eid=getPntrToComponent(i);
+     380         110 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) eid->addDerivative( j, mypack.getArgumentDerivative(j) );
+     381         110 :     if( getNumberOfAtoms()>0 ) {
+     382         110 :       tvir.zero();
+     383         880 :       for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     384         770 :         Vector myader=mypack.getAtomDerivative(j);
+     385        3080 :         for(unsigned k=0; k<3; ++k) {
+     386        2310 :           eid->addDerivative( nargs + 3*j+k, myader[k] );
+     387        2310 :           resid->addDerivative( nargs + 3*j+k, -2*proj*myader[k] );
+     388             :         }
+     389         770 :         tvir += -1.0*Tensor( getPosition(j), myader );
+     390             :       }
+     391         440 :       for(unsigned j=0; j<3; ++j) {
+     392        1320 :         for(unsigned k=0; k<3; ++k) eid->addDerivative( nargs + 3*getNumberOfAtoms() + 3*j + k, tvir(j,k) );
+     393             :       }
+     394             :     }
+     395         110 :     dist -= proj*proj; // Subtract square from total squared distance to get residual squared
+     396             :     // Derivatives of residual
+     397         110 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->addDerivative( j, -2*proj*eid->getDerivative(j) );
+     398             :     // for(unsigned j=0;j<getNumberOfArguments();++j) resid->addDerivative( j, -2*proj*arg_eigv(i,j) );
+     399             :     // And set final value
+     400         110 :     getPntrToComponent(i)->set( proj );
+     401             :   }
+     402          55 :   dist=std::sqrt(dist);
+     403             :   resid->set( dist );
+     404             : 
+     405             :   // Take square root of residual derivatives
+     406          55 :   double prefactor = 0.5 / dist;
+     407          55 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->setDerivative( j, prefactor*resid->getDerivative(j) );
+     408         440 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     409        1540 :     for(unsigned k=0; k<3; ++k) resid->setDerivative( nargs + 3*j+k, prefactor*resid->getDerivative( nargs+3*j+k ) );
+     410             :   }
+     411             : 
+     412             :   // And finally virial for residual
+     413          55 :   if( getNumberOfAtoms()>0 ) {
+     414          55 :     tvir.zero();
+     415         440 :     for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     416        1540 :       Vector ader; for(unsigned k=0; k<3; ++k) ader[k]=resid->getDerivative( nargs + 3*j+k );
+     417         385 :       tvir += -1.0*Tensor( getPosition(j), ader );
+     418             :     }
+     419         220 :     for(unsigned j=0; j<3; ++j) {
+     420         660 :       for(unsigned k=0; k<3; ++k) resid->addDerivative( nargs + 3*getNumberOfAtoms() + 3*j + k, tvir(j,k) );
+     421             :     }
+     422             :   }
+     423             : 
+     424          55 : }
+     425             : 
+     426           0 : void PCAVars::calculateNumericalDerivatives( ActionWithValue* a ) {
+     427           0 :   if( getNumberOfArguments()>0 ) {
+     428           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     429             :   }
+     430           0 :   if( getNumberOfAtoms()>0 ) {
+     431           0 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     432           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     433           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     434             :     }
+     435           0 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     436           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     437           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     438             :     }
+     439             :   }
+     440           0 : }
+     441             : 
+     442          55 : void PCAVars::apply() {
+     443             : 
+     444          55 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     445         220 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     446         165 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     447             :       wasforced=true;
+     448           0 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     449             :     }
+     450             :   }
+     451          55 :   if( wasforced ) {
+     452           0 :     addForcesOnArguments( forcesToApply );
+     453           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() );
+     454             :   }
+     455             : 
+     456          55 : }
+     457             : 
+     458             : }
+     459             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func-sort-c.html b/coverage/mapping/Path.cpp.func-sort-c.html new file mode 100644 index 0000000000..549eadceff --- /dev/null +++ b/coverage/mapping/Path.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func.html b/coverage/mapping/Path.cpp.func.html new file mode 100644 index 0000000000..efd7ea03bb --- /dev/null +++ b/coverage/mapping/Path.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe1396createERKNS_13ActionOptionsE6
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_117PathRegisterMe139D2Ev4168
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.gcov.html b/coverage/mapping/Path.cpp.gcov.html new file mode 100644 index 0000000000..3e03bf3ff3 --- /dev/null +++ b/coverage/mapping/Path.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + 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-05-27 13:05: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       12516 : PLUMED_REGISTER_ACTION(Path,"PATH")
+     140             : 
+     141           8 : void Path::registerKeywords( Keywords& keys ) {
+     142           8 :   PathBase::registerKeywords( keys ); keys.remove("PROPERTY");
+     143          16 :   keys.addFlag("NOSPATH",false,"do not calculate the spath position");
+     144          16 :   keys.remove("LOWMEM"); keys.use("GPATH");
+     145           8 : }
+     146             : 
+     147           6 : Path::Path(const ActionOptions& ao):
+     148             :   Action(ao),
+     149           6 :   PathBase(ao)
+     150             : {
+     151             :   setLowMemOption( true );
+     152          12 :   bool nos; parseFlag("NOSPATH",nos);
+     153             : 
+     154             :   std::string empty;
+     155           6 :   if(!nos) {
+     156           4 :     if( getLambda()==0 ) error("you must set LAMBDA parameter in order to calculate spath position.  Use LAMBDA/NOSPATH keyword");
+     157             :     empty="LABEL=spath";
+     158           8 :     addVessel("SPATH",empty,0);
+     159             :   }
+     160           6 :   readVesselKeywords();
+     161           6 :   checkRead();
+     162           6 : }
+     163             : 
+     164             : }
+     165             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.func-sort-c.html b/coverage/mapping/PathBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..ac2f6c9a75 --- /dev/null +++ b/coverage/mapping/PathBase.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.func.html b/coverage/mapping/PathBase.cpp.func.html new file mode 100644 index 0000000000..2c51b7fe65 --- /dev/null +++ b/coverage/mapping/PathBase.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.gcov.html b/coverage/mapping/PathBase.cpp.gcov.html new file mode 100644 index 0000000000..c1410f8e0b --- /dev/null +++ b/coverage/mapping/PathBase.cpp.gcov.html @@ -0,0 +1,161 @@ + + + + + + + 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-05-27 13:05: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          13 : void PathBase::registerKeywords( Keywords& keys ) {
+      29          13 :   Mapping::registerKeywords( keys );
+      30          26 :   keys.add("compulsory","LAMBDA","0","the value of the lambda parameter for paths");
+      31          26 :   keys.addFlag("NOZPATH",false,"do not calculate the zpath position");
+      32          13 : }
+      33             : 
+      34           9 : PathBase::PathBase(const ActionOptions& ao):
+      35             :   Action(ao),
+      36           9 :   Mapping(ao)
+      37             : {
+      38             :   setLowMemOption( true );
+      39           9 :   weightHasDerivatives=true;
+      40           9 :   bool noz; parseFlag("NOZPATH",noz);
+      41           9 :   parse("LAMBDA",lambda);
+      42             : 
+      43             :   // Create the list of tasks
+      44         405 :   for(unsigned i=0; i<getNumberOfReferencePoints(); ++i) addTaskToList( i );
+      45             :   // And activate them all
+      46           9 :   deactivateAllTasks();
+      47         405 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+      48           9 :   lockContributors();
+      49             : 
+      50           9 :   std::string empty="LABEL=zpath";
+      51           9 :   if(!noz) {
+      52           7 :     if( lambda==0 ) error("you must set LAMDBA value in order to calculate ZPATH coordinate.  Use LAMBDA/NOZPATH keyword");
+      53          14 :     addVessel("ZPATH",empty,0);
+      54             :   }
+      55           9 : }
+      56             : 
+      57        1103 : double PathBase::getLambda() {
+      58        1103 :   return lambda;
+      59             : }
+      60             : 
+      61        4914 : void PathBase::calculate() {
+      62             :   // Loop over all frames is now performed by ActionWithVessel
+      63        4914 :   runAllTasks();
+      64        4914 : }
+      65             : 
+      66      170352 : void PathBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+      67             :   // This builds a pack to hold the derivatives
+      68      170352 :   ReferenceValuePack mypack( getNumberOfArguments(), getNumberOfAtoms(), myvals );
+      69      170352 :   finishPackSetup( current, mypack );
+      70             :   // Calculate the distance from the frame
+      71      170352 :   double val=calculateDistanceFunction( current, mypack, true );
+      72             :   // Put the element value in element zero
+      73             :   myvals.setValue( 0, val ); myvals.setValue( 1, 1.0 );
+      74      170352 :   return;
+      75      170352 : }
+      76             : 
+      77      170352 : double PathBase::transformHD( const double& dist, double& df ) const {
+      78      170352 :   if( lambda==0 ) { df=1; return dist; }
+      79      114660 :   double val = exp( -dist*lambda );
+      80      114660 :   df = -lambda*val;
+      81      114660 :   return val;
+      82             : }
+      83             : 
+      84             : }
+      85             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func-sort-c.html b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html new file mode 100644 index 0000000000..0e562782ec --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func.html b/coverage/mapping/PathReparameterization.cpp.func.html new file mode 100644 index 0000000000..692e06e903 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.gcov.html b/coverage/mapping/PathReparameterization.cpp.gcov.html new file mode 100644 index 0000000000..f3627ed582 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func-sort-c.html b/coverage/mapping/PathTools.cpp.func-sort-c.html new file mode 100644 index 0000000000..b29abf8d75 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - mapping/PathTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312598.4 %
Date:2024-05-27 13:05: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_119PathToolsRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev4168
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func.html b/coverage/mapping/PathTools.cpp.func.html new file mode 100644 index 0000000000..e532a0611a --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - mapping/PathTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312598.4 %
Date:2024-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe1046createERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.func.html b/coverage/mapping/PropertyMap.cpp.func.html new file mode 100644 index 0000000000..f4f54a6c7d --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe1046createERKNS_13ActionOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104C2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_124PropertyMapRegisterMe104D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.gcov.html b/coverage/mapping/PropertyMap.cpp.gcov.html new file mode 100644 index 0000000000..0dd8a9d2bd --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.gcov.html @@ -0,0 +1,205 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(PropertyMap,"GPROPERTYMAP")
+     105             : 
+     106           5 : void PropertyMap::registerKeywords( Keywords& keys ) {
+     107           5 :   PathBase::registerKeywords( keys );
+     108           5 :   ActionWithValue::useCustomisableComponents( keys );
+     109          10 :   keys.addFlag("NOMAPPING",false,"do not calculate the position on the manifold");
+     110           5 : }
+     111             : 
+     112           3 : PropertyMap::PropertyMap(const ActionOptions& ao):
+     113             :   Action(ao),
+     114           3 :   PathBase(ao)
+     115             : {
+     116           6 :   bool nos; parseFlag("NOMAPPING",nos);
+     117             : 
+     118             :   std::string empty;
+     119           3 :   if(!nos) {
+     120           9 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     121          18 :       empty="LABEL="+it->first; addVessel( "SPATH", empty, 0 );
+     122             :     }
+     123             :   }
+     124           3 :   readVesselKeywords();
+     125           3 :   checkRead();
+     126           3 : }
+     127             : 
+     128             : }
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.func-sort-c.html b/coverage/mapping/SpathVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..f7098b5700 --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4168
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev4168
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.func.html b/coverage/mapping/SpathVessel.cpp.func.html new file mode 100644 index 0000000000..aeeb4cdb4d --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11SpathVessel14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD7mapping11SpathVessel16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7mapping11SpathVessel16value_descriptorB5cxx11Ev10
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZN4PLMD7mapping11SpathVesselC2ERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev4168
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.gcov.html b/coverage/mapping/SpathVessel.cpp.gcov.html new file mode 100644 index 0000000000..9beebc44f9 --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + 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-05-27 13:05: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       12514 : PLUMED_REGISTER_VESSEL(SpathVessel,"SPATH")
+      43             : 
+      44          10 : void SpathVessel::registerKeywords( Keywords& keys ) {
+      45          10 :   FunctionVessel::registerKeywords(keys);
+      46          10 : }
+      47             : 
+      48        4168 : void SpathVessel::reserveKeyword( Keywords& keys ) {
+      49        8336 :   keys.reserve("vessel","SPATH","docs should not appear");
+      50        8336 :   keys.addOutputComponent("spath","SPATH","the position on the path");
+      51        4168 : }
+      52             : 
+      53          10 : SpathVessel::SpathVessel( const vesselbase::VesselOptions& da ):
+      54             :   FunctionVessel(da),
+      55          10 :   foundoneclose(false)
+      56             : {
+      57          10 :   mymap=dynamic_cast<Mapping*>( getAction() );
+      58          10 :   plumed_massert( mymap, "SpathVessel can only be used with mappings");
+      59             :   // Retrieve the index of the property in the underlying mapping
+      60          10 :   usetol=true; norm=true;
+      61             : 
+      62         430 :   for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) {
+      63         420 :     if( mymap->getTaskCode(i)!=mymap->getPositionInFullTaskList(i) ) error("mismatched tasks and codes");
+      64             :   }
+      65          10 : }
+      66             : 
+      67          10 : std::string SpathVessel::value_descriptor() {
+      68          10 :   return "the position on the path";
+      69             : }
+      70             : 
+      71        5460 : void SpathVessel::prepare() {
+      72        5460 :   foundoneclose=false;
+      73        5460 : }
+      74             : 
+      75       27391 : void SpathVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const {
+      76       27391 :   double pp=mymap->getPropertyValue( current, getLabel() ), weight=myvals.get(0);
+      77       27391 :   if( weight<getTolerance() ) return;
+      78       27391 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      79       27391 :   buffer[bufstart] += weight*pp; buffer[bufstart+1+nderivatives] += weight;
+      80       27391 :   if( getAction()->derivativesAreRequired() ) {
+      81       23478 :     myvals.chainRule( 0, 0, 1, 0, pp, bufstart, buffer );
+      82       23478 :     myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
+      83             :   }
+      84             : }
+      85             : 
+      86             : }
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html b/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..88e5080e07 --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_133TrigonometricPathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev4168
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.func.html b/coverage/mapping/TrigonometricPathVessel.cpp.func.html new file mode 100644 index 0000000000..4e636e502e --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev4168
_ZN4PLMD7mapping23TrigonometricPathVessel10applyForceERSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel11descriptionB5cxx11Ev3
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD7mapping23TrigonometricPathVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping23TrigonometricPathVessel6finishERKSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel6resizeEv7
_ZN4PLMD7mapping23TrigonometricPathVesselC2ERKNS_10vesselbase13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html b/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html new file mode 100644 index 0000000000..1f486cd87b --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html @@ -0,0 +1,305 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_VESSEL(TrigonometricPathVessel,"GPATH")
+      30             : 
+      31           3 : void TrigonometricPathVessel::registerKeywords( Keywords& keys ) {
+      32           3 :   StoreDataVessel::registerKeywords(keys);
+      33           3 : }
+      34             : 
+      35        4168 : void TrigonometricPathVessel::reserveKeyword( Keywords& keys ) {
+      36        8336 :   keys.reserve("vessel","GPATH","calculate the position on the path using trigonometry");
+      37        8336 :   keys.addOutputComponent("gspath","GPATH","the position on the path calculated using trigonometry");
+      38        8336 :   keys.addOutputComponent("gzpath","GPATH","the distance from the path calculated using trigonometry");
+      39        4168 : }
+      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.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.func-sort-c.html b/coverage/mapping/ZpathVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..cab42523df --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev4168
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.func.html b/coverage/mapping/ZpathVessel.cpp.func.html new file mode 100644 index 0000000000..5858651df7 --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD7mapping11ZpathVessel16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping11ZpathVessel16value_descriptorB5cxx11Ev7
_ZN4PLMD7mapping11ZpathVesselC2ERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev4168
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev4168
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.gcov.html b/coverage/mapping/ZpathVessel.cpp.gcov.html new file mode 100644 index 0000000000..1940f463c2 --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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       12511 : PLUMED_REGISTER_VESSEL(ZpathVessel,"ZPATH")
+      42             : 
+      43           7 : void ZpathVessel::registerKeywords( Keywords& keys ) {
+      44           7 :   FunctionVessel::registerKeywords(keys);
+      45           7 : }
+      46             : 
+      47        4168 : void ZpathVessel::reserveKeyword( Keywords& keys ) {
+      48        8336 :   keys.reserve("vessel","ZPATH","calculate the distance from the low dimensionality manifold");
+      49        8336 :   keys.addOutputComponent("zpath","ZPATH","the distance from the path");
+      50        4168 : }
+      51             : 
+      52           7 : ZpathVessel::ZpathVessel( const vesselbase::VesselOptions& da ):
+      53           7 :   FunctionVessel(da)
+      54             : {
+      55           7 :   Mapping* mymap=dynamic_cast<Mapping*>( getAction() );
+      56           7 :   plumed_massert( mymap, "ZpathVessel should only be used with mappings");
+      57           7 :   invlambda = 1.0 / mymap->getLambda(); usetol=true;
+      58           7 : }
+      59             : 
+      60           7 : std::string ZpathVessel::value_descriptor() {
+      61           7 :   return "the distance from the low-dimensional manifold";
+      62             : }
+      63             : 
+      64       19565 : double ZpathVessel::calcTransform( const double& val, double& dv ) const {
+      65       19565 :   dv=0.0; return 1.0;
+      66             : }
+      67             : 
+      68        3822 : double ZpathVessel::finalTransform( const double& val, double& dv ) {
+      69        3822 :   dv = -invlambda / val;
+      70        3822 :   return -invlambda*std::log( val );
+      71             : }
+      72             : 
+      73             : }
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-f.html b/coverage/mapping/index-sort-f.html new file mode 100644 index 0000000000..43ebd917ef --- /dev/null +++ b/coverage/mapping/index-sort-f.html @@ -0,0 +1,203 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75880993.7 %
Date:2024-05-27 13:05:14Functions:8910089.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10566.7 %8 / 12
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
PropertyMap.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
Path.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14484.6 %11 / 13
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.4%98.4%
+
98.4 %123 / 125100.0 %7 / 7
SpathVessel.cpp +
100.0%
+
100.0 %29 / 29100.0 %9 / 9
ZpathVessel.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-l.html b/coverage/mapping/index-sort-l.html new file mode 100644 index 0000000000..dc8be2e34c --- /dev/null +++ b/coverage/mapping/index-sort-l.html @@ -0,0 +1,203 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75880993.7 %
Date:2024-05-27 13:05:14Functions:8910089.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10566.7 %8 / 12
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14484.6 %11 / 13
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.4%98.4%
+
98.4 %123 / 125100.0 %7 / 7
PropertyMap.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
Path.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.16
+
+ + + diff --git a/coverage/mapping/index.html b/coverage/mapping/index.html new file mode 100644 index 0000000000..7da37db7c6 --- /dev/null +++ b/coverage/mapping/index.html @@ -0,0 +1,203 @@ + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75880993.7 %
Date:2024-05-27 13:05:14Functions:8910089.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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 / 10566.7 %8 / 12
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
PCAVars.cpp +
88.2%88.2%
+
88.2 %127 / 14484.6 %11 / 13
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.4%98.4%
+
98.4 %123 / 125100.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.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.func-sort-c.html b/coverage/maze/Loss.cpp.func-sort-c.html new file mode 100644 index 0000000000..aa2f7f2c59 --- /dev/null +++ b/coverage/maze/Loss.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe626createERKNS_13ActionOptionsE8
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62D2Ev4168
_ZN4PLMD4maze4Loss7pairingEd14974890
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.func.html b/coverage/maze/Loss.cpp.func.html new file mode 100644 index 0000000000..1e1cb58c77 --- /dev/null +++ b/coverage/maze/Loss.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe626createERKNS_13ActionOptionsE8
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_116LossRegisterMe62D2Ev4168
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze4Loss7pairingEd14974890
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.gcov.html b/coverage/maze/Loss.cpp.gcov.html new file mode 100644 index 0000000000..4dfea7f2f5 --- /dev/null +++ b/coverage/maze/Loss.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(Loss, "MAZE_LOSS")
+      63             : 
+      64          10 : void Loss::registerKeywords(Keywords& keys) {
+      65          10 :   Colvar::registerKeywords(keys);
+      66             : 
+      67          20 :   keys.add(
+      68             :     "compulsory",
+      69             :     "PARAMS",
+      70             :     "Parameters for the loss function."
+      71             :   );
+      72          10 : }
+      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.16
+
+ + + diff --git a/coverage/maze/Loss.h.func-sort-c.html b/coverage/maze/Loss.h.func-sort-c.html new file mode 100644 index 0000000000..64dbcb3f50 --- /dev/null +++ b/coverage/maze/Loss.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.func.html b/coverage/maze/Loss.h.func.html new file mode 100644 index 0000000000..82e4f1128e --- /dev/null +++ b/coverage/maze/Loss.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.gcov.html b/coverage/maze/Loss.h.gcov.html new file mode 100644 index 0000000000..0fc5c206ad --- /dev/null +++ b/coverage/maze/Loss.h.gcov.html @@ -0,0 +1,162 @@ + + + + + + + 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-05-27 13:05: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          16 :   ~Loss() { /* Nothing to do. */ }
+      60             : 
+      61             :   /**
+      62             :    * Register PLMD keywords.
+      63             :    *
+      64             :    * @param[in] keys Keywords.
+      65             :    */
+      66             :   static void registerKeywords(Keywords& keys);
+      67             : 
+      68             :   /**
+      69             :    * Calculate a loss of a single pair of ligand-protein atoms.
+      70             :    *
+      71             :    * @param[in] distance Distance between atoms in the pair.
+      72             :    */
+      73             :   double pairing(double distance);
+      74             : 
+      75             :   // Required by the Colvar class.
+      76           0 :   void calculate() override { /* Nothing to do. */ }
+      77             : 
+      78             : protected:
+      79             :   //! Parameters of the loss function.
+      80             :   std::vector<double> params_;
+      81             : };
+      82             : 
+      83             : } // namespace maze
+      84             : } // namespace PLMD
+      85             : 
+      86             : #endif // __PLUMED_maze_Loss_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func-sort-c.html b/coverage/maze/Member.h.func-sort-c.html new file mode 100644 index 0000000000..b866ca51f0 --- /dev/null +++ b/coverage/maze/Member.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_406
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func.html b/coverage/maze/Member.h.func.html new file mode 100644 index 0000000000..75b1854aba --- /dev/null +++ b/coverage/maze/Member.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev324
_ZN4PLMD4maze7compareERNS0_6MemberES2_406
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.gcov.html b/coverage/maze/Member.h.gcov.html new file mode 100644 index 0000000000..1d49e75406 --- /dev/null +++ b/coverage/maze/Member.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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         406 : inline bool compare(Member& m, Member& n) {
+      60         406 :   return m.score > n.score;
+      61             : }
+      62             : 
+      63             : } // namespace maze
+      64             : } // namespace PLMD
+      65             : 
+      66             : #endif // __PLUMED_maze_Member_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func-sort-c.html b/coverage/maze/Memetic.cpp.func-sort-c.html new file mode 100644 index 0000000000..1e1af13367 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:6161100.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe836createERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func.html b/coverage/maze/Memetic.cpp.func.html new file mode 100644 index 0000000000..b8ed4b0364 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:6161100.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe836createERKNS_13ActionOptionsE2
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_119MemeticRegisterMe83D2Ev4168
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.gcov.html b/coverage/maze/Memetic.cpp.gcov.html new file mode 100644 index 0000000000..3c5ef17ba7 --- /dev/null +++ b/coverage/maze/Memetic.cpp.gcov.html @@ -0,0 +1,358 @@ + + + + + + + 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:6161100.0 %
Date:2024-05-27 13:05: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 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       12508 : PLUMED_REGISTER_ACTION(Memetic, "MAZE_MEMETIC_SAMPLING")
+      84             : 
+      85           4 : void Memetic::registerKeywords(Keywords& keys) {
+      86           4 :   Optimizer::registerKeywords(keys);
+      87             : 
+      88           8 :   keys.add(
+      89             :     "compulsory",
+      90             :     "CAPACITY",
+      91             :     "Sampling set size."
+      92             :   );
+      93             : 
+      94           8 :   keys.add(
+      95             :     "compulsory",
+      96             :     "MUTATION_RATE",
+      97             :     "Probability of mutation."
+      98             :   );
+      99             : 
+     100           8 :   keys.add(
+     101             :     "compulsory",
+     102             :     "MATING_RATE",
+     103             :     "Probability of mating."
+     104             :   );
+     105             : 
+     106           8 :   keys.add(
+     107             :     "compulsory",
+     108             :     "CAUCHY_ALPHA",
+     109             :     "Mean of Cauchy distribution for sampling."
+     110             :   );
+     111             : 
+     112           8 :   keys.add(
+     113             :     "compulsory",
+     114             :     "CAUCHY_BETA",
+     115             :     "Spread of Cauchy distribution for sampling."
+     116             :   );
+     117             : 
+     118           8 :   keys.addFlag(
+     119             :     "LOCAL_SEARCH_ON",
+     120             :     false,
+     121             :     "Turn local search on."
+     122             :   );
+     123             : 
+     124           8 :   keys.add(
+     125             :     "optional",
+     126             :     "N_LOCAL_ITER",
+     127             :     "Number of local search iterations."
+     128             :   );
+     129             : 
+     130           8 :   keys.add(
+     131             :     "optional",
+     132             :     "LOCAL_SEARCH_RATE",
+     133             :     "Rate of mutation in local search."
+     134             :   );
+     135             : 
+     136           8 :   keys.add(
+     137             :     "optional",
+     138             :     "LOCAL_SEARCH_TYPE",
+     139             :     "Type of local search."
+     140             :   );
+     141           4 : }
+     142             : 
+     143           2 : Memetic::Memetic(const ActionOptions& ao)
+     144             :   : PLUMED_OPT_INIT(ao),
+     145           2 :     bound_(true),
+     146           2 :     score_worst_(0),
+     147           2 :     score_best_(0),
+     148           2 :     adaptation_(true),
+     149           2 :     coding_len_(3),
+     150           2 :     local_search_on_(false)
+     151             : {
+     152           2 :   log.printf("maze> Memetic sampling.\n");
+     153             : 
+     154           4 :   if (keywords.exists("CAPACITY")) {
+     155           2 :     parse("CAPACITY", capacity_);
+     156             : 
+     157           2 :     plumed_massert(
+     158             :       capacity_ > 0,
+     159             :       "maze> CAPACITY should be explicitly specified and positive.\n"
+     160             :     );
+     161             : 
+     162           2 :     log.printf(
+     163             :       "maze> CAPACITY read: %u.\n",
+     164             :       capacity_
+     165             :     );
+     166             :   }
+     167             : 
+     168           4 :   if (keywords.exists("MUTATION_RATE")) {
+     169           2 :     parse("MUTATION_RATE", mutation_rate_);
+     170             : 
+     171           2 :     plumed_massert(
+     172             :       mutation_rate_ > 0 && mutation_rate_ <= 1,
+     173             :       "maze> MUTATION_RATE should be in [0, 1).\n"
+     174             :     );
+     175             : 
+     176           2 :     log.printf(
+     177             :       "maze> MUTATION_RATE read: %f.\n",
+     178             :       mutation_rate_
+     179             :     );
+     180             :   }
+     181             : 
+     182           4 :   if (keywords.exists("MATING_RATE")) {
+     183           2 :     parse("MATING_RATE", mating_rate_);
+     184             : 
+     185           2 :     plumed_massert(
+     186             :       mating_rate_ > 0 && mating_rate_ <= 1,
+     187             :       "maze> MATING_RATE should be in [0, 1).\n"
+     188             :     );
+     189             : 
+     190           2 :     log.printf(
+     191             :       "maze> MATING_RATE read: %f.\n",
+     192             :       mating_rate_
+     193             :     );
+     194             :   }
+     195             : 
+     196           4 :   if (keywords.exists("CAUCHY_ALPHA")) {
+     197           2 :     parse("CAUCHY_ALPHA", cauchy_mean_alpha_);
+     198             : 
+     199           2 :     log.printf(
+     200             :       "maze> CAUCHY_ALPHA read: %f.\n",
+     201             :       cauchy_mean_alpha_
+     202             :     );
+     203             :   }
+     204             : 
+     205           4 :   if (keywords.exists("CAUCHY_BETA")) {
+     206           2 :     parse("CAUCHY_BETA", cauchy_mean_beta_);
+     207             : 
+     208           2 :     plumed_massert(
+     209             :       cauchy_mean_beta_ > 0,
+     210             :       "maze> CAUCHY_BETA should be explicitly specified and positive.\n"
+     211             :     );
+     212             : 
+     213           2 :     log.printf(
+     214             :       "maze> CAUCHY_BETA read: %f.\n",
+     215             :       cauchy_mean_beta_
+     216             :     );
+     217             :   }
+     218             : 
+     219           4 :   if (keywords.exists("LOCAL_SEARCH_ON")) {
+     220           2 :     parseFlag("LOCAL_SEARCH_ON", local_search_on_);
+     221             : 
+     222           2 :     log.printf("maze> LOCAL_SEARCH_ON enabled: %d.\n", local_search_on_);
+     223             :   }
+     224             : 
+     225           2 :   if (local_search_on_) {
+     226           1 :     parse("N_LOCAL_ITER", n_local_iterations_);
+     227             : 
+     228           1 :     plumed_massert(
+     229             :       n_local_iterations_ > 0,
+     230             :       "maze> N_LOCAL_ITER should be explicitly specified and positive.\n"
+     231             :     );
+     232             : 
+     233           1 :     log.printf(
+     234             :       "maze> N_LOCAL_ITER read: %u.\n",
+     235             :       n_local_iterations_
+     236             :     );
+     237             : 
+     238           1 :     parse("LOCAL_SEARCH_RATE", local_search_rate_);
+     239             : 
+     240           1 :     plumed_massert(
+     241             :       local_search_rate_ > 0 && local_search_rate_ <= 1,
+     242             :       "maze> LOCAL_SEARCH_RATE should be in [0, 1).\n"
+     243             :     );
+     244             : 
+     245           1 :     log.printf(
+     246             :       "maze> LOCAL_SEARCH_RATE read: %f.\n",
+     247             :       local_search_rate_
+     248             :     );
+     249             : 
+     250           2 :     parse("LOCAL_SEARCH_TYPE", local_search_type_);
+     251             : 
+     252           1 :     plumed_massert(
+     253             :       local_search_type_ == "stochastic_hill_climbing" ||
+     254             :       local_search_type_ == "adaptive_random_search",
+     255             :       "maze> LOCAL_SEARCH_TYPE should be: "
+     256             :       "stochastic_hill_climbing, or adaptive_random_search.\n"
+     257             :     );
+     258             : 
+     259           1 :     log.printf(
+     260             :       "maze> LOCAL_SEARCH_TYPE read: %s.\n",
+     261             :       local_search_type_.c_str()
+     262             :     );
+     263             :   }
+     264             : 
+     265           2 :   set_n_global_iterations(n_iter_);
+     266             : 
+     267           4 :   set_label("MEMETIC_SAMPLING");
+     268             : 
+     269             :   start_step_0();
+     270             : 
+     271           2 :   checkRead();
+     272           2 : }
+     273             : 
+     274           6 : void Memetic::optimize() {
+     275           6 :   Vector t = solve();
+     276             : 
+     277             :   set_opt(t);
+     278           6 :   set_opt_value(score());
+     279           6 : }
+     280             : 
+     281             : } // namespace maze
+     282             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.func-sort-c.html b/coverage/maze/Memetic.h.func-sort-c.html new file mode 100644 index 0000000000..2b7f253fb4 --- /dev/null +++ b/coverage/maze/Memetic.h.func-sort-c.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-05-27 13:05:14Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic10score_meanEv0
_ZN4PLMD4maze7Memetic12luus_jaakolaERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic9annealingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZNK4PLMD4maze7Memetic12print_statusEv0
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_1
_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
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE77
_ZN4PLMD4maze7Memetic13out_of_boundsEd79
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE250
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.func.html b/coverage/maze/Memetic.h.func.html new file mode 100644 index 0000000000..777c4c6ac0 --- /dev/null +++ b/coverage/maze/Memetic.h.func.html @@ -0,0 +1,152 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-05-27 13:05:14Functions:142070.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_6MemberE77
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic9annealingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_1
_ZNK4PLMD4maze7Memetic12print_statusEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.gcov.html b/coverage/maze/Memetic.h.gcov.html new file mode 100644 index 0000000000..d351322773 --- /dev/null +++ b/coverage/maze/Memetic.h.gcov.html @@ -0,0 +1,882 @@ + + + + + + + LCOV - plumed test coverage - maze/Memetic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-05-27 13:05:14Functions:142070.0 %
+
+ + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer15sampling_radiusEv328
_ZNK4PLMD4maze9Optimizer7pairingEd14974890
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.func.html b/coverage/maze/Optimizer.cpp.func.html new file mode 100644 index 0000000000..9edd770e98 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.func.html b/coverage/maze/Optimizer.h.func.html new file mode 100644 index 0000000000..e27fa71278 --- /dev/null +++ b/coverage/maze/Optimizer.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

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

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe1986createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_126OptimizerBiasRegisterMe198D2Ev4168
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze13OptimizerBias9calculateEv30
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.gcov.html b/coverage/maze/Optimizer_Bias.cpp.gcov.html new file mode 100644 index 0000000000..8f31aad229 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.gcov.html @@ -0,0 +1,510 @@ + + + + + + + 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-05-27 13:05: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 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             : \ref MAZE_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       12506 : PLUMED_REGISTER_ACTION(OptimizerBias, "MAZE_OPTIMIZER_BIAS")
+     199             : 
+     200           3 : void OptimizerBias::registerKeywords(Keywords& keys) {
+     201           3 :   Bias::registerKeywords(keys);
+     202             : 
+     203           3 :   keys.use("ARG");
+     204             : 
+     205           6 :   keys.add(
+     206             :     "compulsory",
+     207             :     "BIASING_RATE",
+     208             :     "Biasing rate."
+     209             :   );
+     210             : 
+     211           6 :   keys.add(
+     212             :     "compulsory",
+     213             :     "ALPHA",
+     214             :     "Rescaled force constant."
+     215             :   );
+     216             : 
+     217           6 :   keys.add(
+     218             :     "compulsory",
+     219             :     "OPTIMIZER",
+     220             :     "Optimization technique to minimize the collective variable for ligand\
+     221             :      unbinding: RANDOM_WALK,\
+     222             :                 STEERED_MD,\
+     223             :                 RANDOM_ACCELERATION_MD,\
+     224             :                 SIMULATED_ANNEALING,\
+     225             :                 MEMETIC_SAMPLING"
+     226             :   );
+     227             : 
+     228           3 :   componentsAreNotOptional(keys);
+     229             : 
+     230           6 :   keys.addOutputComponent(
+     231             :     "force2",
+     232             :     "default",
+     233             :     "Square of the biasing force."
+     234             :   );
+     235             : 
+     236           6 :   keys.addOutputComponent(
+     237             :     "x",
+     238             :     "default",
+     239             :     "Optimal biasing direction: x component."
+     240             :   );
+     241             : 
+     242           6 :   keys.addOutputComponent(
+     243             :     "y",
+     244             :     "default",
+     245             :     "Optimal biasing direction: y component."
+     246             :   );
+     247             : 
+     248           6 :   keys.addOutputComponent(
+     249             :     "z",
+     250             :     "default",
+     251             :     "Optimal biasing direction: z component."
+     252             :   );
+     253             : 
+     254           6 :   keys.addOutputComponent(
+     255             :     "tdist",
+     256             :     "default",
+     257             :     "Total distance traveled by biased atoms."
+     258             :   );
+     259           3 : }
+     260             : 
+     261           1 : OptimizerBias::OptimizerBias(const ActionOptions& ao)
+     262             :   : PLUMED_BIAS_INIT(ao),
+     263           1 :     bias_(0.0),
+     264           1 :     force_(0.0),
+     265           1 :     total_distance_(0.0)
+     266             : {
+     267           1 :   log.printf(
+     268             :     "maze> You are using the maze module of PLUMED2,\
+     269             :     please read and cite "
+     270             :   );
+     271             : 
+     272           2 :   log << plumed.cite("Rydzewski J. and Valsson O., arXiv:1808.08089, 2018");
+     273           1 :   log.printf("\n");
+     274             : 
+     275           1 :   args_ = getArguments();
+     276           1 :   log.printf(
+     277             :     "maze> Number of args %zu\n",
+     278             :     args_.size()
+     279             :   );
+     280             : 
+     281           1 :   if (!args_.empty()) {
+     282           1 :     log.printf("maze> With arguments");
+     283           4 :     for (unsigned i = 0; i < args_.size(); i++) {
+     284           3 :       log.printf(" %s", args_[i]->getName().c_str());
+     285             :     }
+     286           1 :     log.printf("\n");
+     287             :   }
+     288             : 
+     289           2 :   if (keywords.exists("ALPHA")) {
+     290           1 :     parse("ALPHA", alpha_);
+     291             : 
+     292           1 :     plumed_massert(
+     293             :       alpha_>0,
+     294             :       "maze> ALPHA should be explicitly specified and positive.\n"
+     295             :     );
+     296             : 
+     297           1 :     log.printf(
+     298             :       "maze> ALPHA read: %f [kcal/mol/A].\n",
+     299             :       alpha_
+     300             :     );
+     301             :   }
+     302             : 
+     303           2 :   if (keywords.exists("BIASING_RATE")) {
+     304           1 :     parse("BIASING_RATE", biasing_speed_);
+     305             : 
+     306           1 :     plumed_massert(
+     307             :       biasing_speed_>0,
+     308             :       "maze> BIASING_RATE should be explicitly specified and positive.\n"
+     309             :     );
+     310             : 
+     311           1 :     log.printf(
+     312             :       "maze> BIASING_RATE read: %f [A/ps].\n",
+     313             :       biasing_speed_
+     314             :     );
+     315             :   }
+     316             : 
+     317           2 :   if (keywords.exists("OPTIMIZER")) {
+     318           1 :     std::vector<std::string> opt_labels(0);
+     319           2 :     parseVector("OPTIMIZER", opt_labels);
+     320             : 
+     321           1 :     plumed_massert(
+     322             :       opt_labels.size() > 0,
+     323             :       "maze> Problem with OPTIMIZER keyword.\n"
+     324             :     );
+     325             : 
+     326           1 :     std::string error_msg = "";
+     327           2 :     opt_pntrs_ = tls::get_pointers_labels<Optimizer*>(
+     328             :                    opt_labels,
+     329           1 :                    plumed.getActionSet(),
+     330             :                    error_msg
+     331             :                  );
+     332             : 
+     333           1 :     if (error_msg.size() > 0) {
+     334           0 :       plumed_merror(
+     335             :         "maze> Error in keyword OPTIMIZER of " + getName() + ": " + error_msg
+     336             :       );
+     337             :     }
+     338             : 
+     339           1 :     optimizer_ = opt_pntrs_[0];
+     340           1 :     log.printf(
+     341             :       "maze> Optimizer linked: %s.\n",
+     342           0 :       optimizer_->get_label().c_str()
+     343             :     );
+     344             : 
+     345           1 :     biasing_stride_=optimizer_->get_optimizer_stride();
+     346           1 :   }
+     347             : 
+     348           1 :   checkRead();
+     349             : 
+     350           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.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html new file mode 100644 index 0000000000..e38becbf37 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:404295.2 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe1126createERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe112C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe112D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func.html b/coverage/maze/Random_Acceleration_MD.cpp.func.html new file mode 100644 index 0000000000..57efec53a8 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:404295.2 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe1126createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe112C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_135Random_Acceleration_MDRegisterMe112D2Ev4168
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.gcov.html b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html new file mode 100644 index 0000000000..dc09373e2c --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + 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:404295.2 %
Date:2024-05-27 13:05: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 Random_Acceleration_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_ACCELERATION_MD
+      36             : /*
+      37             : 
+      38             : Performs random acceleration MD within the protein matrix.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : Every optimizer implemented in the maze module needs a loss function as
+      43             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      44             : 
+      45             : \plumedfile
+      46             : MAZE_RANDOM_ACCELERATION_MD ...
+      47             :   LABEL=rw
+      48             : 
+      49             :   OPTIMIZER_STRIDE=_
+      50             :   LOSS=l
+      51             :   RMIN=_
+      52             : 
+      53             :   LIGAND=2635-2646
+      54             :   PROTEIN=1-2634
+      55             : ... MAZE_RANDOM_ACCELERATION_MD
+      56             : \endplumedfile
+      57             : 
+      58             : As shown above, each optimizer should be provided with the LIGAND and
+      59             : the PROTEIN keywords.
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : /**
+      65             :  * @class Random_Acceleration_MD Random_Acceleration_MD.cpp
+      66             :  *  "maze/Random_Acceleration_MD.cpp"
+      67             :  *
+      68             :  * @brief Perform RAMD simulation.
+      69             :  */
+      70             : class Random_Acceleration_MD: public Optimizer {
+      71             : public:
+      72             :   /**
+      73             :    * PLMD constructor.
+      74             :    *
+      75             :    * @param[in] ao PLMD::ActionOptions&
+      76             :    */
+      77             :   explicit Random_Acceleration_MD(const ActionOptions&);
+      78             : 
+      79             :   /**
+      80             :    * Registers PLMD keywords.
+      81             :    *
+      82             :    * @param[in] keys PLMD keywords
+      83             :    */
+      84             :   static void registerKeywords(Keywords&);
+      85             : 
+      86             :   /**
+      87             :    * Each class deriving from Optimizer needs to override this function.
+      88             :    */
+      89             :   void optimize() override;
+      90             : 
+      91             : private:
+      92             :   //! Threshold distance that the ligand needs to pass.
+      93             :   double r_min_;
+      94             : 
+      95             :   //! Total distance.
+      96             :   double total_dist_;
+      97             : 
+      98             :   //! Distance.
+      99             :   double dist_;
+     100             : 
+     101             :   //! Ligand center of mass.
+     102             :   Vector com_;
+     103             : 
+     104             :   //! PLMD value for distance.
+     105             :   Value* value_dist_;
+     106             : 
+     107             :   //! PLMD value for total distance.
+     108             :   Value* value_total_dist_;
+     109             : };
+     110             : 
+     111             : // Register MAZE_RANDOM_ACCELERATION_MD.
+     112       12506 : PLUMED_REGISTER_ACTION(Random_Acceleration_MD, "MAZE_RANDOM_ACCELERATION_MD")
+     113             : 
+     114           3 : void Random_Acceleration_MD::registerKeywords(Keywords& keys) {
+     115           3 :   Optimizer::registerKeywords(keys);
+     116             : 
+     117           3 :   keys.remove("N_ITER");
+     118             : 
+     119           6 :   keys.add(
+     120             :     "compulsory",
+     121             :     "R_MIN",
+     122             :     "Minimal distance traveled before sampling a new direction of biasing."
+     123             :   );
+     124             : 
+     125           6 :   keys.addOutputComponent(
+     126             :     "dist",
+     127             :     "default",
+     128             :     "Distance traveled in one sampling interval."
+     129             :   );
+     130             : 
+     131           6 :   keys.addOutputComponent(
+     132             :     "tdist",
+     133             :     "default",
+     134             :     "Total distance traveled by biased atoms."
+     135             :   );
+     136           3 : }
+     137             : 
+     138           1 : Random_Acceleration_MD::Random_Acceleration_MD(const ActionOptions& ao)
+     139             :   : PLUMED_OPT_INIT(ao),
+     140           1 :     total_dist_(0.0),
+     141           1 :     dist_(0.0) {
+     142           1 :   log.printf("maze> Random accelerated molecular dynamics.\n");
+     143             : 
+     144           2 :   if(keywords.exists("R_MIN")) {
+     145           1 :     parse("R_MIN", r_min_);
+     146             : 
+     147           1 :     plumed_massert(
+     148             :       r_min_ > 0,
+     149             :       "maze> R_MIN should be explicitly specified and positive.\n"
+     150             :     );
+     151             : 
+     152           1 :     log.printf(
+     153             :       "maze> R_MIN read: %f [A].\n",
+     154             :       r_min_
+     155             :     );
+     156             :   }
+     157             : 
+     158           1 :   set_label("RANDOM_ACCELERATION_MD");
+     159           1 :   set_opt(rnd::next_plmd_vector());
+     160             :   set_opt_value(0.0);
+     161             : 
+     162             :   start_step_stride();
+     163             : 
+     164           1 :   checkRead();
+     165             : 
+     166           1 :   com_ = center_of_mass();
+     167             : 
+     168           1 :   addComponent("dist");
+     169           1 :   componentIsNotPeriodic("dist");
+     170           1 :   value_dist_ = getPntrToComponent("dist");
+     171             : 
+     172           1 :   addComponent("tdist");
+     173           1 :   componentIsNotPeriodic("tdist");
+     174           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     175           1 : }
+     176             : 
+     177           2 : void Random_Acceleration_MD::optimize() {
+     178           2 :   Vector c = center_of_mass();
+     179           2 :   Vector d;
+     180             : 
+     181           2 :   if (pbc_) {
+     182           2 :     d = pbcDistance(c, com_);
+     183             :   }
+     184             :   else {
+     185           0 :     d = delta(c, com_);
+     186             :   }
+     187             : 
+     188           2 :   dist_ = d.modulo();
+     189           2 :   total_dist_ += dist_;
+     190             : 
+     191           2 :   if(dist_ < r_min_) {
+     192           0 :     set_opt(rnd::next_plmd_vector());
+     193             :   }
+     194             : 
+     195           2 :   set_opt_value(score());
+     196           2 :   com_ = c;
+     197             : 
+     198           2 :   value_dist_->set(dist_);
+     199           2 :   value_total_dist_->set(total_dist_);
+     200           2 : }
+     201             : 
+     202             : } // namespace maze
+     203             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func-sort-c.html b/coverage/maze/Random_MT.cpp.func-sort-c.html new file mode 100644 index 0000000000..63e22f3a87 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd8next_intEii1
_ZN4PLMD4maze3rnd11next_cauchyEdd77
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd8next_intEi311
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1178
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func.html b/coverage/maze/Random_MT.cpp.func.html new file mode 100644 index 0000000000..dce8a228dc --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_cauchyEdd77
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1178
_ZN4PLMD4maze3rnd8next_intEi311
_ZN4PLMD4maze3rnd8next_intEii1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.gcov.html b/coverage/maze/Random_MT.cpp.gcov.html new file mode 100644 index 0000000000..680afddbf9 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_MT.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  *
+      28             :  * @brief Dummy cpp file.
+      29             :  */
+      30             : 
+      31             : #include "Random_MT.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36        1178 : std::mt19937_64& rnd::mt_eng() {
+      37        1185 :   static std::mt19937_64 mt{};
+      38             : 
+      39        1178 :   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         311 : int rnd::next_int(int e) {
+      59         311 :   static std::uniform_int_distribution<int> dist_int(0, e-1);
+      60         311 :   std::uniform_int_distribution<int>::param_type p(0, e-1);
+      61             :   dist_int.param(p);
+      62             : 
+      63         311 :   return dist_int(mt_eng());
+      64             : }
+      65             : 
+      66           1 : int rnd::next_int(int f, int e) {
+      67           1 :   static std::uniform_int_distribution<int> dist_int(f, e-1);
+      68           1 :   std::uniform_int_distribution<int>::param_type p(f, e-1);
+      69             :   dist_int.param(p);
+      70             : 
+      71           1 :   return dist_int(mt_eng());
+      72             : }
+      73             : 
+      74          77 : double rnd::next_cauchy(double m, double s) {
+      75          77 :   static std::cauchy_distribution<double> dist_cauchy(m, s);
+      76             : 
+      77          77 :   return dist_cauchy(mt_eng());
+      78             : }
+      79             : 
+      80             : } // namespace maze
+      81             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func-sort-c.html b/coverage/maze/Random_MT.h.func-sort-c.html new file mode 100644 index 0000000000..de3299059e --- /dev/null +++ b/coverage/maze/Random_MT.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func.html b/coverage/maze/Random_MT.h.func.html new file mode 100644 index 0000000000..a17b91bad5 --- /dev/null +++ b/coverage/maze/Random_MT.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.gcov.html b/coverage/maze/Random_MT.h.gcov.html new file mode 100644 index 0000000000..7a5813879a --- /dev/null +++ b/coverage/maze/Random_MT.h.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func-sort-c.html b/coverage/maze/Random_Walk.cpp.func-sort-c.html new file mode 100644 index 0000000000..61bfdb815b --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:1515100.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe976createERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe97C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func.html b/coverage/maze/Random_Walk.cpp.func.html new file mode 100644 index 0000000000..c0fea293bc --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:1515100.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe976createERKNS_13ActionOptionsE2
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe97C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_123Random_WalkRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.gcov.html b/coverage/maze/Random_Walk.cpp.gcov.html new file mode 100644 index 0000000000..6fb59a8ba7 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + 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:1515100.0 %
Date:2024-05-27 13:05: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 Random_Walk.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_WALK
+      36             : /*
+      37             : 
+      38             : Fake optimizer that can be used for debugging.
+      39             : 
+      40             : This is dummy optimizer that can be used for debugging and monitoring
+      41             : purposes. It returns a random direction of biasing, changed every
+      42             : OPTIMIZER_STRIDE.
+      43             : 
+      44             : Performs a random walk within the protein matrix.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : Every optimizer implemented in the maze module needs a loss function as
+      49             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      50             : 
+      51             : \plumedfile
+      52             : MAZE_RANDOM_WALK ...
+      53             :   LABEL=rw
+      54             : 
+      55             :   LOSS=l
+      56             :   OPTIMIZER_STRIDE=200
+      57             : 
+      58             :   LIGAND=2635-2646
+      59             :   PROTEIN=1-2634
+      60             : ... MAZE_RANDOM_WALK
+      61             : \endplumedfile
+      62             : 
+      63             : As shown above, each optimizer should be provided with the LIGAND and
+      64             : the PROTEIN keywords.
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : /**
+      70             :  * @class Random_Walk Random_Walk.cpp "maze/Random_Walk.cpp"
+      71             :  *
+      72             :  * @brief Perform a random walk within the protein matrix.
+      73             :  */
+      74             : class Random_Walk: public Optimizer {
+      75             : public:
+      76             :   /**
+      77             :    * PLMD constructor.
+      78             :    *
+      79             :    * @param[in] ao PLMD::ActionOptions&
+      80             :    */
+      81             :   explicit Random_Walk(const ActionOptions& ao);
+      82             : 
+      83             :   /**
+      84             :    * Registers PLMD keywords.
+      85             :    *
+      86             :    * @param[in] keys PLMD keywords
+      87             :    */
+      88             :   static void registerKeywords(Keywords&);
+      89             : 
+      90             :   /**
+      91             :    * Each class deriving from Optimizer needs to override this function.
+      92             :    */
+      93             :   void optimize() override;
+      94             : };
+      95             : 
+      96             : // Register MAZE_RANDOM_WALK.
+      97       12508 : PLUMED_REGISTER_ACTION(Random_Walk, "MAZE_RANDOM_WALK")
+      98             : 
+      99           4 : void Random_Walk::registerKeywords(Keywords& keys) {
+     100           4 :   Optimizer::registerKeywords(keys);
+     101             : 
+     102           4 :   keys.remove("N_ITER");
+     103           4 : }
+     104             : 
+     105           2 : Random_Walk::Random_Walk(const ActionOptions& ao)
+     106           2 :   : PLUMED_OPT_INIT(ao)
+     107             : {
+     108           2 :   log.printf("maze> Fake optimizer that returns a next step as random,\
+     109             :     can be used to monitor loss, and for debugging and regtests purposes.\n");
+     110             : 
+     111           4 :   set_label("RANDOM_WALK");
+     112             : 
+     113             :   start_step_0();
+     114             : 
+     115           2 :   checkRead();
+     116           2 : }
+     117             : 
+     118           6 : void Random_Walk::optimize() {
+     119           6 :   set_opt(rnd::next_plmd_vector());
+     120           6 :   set_opt_value(score());
+     121           6 : }
+     122             : 
+     123             : } // namespace maze
+     124             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html new file mode 100644 index 0000000000..41add3311c --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:445088.0 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe1206createERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe120C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe120D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func.html b/coverage/maze/Simulated_Annealing.cpp.func.html new file mode 100644 index 0000000000..adc105d038 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:445088.0 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe1206createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe120C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_132Simulated_AnnealingRegisterMe120D2Ev4168
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.gcov.html b/coverage/maze/Simulated_Annealing.cpp.gcov.html new file mode 100644 index 0000000000..dee3b533a2 --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.gcov.html @@ -0,0 +1,351 @@ + + + + + + + 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:445088.0 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Simulated_Annealing.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_SIMULATED_ANNEALING
+      36             : /*
+      37             : 
+      38             : Calculates the biasing direction along which the ligand unbinds by minimizing
+      39             : the \ref MAZE_LOSS function. The optimal biasing direction is determined by
+      40             : performing simulated annealing.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : Every optimizer implemented in the maze module needs a loss function as an
+      45             : argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      46             : 
+      47             : In the following example simulated annealing is launched for 1000 iterations
+      48             : as the optimizer for the loss function every 200 ps. The geometric cooling
+      49             : scheme is used.
+      50             : 
+      51             : \plumedfile
+      52             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      53             : 
+      54             : MAZE_SIMULATED_ANNEALING ...
+      55             :   LABEL=sa
+      56             : 
+      57             :   LOSS=l
+      58             : 
+      59             :   N_ITER=1000
+      60             :   OPTIMIZER_STRIDE=200
+      61             : 
+      62             :   PROBABILITY_DECREASER=300
+      63             :   COOLING=0.95
+      64             :   COOLING_TYPE=geometric
+      65             : 
+      66             :   LIGAND=2635-2646
+      67             :   PROTEIN=1-2634
+      68             : ... MAZE_SIMULATED_ANNEALING
+      69             : \endplumedfile
+      70             : 
+      71             : As shown above, each optimizer should be provided with the LIGAND and
+      72             : the PROTEIN keywords.
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : /**
+      78             :  * @class Simulated_Annealing Simulated_Annealing.cpp "maze/Simulated_Annealing.cpp"
+      79             :  *
+      80             :  * @brief Perform simulated annealing to compute an optimal bias direction.
+      81             :  */
+      82             : class Simulated_Annealing: public Optimizer {
+      83             : public:
+      84             :   /**
+      85             :    * PLMD constructor.
+      86             :    *
+      87             :    * @param[in] ao PLMD::ActionOptions&.
+      88             :    */
+      89             :   explicit Simulated_Annealing(const ActionOptions& ao);
+      90             : 
+      91             :   /**
+      92             :    * Register PLMD keywords.
+      93             :    *
+      94             :    * @param[in] keys Keywords.
+      95             :    */
+      96             :   static void registerKeywords(Keywords& keys);
+      97             : 
+      98             :   /**
+      99             :    * Each class deriving from Optimizer needs to override this function.
+     100             :    */
+     101             :   void optimize() override;
+     102             : 
+     103             :   /**
+     104             :    * Reduce the temperature parameter.
+     105             :    */
+     106             :   void decrease_probability(unsigned int);
+     107             : 
+     108             : private:
+     109             :   //! Temperature parameter.
+     110             :   double probability_decreaser_;
+     111             : 
+     112             :   //! Cooling factor.
+     113             :   double cooling_factor_;
+     114             : 
+     115             :   //! Cooling scheme.
+     116             :   std::string cooling_scheme_;
+     117             : };
+     118             : 
+     119             : // Register MAZE_SIMULATED_ANNEALING.
+     120       12506 : PLUMED_REGISTER_ACTION(Simulated_Annealing, "MAZE_SIMULATED_ANNEALING")
+     121             : 
+     122           3 : void Simulated_Annealing::registerKeywords(Keywords& keys) {
+     123           3 :   Optimizer::registerKeywords(keys);
+     124             : 
+     125           6 :   keys.add(
+     126             :     "compulsory",
+     127             :     "PROBABILITY_DECREASER",
+     128             :     "Temperature-like parameter that is decreased during optimization to modify "
+     129             :     "the Metropolis-Hastings acceptance probability."
+     130             :   );
+     131             : 
+     132           6 :   keys.add(
+     133             :     "compulsory",
+     134             :     "COOLING",
+     135             :     "Reduction factor for PROBABILITY_DECREASER, should be in (0, 1]."
+     136             :   );
+     137             : 
+     138           6 :   keys.add(
+     139             :     "compulsory",
+     140             :     "COOLING_SCHEME",
+     141             :     "Cooling scheme: geometric."
+     142             :   );
+     143           3 : }
+     144             : 
+     145           1 : Simulated_Annealing::Simulated_Annealing(const ActionOptions& ao)
+     146           1 :   : PLUMED_OPT_INIT(ao)
+     147             : {
+     148           1 :   log.printf("maze> Simulated annealing optimizer.\n");
+     149             : 
+     150           2 :   if(keywords.exists("COOLING")) {
+     151           1 :     parse("COOLING", cooling_factor_);
+     152             : 
+     153           1 :     plumed_massert(
+     154             :       cooling_factor_ > 0 && cooling_factor_ <= 1,
+     155             :       "maze> COOLING should be in (0, 1]; preferably 0.95.\n"
+     156             :     );
+     157             :   }
+     158             : 
+     159           2 :   if(keywords.exists("PROBABILITY_DECREASER")) {
+     160           1 :     parse("PROBABILITY_DECREASER", probability_decreaser_);
+     161             : 
+     162           1 :     plumed_massert(
+     163             :       probability_decreaser_ > 0,
+     164             :       "maze> PROBABILITY_DECREASER should be explicitly specified and positive.\n");
+     165             :   }
+     166             : 
+     167           2 :   if(keywords.exists("COOLING_SCHEME")) {
+     168           1 :     parse("COOLING_SCHEME", cooling_scheme_);
+     169             : 
+     170           1 :     log.printf(
+     171             :       "maze> COOLING_SCHEME read: %s.\n",
+     172             :       cooling_scheme_.c_str()
+     173             :     );
+     174             :   }
+     175             : 
+     176           2 :   set_label("SIMULATED_ANNEALING");
+     177             : 
+     178             :   // Calculate an optimal direction at the beginning of the MD simulation.
+     179             :   start_step_0();
+     180             : 
+     181           1 :   checkRead();
+     182           1 : }
+     183             : 
+     184          30 : void Simulated_Annealing::decrease_probability(unsigned int time) {
+     185          30 :   if (cooling_scheme_ == "linear") {
+     186           0 :     probability_decreaser_ -= time * cooling_factor_;
+     187             :   }
+     188          30 :   else if (cooling_scheme_ == "exponential") {
+     189           0 :     probability_decreaser_ *= pow(cooling_factor_, time);
+     190             :   }
+     191          30 :   else if (cooling_scheme_ == "geometric") {
+     192          30 :     probability_decreaser_ *= cooling_factor_;
+     193             :   }
+     194           0 :   else if (cooling_scheme_ == "logarithmic") {
+     195           0 :     probability_decreaser_ = cooling_factor_ / std::log(time + 1);
+     196             :   }
+     197           0 :   else if (cooling_scheme_ == "hoffman") {
+     198           0 :     probability_decreaser_ = (cooling_factor_ - 1) / std::log(time);
+     199             :   }
+     200          30 : }
+     201             : 
+     202           3 : void Simulated_Annealing::optimize() {
+     203           3 :   sampling_r_ = sampling_radius();
+     204             :   double rad_s;
+     205           3 :   const unsigned nl_size = neighbor_list_->size();
+     206             : 
+     207           3 :   Vector distance, distance_next;
+     208             : 
+     209          33 :   for (unsigned int iter=0; iter < get_n_iterations(); ++iter) {
+     210             :     double action = 0;
+     211             :     double action_next = 0;
+     212             : 
+     213          30 :     rad_s = rnd::next_double(sampling_r_);
+     214          30 :     Vector dev = rnd::next_plmd_vector(rad_s);
+     215             : 
+     216          30 :     #pragma omp parallel num_threads(get_n_threads_openmp())
+     217             :     {
+     218             :       #pragma omp for reduction(+:action_next, action)
+     219             :       for (unsigned int i=0; i < nl_size; i++) {
+     220             :         unsigned i0 = neighbor_list_->getClosePair(i).first;
+     221             :         unsigned i1 = neighbor_list_->getClosePair(i).second;
+     222             : 
+     223             :         if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     224             :           continue;
+     225             :         }
+     226             : 
+     227             :         if (pbc_) {
+     228             :           distance = pbcDistance(
+     229             :                        getPosition(i0) + get_opt(),
+     230             :                        getPosition(i1)
+     231             :                      );
+     232             : 
+     233             :           distance_next = pbcDistance(
+     234             :                             getPosition(i0) + dev,
+     235             :                             getPosition(i1)
+     236             :                           );
+     237             :         }
+     238             :         else {
+     239             :           distance = delta(
+     240             :                        getPosition(i0) + get_opt(),
+     241             :                        getPosition(i1)
+     242             :                      );
+     243             : 
+     244             :           distance_next = delta(
+     245             :                             getPosition(i0) + dev,
+     246             :                             getPosition(i1)
+     247             :                           );
+     248             :         }
+     249             : 
+     250             :         action += pairing(distance.modulo());
+     251             :         action_next += pairing(distance_next.modulo());
+     252             :       }
+     253             :     }
+     254             : 
+     255             :     double p = std::min(
+     256          60 :                  1.0,
+     257          30 :                  std::exp(-(action_next - action) / probability_decreaser_)
+     258          30 :                );
+     259             : 
+     260          30 :     double r = rnd::next_double();
+     261             : 
+     262          30 :     if (r < p) {
+     263             :       set_opt(dev);
+     264             :       set_opt_value(action_next);
+     265             :     }
+     266             : 
+     267          30 :     decrease_probability(iter);
+     268             :   }
+     269             : 
+     270           3 :   Vector s = get_opt() / modulo(get_opt());
+     271             :   set_opt(s);
+     272           3 : }
+     273             : 
+     274             : } // namespace maze
+     275             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func-sort-c.html b/coverage/maze/Steered_MD.cpp.func-sort-c.html new file mode 100644 index 0000000000..ffef30546b --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:323397.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe1056createERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe105C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe105D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func.html b/coverage/maze/Steered_MD.cpp.func.html new file mode 100644 index 0000000000..5fe02fffa3 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:323397.0 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe1056createERKNS_13ActionOptionsE1
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe105C2Ev4168
_ZN4PLMD4maze12_GLOBAL__N_123Steered_MDRegisterMe105D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.gcov.html b/coverage/maze/Steered_MD.cpp.gcov.html new file mode 100644 index 0000000000..d10f7939c1 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + 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:323397.0 %
Date:2024-05-27 13:05: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 Steered_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_STEERED_MD
+      36             : /*
+      37             : 
+      38             : Performs a linear unbinding along a predefined biasing direction that
+      39             : needs to be provided using the PULLING keyword.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : Every optimizer implemented in the maze module needs a loss function as
+      44             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      45             : 
+      46             : \plumedfile
+      47             : MAZE_STEERED_MD ...
+      48             :   LABEL=smd
+      49             : 
+      50             :   LOSS=l
+      51             :   PULLING=0.3,0.3,0.3
+      52             :   OPTIMIZER_STRIDE=_
+      53             : 
+      54             :   LIGAND=2635-2646
+      55             :   PROTEIN=1-2634
+      56             : ... MAZE_STEERED_MD
+      57             : \endplumedfile
+      58             : 
+      59             : As shown above, each optimizer should be provided with the LIGAND and
+      60             : the PROTEIN keywords.
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : /**
+      66             :  * @class Steered_MD Steered_MD.cpp "maze/Steered_MD.cpp"
+      67             :  * @brief Performs steered MD simulation.
+      68             :  */
+      69             : class Steered_MD: public Optimizer {
+      70             : public:
+      71             :   /**
+      72             :    * PLMD constructor.
+      73             :    *
+      74             :    * @param[in] ao PLMD::ActionOptions&
+      75             :    */
+      76             :   explicit Steered_MD(const ActionOptions& ao);
+      77             : 
+      78             :   /**
+      79             :    * Registers PLMD keywords.
+      80             :    *
+      81             :    * @param[in] keys PLMD keywords
+      82             :    */
+      83             :   static void registerKeywords(Keywords&);
+      84             : 
+      85             :   /**
+      86             :    * Each class deriving from Optimizer needs to override this function.
+      87             :    */
+      88             :   void optimize() override;
+      89             : 
+      90             : private:
+      91             :   //! Total distance traveled by the ligand.
+      92             :   double total_dist_;
+      93             : 
+      94             :   //! Ligand center of mass.
+      95             :   Vector com_;
+      96             : 
+      97             :   //! Constant direction of biasing.
+      98             :   Vector pulling_;
+      99             : 
+     100             :   //! PLMD::Value of total distance.
+     101             :   Value* value_total_dist_;
+     102             : };
+     103             : 
+     104             : // Register MAZE_STEERED_MD.
+     105       12506 : PLUMED_REGISTER_ACTION(Steered_MD, "MAZE_STEERED_MD")
+     106             : 
+     107           3 : void Steered_MD::registerKeywords(Keywords& keys) {
+     108           3 :   Optimizer::registerKeywords(keys);
+     109             : 
+     110           3 :   keys.remove("N_ITER");
+     111             : 
+     112           6 :   keys.add(
+     113             :     "compulsory",
+     114             :     "PULLING",
+     115             :     "Constant biasing direction."
+     116             :   );
+     117             : 
+     118           6 :   keys.addOutputComponent(
+     119             :     "tdist",
+     120             :     "default",
+     121             :     "Total distance traveled by biased atoms."
+     122             :   );
+     123           3 : }
+     124             : 
+     125           1 : Steered_MD::Steered_MD(const ActionOptions& ao)
+     126             :   : PLUMED_OPT_INIT(ao),
+     127           1 :     total_dist_(0.0)
+     128             : {
+     129           1 :   log.printf("maze> Steered MD.\n");
+     130             : 
+     131           2 :   if (keywords.exists("PULLING")) {
+     132             :     std::vector<double> v;
+     133           1 :     parseVector("PULLING", v);
+     134           1 :     pulling_ = tls::vector2Vector(v);
+     135             : 
+     136           1 :     log.printf("maze> PULLING read.\n");
+     137             :   }
+     138             : 
+     139           2 :   set_label("STEERED_MD");
+     140             :   set_opt(pulling_);
+     141             :   set_opt_value(0.0);
+     142             : 
+     143             :   start_step_stride();
+     144             : 
+     145           1 :   checkRead();
+     146             : 
+     147           1 :   com_ = center_of_mass();
+     148             : 
+     149           1 :   addComponent("tdist");
+     150           1 :   componentIsNotPeriodic("tdist");
+     151           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     152           1 : }
+     153             : 
+     154           2 : void Steered_MD::optimize() {
+     155           2 :   Vector c = center_of_mass();
+     156           2 :   Vector d;
+     157             : 
+     158           2 :   if (pbc_) {
+     159           2 :     d = pbcDistance(c, com_);
+     160             :   }
+     161             :   else {
+     162           0 :     d = delta(c, com_);
+     163             :   }
+     164             : 
+     165           2 :   double dist = d.modulo();
+     166           2 :   total_dist_ += dist;
+     167             : 
+     168             :   set_opt(pulling_);
+     169           2 :   set_opt_value(score());
+     170           2 :   com_ = c;
+     171             : 
+     172           2 :   value_total_dist_->set(total_dist_);
+     173           2 : }
+     174             : 
+     175             : } // namespace maze
+     176             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.func-sort-c.html b/coverage/maze/Tools.h.func-sort-c.html new file mode 100644 index 0000000000..70d52a6738 --- /dev/null +++ b/coverage/maze/Tools.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/Tools.h.func.html b/coverage/maze/Tools.h.func.html new file mode 100644 index 0000000000..ac72101ebb --- /dev/null +++ b/coverage/maze/Tools.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/Tools.h.gcov.html b/coverage/maze/Tools.h.gcov.html new file mode 100644 index 0000000000..09bcf14647 --- /dev/null +++ b/coverage/maze/Tools.h.gcov.html @@ -0,0 +1,256 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/maze/index-sort-f.html b/coverage/maze/index-sort-f.html new file mode 100644 index 0000000000..9c1828bcc5 --- /dev/null +++ b/coverage/maze/index-sort-f.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:66177585.3 %
Date:2024-05-27 13:05:14Functions:8610284.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 +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_Acceleration_MD.cpp +
95.2%95.2%
+
95.2 %40 / 4285.7 %6 / 7
Steered_MD.cpp +
97.0%97.0%
+
97.0 %32 / 3385.7 %6 / 7
Random_Walk.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
Memetic.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
Loss.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
Simulated_Annealing.cpp +
88.0%88.0%
+
88.0 %44 / 5087.5 %7 / 8
Optimizer_Bias.cpp +
98.0%98.0%
+
98.0 %96 / 9888.9 %8 / 9
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index-sort-l.html b/coverage/maze/index-sort-l.html new file mode 100644 index 0000000000..4269484ecb --- /dev/null +++ b/coverage/maze/index-sort-l.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:66177585.3 %
Date:2024-05-27 13:05:14Functions:8610284.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 +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Simulated_Annealing.cpp +
88.0%88.0%
+
88.0 %44 / 5087.5 %7 / 8
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_Acceleration_MD.cpp +
95.2%95.2%
+
95.2 %40 / 4285.7 %6 / 7
Steered_MD.cpp +
97.0%97.0%
+
97.0 %32 / 3385.7 %6 / 7
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 %13 / 13100.0 %1 / 1
Random_Walk.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Loss.cpp +
100.0%
+
100.0 %24 / 2485.7 %6 / 7
Memetic.cpp +
100.0%
+
100.0 %61 / 6185.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index.html b/coverage/maze/index.html new file mode 100644 index 0000000000..277165b109 --- /dev/null +++ b/coverage/maze/index.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:66177585.3 %
Date:2024-05-27 13:05:14Functions:8610284.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 %61 / 6185.7 %6 / 7
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Optimizer_Bias.cpp +
98.0%98.0%
+
98.0 %96 / 9888.9 %8 / 9
Random_Acceleration_MD.cpp +
95.2%95.2%
+
95.2 %40 / 4285.7 %6 / 7
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %15 / 1585.7 %6 / 7
Simulated_Annealing.cpp +
88.0%88.0%
+
88.0 %44 / 5087.5 %7 / 8
Steered_MD.cpp +
97.0%97.0%
+
97.0 %32 / 3385.7 %6 / 7
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html new file mode 100644 index 0000000000..cc319d68da --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13815887.3 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe85C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe85D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html new file mode 100644 index 0000000000..e9bd40349a --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13815887.3 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe85C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_132fusionPoreExpansionPRegisterMe85D2Ev4168
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html new file mode 100644 index 0000000000..1ce6cf7b7a --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html @@ -0,0 +1,681 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13815887.3 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR FUSIONPOREEXPANSIONP
+      35             : /*
+      36             : A CV for inducing the expansion of a fusion pore from a nucleated fusion pore.
+      37             : 
+      38             : Calculate the collective variable designed by Hub \cite Hub2021  and implemented into PLUMED by Masone and collaborators.
+      39             : This CV is capable of inducing the expansion of the fusion pore from a nucleated fusion pore.
+      40             : 
+      41             : \f[
+      42             : \xi_e = \frac{R(r) - R_0}{R_0}
+      43             : \f]
+      44             : 
+      45             : Where \f$\xi_e\f$ is the CV, \f$R_0\f$ is a normalization constant that makes zero the initial value of \f$\xi_e\f$, and
+      46             : \f$R(r)\f$ is the approximate radius of the fusion pore, which is defined by the number of waters and phosphateoxygens
+      47             : beads within a horizontal layer in the center of both membranes.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : This example induces the expansion of a nucleated fusion pore (\f$\xi_e = 0.75\f$) from a just nucleated fusion pore (\f$\xi_e = 0.00\f$).
+      52             : 
+      53             : \plumedfile
+      54             : lMem: GROUP ATOMS=1-10752,21505-22728,23953-24420 #All the lower membrane beads.
+      55             : uMem: GROUP ATOMS=10753-21504,22729-23952,24421-24888 #All the upper membrane beads.
+      56             : tails: GROUP ATOMS=8-23948:12,12-23952:12,23966-24884:18,23970-24888:18 #All the lipid tails beads (from the lower and upper membrane).
+      57             : waters: GROUP ATOMS=24889-56589  #All the water beads.
+      58             : po4: GROUP ATOMS=2-23942:12,23957-24875:18 #All the lipid phosphateoxygens beads.
+      59             : 
+      60             : fusionPoreExpansion: FUSIONPOREEXPANSIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails WATERS=waters PHOSPHATEOXYGENS=po4 NSMEM=85 D=7.0 R0=0.57
+      61             : 
+      62             : MOVINGRESTRAINT ...
+      63             :     ARG=fusionPoreExpansion
+      64             :     STEP0=0 AT0=0.0 KAPPA0=10000.0
+      65             :     STEP1=500000 AT1=0.75 KAPPA1=10000.0
+      66             : ...
+      67             : 
+      68             : PRINT ARG=fusionPoreExpansion FILE=COLVAR STRIDE=1
+      69             : 
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : class fusionPoreExpansionP : public Colvar
+      75             : {
+      76             :   std::vector<AtomNumber> UMEM, LMEM, TAILS, WATERS, POXYGENS;
+      77             :   std::vector<double> NSMEM, DSMEM, HMEM, VO, D, H, RMAX, R0, XCYL, YCYL;
+      78             : 
+      79             : public:
+      80             :   explicit fusionPoreExpansionP(const ActionOptions &);
+      81             :   void calculate() override;
+      82             :   static void registerKeywords(Keywords &keys);
+      83             : };
+      84             : 
+      85       12506 : PLUMED_REGISTER_ACTION(fusionPoreExpansionP, "FUSIONPOREEXPANSIONP")
+      86             : 
+      87           3 : void fusionPoreExpansionP::registerKeywords(Keywords &keys)
+      88             : {
+      89           3 :   Colvar::registerKeywords(keys);
+      90           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane.");
+      91           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane.");
+      92           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system.");
+      93           6 :   keys.add("atoms", "WATERS", "all the water beads of the system.");
+      94           6 :   keys.add("atoms", "PHOSPHATEOXYGENS", "all the lipid phosphateoxygens beads of the system.");
+      95           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder.");
+      96           6 :   keys.add("optional", "DSMEM", "( default=0.1 ) thickness of the slices of the membrane fusion cylinder.");
+      97           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+      98           6 :   keys.add("optional", "VO", "( default=0.076879 ) beads' molecular volume.");
+      99           6 :   keys.add("compulsory", "D", "horizontal layer thickness, it depends on the Z separation of the membranes.");
+     100           6 :   keys.add("optional", "H", "( default=0.1 ) parameter of the step function θ(x,h) for the fusion pore expansion.");
+     101           6 :   keys.add("optional", "RMAX", "( default=2.5 ) to avoid effects of membrane undulations in large membranes (more than 256 lipids).");
+     102           6 :   keys.add("compulsory", "R0", "normalization constant that makes 0 the initial value of the CV.");
+     103           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     104           6 :   keys.add("optional", "YCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     105           3 : }
+     106             : 
+     107           1 : fusionPoreExpansionP::fusionPoreExpansionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     108             : {
+     109           2 :   parseAtomList("UMEMBRANE", UMEM);
+     110           1 :   if (UMEM.size() == 0)
+     111           0 :     error("UMEMBRANE has not any atom specified.");
+     112             : 
+     113           2 :   parseAtomList("LMEMBRANE", LMEM);
+     114           1 :   if (LMEM.size() == 0)
+     115           0 :     error("LMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("TAILS", TAILS);
+     118           1 :   if (TAILS.size() == 0)
+     119           0 :     error("TAILS has not any atom specified.");
+     120             : 
+     121           2 :   parseAtomList("WATERS", WATERS);
+     122           1 :   if (WATERS.size() == 0)
+     123           0 :     error("WATERS has not any atom specified.");
+     124             : 
+     125           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     126           1 :   if (POXYGENS.size() == 0)
+     127           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     128             : 
+     129           2 :   parseVector("NSMEM", NSMEM);
+     130           1 :   if (NSMEM.size() > 1)
+     131           0 :     error("NSMEM cannot take more than one value.");
+     132             : 
+     133           2 :   parseVector("DSMEM", DSMEM);
+     134           1 :   if (DSMEM.size() > 1)
+     135           0 :     error("DSMEM cannot take more than one value.");
+     136           1 :   if (DSMEM.size() == 0)
+     137           0 :     DSMEM.push_back(0.1);
+     138             : 
+     139           2 :   parseVector("HMEM", HMEM);
+     140           1 :   if (HMEM.size() > 1)
+     141           0 :     error("HMEM cannot take more than one value.");
+     142           1 :   if (HMEM.size() == 0)
+     143           0 :     HMEM.push_back(0.25);
+     144             : 
+     145           2 :   parseVector("VO", VO);
+     146           1 :   if (VO.size() > 1)
+     147           0 :     error("VO cannot take more than one value.");
+     148           1 :   if (VO.size() == 0)
+     149           0 :     VO.push_back(0.076879);
+     150             : 
+     151           2 :   parseVector("D", D);
+     152           1 :   if (D.size() > 1)
+     153           0 :     error("D cannot take more than one value.");
+     154             : 
+     155           2 :   parseVector("H", H);
+     156           1 :   if (H.size() > 1)
+     157           0 :     error("H cannot take more than one value.");
+     158           1 :   if (H.size() == 0)
+     159           0 :     H.push_back(0.1);
+     160             : 
+     161           2 :   parseVector("RMAX", RMAX);
+     162           1 :   if (RMAX.size() > 1)
+     163           0 :     error("RMAX cannot take more than one value.");
+     164           1 :   if (RMAX.size() == 0)
+     165           0 :     RMAX.push_back(2.5);
+     166             : 
+     167           2 :   parseVector("R0", R0);
+     168           1 :   if (R0.size() > 1)
+     169           0 :     error("R0 cannot take more than one value.");
+     170             : 
+     171           2 :   parseVector("XCYL", XCYL);
+     172           1 :   if (XCYL.size() > 1)
+     173           0 :     error("XCYL cannot take more than one value.");
+     174           1 :   if (XCYL.size() == 0)
+     175           1 :     XCYL.push_back(-1.0);
+     176             : 
+     177           2 :   parseVector("YCYL", YCYL);
+     178           1 :   if (YCYL.size() > 1)
+     179           0 :     error("YCYL cannot take more than one value.");
+     180           1 :   if (YCYL.size() == 0)
+     181           1 :     YCYL.push_back(-1.0);
+     182             : 
+     183           1 :   checkRead();
+     184             : 
+     185             :   std::vector<AtomNumber> atoms;
+     186       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     187             :   {
+     188       12444 :     atoms.push_back(UMEM[i]);
+     189             :   }
+     190       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     191             :   {
+     192       12444 :     atoms.push_back(LMEM[i]);
+     193             :   }
+     194        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     195             :   {
+     196        4096 :     atoms.push_back(TAILS[i]);
+     197             :   }
+     198       31800 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     199             :   {
+     200       31799 :     atoms.push_back(WATERS[i]);
+     201             :   }
+     202        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     203             :   {
+     204        2048 :     atoms.push_back(POXYGENS[i]);
+     205             :   }
+     206             : 
+     207           1 :   addValueWithDerivatives();
+     208           1 :   setNotPeriodic();
+     209           1 :   requestAtoms(atoms);
+     210           1 : }
+     211           4 : void fusionPoreExpansionP::calculate()
+     212             : {
+     213             :   /*************************
+     214             :   *                        *
+     215             :   *         System         *
+     216             :   *                        *
+     217             :   **************************/
+     218             : 
+     219             :   // Box dimensions.
+     220           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     221             : 
+     222             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     223             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     224             : 
+     225             : #ifdef _OPENMP
+     226             : #if _OPENMP >= 201307
+     227           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     228             : #endif
+     229             : #endif
+     230             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     231             :   {
+     232             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     233             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     234             :     ZuMemcos += cos(uMemAngle);
+     235             :     ZuMemsin += sin(uMemAngle);
+     236             :     ZlMemcos += cos(lMemAngle);
+     237             :     ZlMemsin += sin(lMemAngle);
+     238             :   }
+     239           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     240           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     241           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     242           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     243           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     244           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     245             : 
+     246             :   // Z center of the boths membranes (upper and lower).
+     247           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     248             : 
+     249             :   /**************************
+     250             :   *                         *
+     251             :   *   Xcyl_Mem & Ycyl_Mem   *
+     252             :   *                         *
+     253             :   ***************************/
+     254             : 
+     255             :   // Quantity of beads of the membranes.
+     256           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     257             : 
+     258             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     259             :   double ZTailDistance;
+     260             : 
+     261             :   // Z position of the first slice.
+     262           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     263             : 
+     264             :   // Z distance between the first slice and the Z center of the membrane.
+     265           4 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     266             : 
+     267             :   // Position in the cylinder.
+     268             :   double PositionS_Mem;
+     269             : 
+     270             :   // Slices to analyze per particle.
+     271             :   unsigned s1_Mem, s2_Mem;
+     272             : 
+     273             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     274           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     275             : 
+     276             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     277           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     278             : 
+     279             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     280           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     281             : 
+     282             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     283             :   double W_Mem = 0.0;
+     284             : 
+     285             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     286           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     287             : 
+     288             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     289             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     290             : 
+     291             :   // Aux.
+     292             :   double x, aux;
+     293             : 
+     294             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     295           4 :   Vector TailPosition;
+     296             : 
+     297             : #ifdef _OPENMP
+     298             : #if _OPENMP >= 201307
+     299             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     300             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     301             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     302             : #endif
+     303             : #endif
+     304             : 
+     305             : #ifdef _OPENMP
+     306             : #if _OPENMP >= 201307
+     307           4 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, TailPosition, x, aux, s1_Mem, s2_Mem) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     308             : #endif
+     309             : #endif
+     310             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     311             :   {
+     312             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     313             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     314             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     315             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     316             :     {
+     317             :       //Defining the slices to analyze each particle.
+     318             :       if (PositionS_Mem < 1)
+     319             :       {
+     320             :         s1_Mem = 0;
+     321             :         s2_Mem = 2;
+     322             :       }
+     323             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     324             :       {
+     325             :         s1_Mem = floor(PositionS_Mem) - 1;
+     326             :         s2_Mem = floor(PositionS_Mem) + 1;
+     327             :       }
+     328             :       else
+     329             :       {
+     330             :         s1_Mem = NSMEM[0] - 3;
+     331             :         s2_Mem = NSMEM[0] - 1;
+     332             :       }
+     333             : 
+     334             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     335             : 
+     336             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     337             :       {
+     338             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     339             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     340             :         {
+     341             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     342             :           {
+     343             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     344             :             Fs_Mem[s] += 1.0;
+     345             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     346             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     347             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     348             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     349             :           }
+     350             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     351             :           {
+     352             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     353             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     354             :             Fs_Mem[s] += aux;
+     355             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     356             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     357             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     358             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     359             :           }
+     360             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     361             :           {
+     362             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     363             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     364             :             Fs_Mem[s] += aux;
+     365             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     366             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     367             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     368             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     369             :           }
+     370             :         }
+     371             :       }
+     372             :     }
+     373             :   }
+     374             : 
+     375         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     376             :   {
+     377         340 :     if (Fs_Mem[s] != 0.0)
+     378             :     {
+     379         340 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     380         340 :       W_Mem += ws_Mem[s];
+     381         340 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     382         340 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     383         340 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     384         340 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     385         340 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     386         340 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     387         340 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     388         340 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     389             :     }
+     390             :   }
+     391             : 
+     392           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     393           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     394           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     395           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     396             : 
+     397             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     398             :   double Xcyl_Mem, Ycyl_Mem;
+     399             : 
+     400           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     401             :   {
+     402             :     Xcyl_Mem = XCYL[0];
+     403             :     Ycyl_Mem = YCYL[0];
+     404             :   }
+     405             :   else
+     406             :   {
+     407           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     408           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     409             :   }
+     410             : 
+     411             :   /*************************
+     412             :   *                        *
+     413             :   *         Xi_Exp         *
+     414             :   *                        *
+     415             :   **************************/
+     416             : 
+     417             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     418           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     419             : 
+     420             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     421           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     422             : 
+     423             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     424           4 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     425             : 
+     426             :   // Estimation of RO with the Hub 2021 JCTC method. Only needed for the expansion.
+     427           4 :   double RO = R0[0];
+     428             : 
+     429             :   // Number of polar atoms inside the horizontal layer. Eq. 3 Hub 2021 JCTC.
+     430             :   double np = 0.0, fz, fr, fz_prime, fr_prime;
+     431             : 
+     432             :   // Derivative of np. Eq. 8 Hub 2021 JCTC.
+     433           4 :   std::vector<double> d_np_dx(chainBeads), d_np_dy(chainBeads), d_np_dz(chainBeads);
+     434             : 
+     435             :   // Pore radius of the defect. Eq. 2 Hub 2021 JCTC.
+     436             :   double poreR = 1.0;
+     437             : 
+     438             :   // Z center of the Membrane in the RMAX radius.
+     439             :   double ZMemRMAX, ZMemRMAXcos = 0.0, ZMemRMAXsin = 0.0, countAux = 0.0, auxcos, auxsin;
+     440             : 
+     441             :   ZMemRMAX = ZMems;
+     442             : 
+     443             :   // The curvature of large membranes (1024 lipids) makes the Z-center of the membranes not to be representative
+     444             :   // in some sectors, particularly in the region of ​​the defect.
+     445             :   //
+     446             :   // To solve this, the center Z of the membranes in the defect sector is calculated and used to calculate
+     447             :   // the number of polar atoms within the horizontal layer AND in the radious of the defect.
+     448             :   //
+     449             :   // ________       | |       ________
+     450             :   // ________ \_____| |______/ _______<-- Top membrane.
+     451             :   //         \______|P|_______/
+     452             :   //                |O|
+     453             :   //                | |               <-- Z-center of the membranes in the region of the defect.
+     454             :   //          ______|R|_______        <-- Z-center of the membranes
+     455             :   //         / _____|E|______ \ 
+     456             :   //        / /     | |      \ \ 
+     457             :   // ______/ /      | |       \ \______
+     458             :   // _______/                  \_______<-- Bottom membrane.
+     459             : 
+     460             :   // Center of mass for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions
+     461           4 :   Vector MemCylDistances, distCylinder;
+     462             :   double angle, ri;
+     463             : 
+     464             : #ifdef _OPENMP
+     465             : #if _OPENMP >= 201307
+     466           4 :   #pragma omp parallel for private(MemCylDistances, x, angle, auxcos, auxsin) reduction(+:ZMemRMAXcos, ZMemRMAXsin, countAux)
+     467             : #endif
+     468             : #endif
+     469             :   for (unsigned i = 0; i < membraneBeads; i++)
+     470             : {
+     471             :   MemCylDistances = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)));
+     472             :     x = sqrt(pow(MemCylDistances[0], 2) + pow(MemCylDistances[1], 2)) / RMAX[0];
+     473             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     474             :     {
+     475             :       angle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     476             :       auxcos = cos(angle);
+     477             :       auxsin = sin(angle);
+     478             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     479             :       {
+     480             :         ZMemRMAXcos += 1.0 * auxcos;
+     481             :         ZMemRMAXsin += 1.0 * auxsin;
+     482             :         countAux += 1.0;
+     483             :       }
+     484             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     485             :       {
+     486             :         ZMemRMAXcos += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxcos;
+     487             :         ZMemRMAXsin += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxsin;
+     488             :         countAux += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3));
+     489             :       }
+     490             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     491             :       {
+     492             :         ZMemRMAXcos += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxcos;
+     493             :         ZMemRMAXsin += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxsin;
+     494             :         countAux += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3));
+     495             :       }
+     496             :     }
+     497             :   }
+     498             : 
+     499           4 :   ZMemRMAXcos = ZMemRMAXcos / countAux;
+     500           4 :   ZMemRMAXsin = ZMemRMAXsin / countAux;
+     501           4 :   ZMemRMAX = Lz * (atan2(-ZMemRMAXsin, -ZMemRMAXcos) + M_PI) / (2.0 * M_PI);
+     502             : 
+     503           4 :   xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMemRMAX));
+     504             : 
+     505             : #ifdef _OPENMP
+     506             : #if _OPENMP >= 201307
+     507           4 :   #pragma omp parallel for private(distCylinder, fz, fz_prime, fr, fr_prime, ri, x) reduction(+:np)
+     508             : #endif
+     509             : #endif
+     510             :   for (unsigned i = 0; i < chainBeads; i++)
+     511             : {
+     512             :   distCylinder = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     513             :     fz = 0.0;
+     514             :     fz_prime = 0.0;
+     515             :     fr = 0.0;
+     516             :     fr_prime = 0.0;
+     517             : 
+     518             :     ri = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     519             :     x = ri / RMAX[0];
+     520             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     521             :     {
+     522             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     523             :       {
+     524             :         fr = 1.0;
+     525             :       }
+     526             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     527             :       {
+     528             :         fr = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     529             :         fr_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     530             :       }
+     531             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     532             :       {
+     533             :         fr = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     534             :         fr_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     535             :       }
+     536             : 
+     537             :       x = distCylinder[2] * 2.0 / D[0];
+     538             :       if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     539             :       {
+     540             :         if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     541             :         {
+     542             :           fz = 1.0;
+     543             :         }
+     544             :         else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     545             :         {
+     546             :           fz = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     547             :           fz_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     548             :         }
+     549             :         else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     550             :         {
+     551             :           fz = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     552             :           fz_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     553             :         }
+     554             : 
+     555             :         np += fz * fr;
+     556             :         d_np_dx[i] = fz * fr_prime * distCylinder[0];
+     557             :         d_np_dy[i] = fz * fr_prime * distCylinder[1];
+     558             :         d_np_dz[i] = fz_prime * fr;
+     559             :       }
+     560             :     }
+     561             :   }
+     562           4 :   poreR = sqrt(np * VO[0] / (M_PI * D[0]));
+     563             : 
+     564             :   // This is the CV that describes the Pore Expansion.
+     565           4 :   double Xi_Exp = (poreR - RO) / RO;
+     566             : 
+     567             :   // Derivatives vector.
+     568           4 :   std::vector<Vector> derivatives(chainBeads);
+     569             : 
+     570             :   // Aux for the derivatives calculations. Eq. 7 Hub 2021 JCTC.
+     571             :   double fact2 = 0.0;
+     572             : 
+     573           4 :   if (poreR != 0.0)
+     574             : {
+     575           4 :   fact2 = VO[0] / (2.0 * M_PI * RO * D[0] * poreR);
+     576             :   }
+     577             : 
+     578             :   // Distances from the oxygens to center of the cylinder.
+     579           4 :   std::vector<Vector> CylDistances(chainBeads);
+     580             : 
+     581             : #ifdef _OPENMP
+     582             : #if _OPENMP >= 201307
+     583           4 :   #pragma omp parallel for
+     584             : #endif
+     585             : #endif
+     586             :   for (unsigned i = 0; i < chainBeads; i++)
+     587             : {
+     588             :   derivatives[i][0] = fact2 * d_np_dx[i];
+     589             :     derivatives[i][1] = fact2 * d_np_dy[i];
+     590             :     derivatives[i][2] = fact2 * d_np_dz[i];
+     591             :     CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     592             :   }
+     593             : 
+     594           4 :   Tensor virial;
+     595      135392 :   for (unsigned i = 0; i < chainBeads; i++)
+     596             : {
+     597      135388 :   setAtomsDerivatives((i + noChainBeads), derivatives[i]);
+     598      135388 :     virial -= Tensor(CylDistances[i], derivatives[i]);
+     599             :   }
+     600             : 
+     601           4 :   setValue(Xi_Exp);
+     602           4 :   setBoxDerivatives(virial);
+     603           4 : }
+     604             : }
+     605             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html new file mode 100644 index 0000000000..c3c8ca9bb2 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18420888.5 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe886createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe88C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe88D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html new file mode 100644 index 0000000000..41dd95d7b5 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18420888.5 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe886createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe88C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_133fusionPoreNucleationPRegisterMe88D2Ev4168
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html new file mode 100644 index 0000000000..e4d9f20d45 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html @@ -0,0 +1,883 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18420888.5 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR FUSIONPORENUCLEATIONP
+      35             : /*
+      36             : A CV for inducing the nucleation of the fusion pore from a hemifusion stalk.
+      37             : 
+      38             : Calculate the collective variable designed by Hub and collaborators \cite Hub2017 and
+      39             : implemented into PLUMED by Masone and collaborators.
+      40             : This CV is capable of inducing the nucleation of the fusion pore from a hemifusion stalk.
+      41             : 
+      42             : \f[
+      43             : \xi_n = \frac{1}{N_{sn}} \sum_{s=0}^{N_{sn}-1} \delta_{sn} (N_{sn}^{(p)})
+      44             : \f]
+      45             : 
+      46             : Where \f$\xi_n\f$ is the CV, \f$N_{sn}\f$ is the number of slices of the cylinder that make up the CV,
+      47             : \f$\delta_{sn}\f$ is a continuos function in the interval [0 1] (\f$\delta_{sf} = 0\f$ for no beads in the slice s, and
+      48             : \f$\delta_{sf} = 1\f$ for 1 or more beads in the slice s) and \f$N_{sf}^{(p)}\f$ accounts for the number of water and
+      49             : phosphateoxygens beads within the slice s.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : This example induces the nucleation of the fusion pore (\f$\xi_n = 1.0\f$) from a hemifusion stalk (\f$\xi_n = 0.2\f$).
+      54             : 
+      55             : \plumedfile
+      56             : 
+      57             : lMem: GROUP ATOMS=1-10752,21505-22728,23953-24420 #All the lower membrane beads.
+      58             : uMem: GROUP ATOMS=10753-21504,22729-23952,24421-24888 #All the upper membrane beads.
+      59             : tails: GROUP ATOMS=8-23948:12,12-23952:12,23966-24884:18,23970-24888:18 #All the lipid tails beads (from the lower and upper membrane).
+      60             : waters: GROUP ATOMS=24889-56490 #All the water beads.
+      61             : po4: GROUP ATOMS=2-23942:12,23957-24875:18 #All the lipid phosphateoxygens beads.
+      62             : 
+      63             : fusionPoreNucleation: FUSIONPORENUCLEATIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails WATERS=waters PHOSPHATEOXYGENS=po4 NSMEM=85 NS=45
+      64             : 
+      65             : MOVINGRESTRAINT ...
+      66             :     ARG=fusionPoreNucleation
+      67             :     STEP0=0 AT0=0.2 KAPPA0=10000.0
+      68             :     STEP1=500000 AT1=1.0 KAPPA1=10000.0
+      69             : ...
+      70             : 
+      71             : PRINT ARG=fusionPoreNucleation FILE=COLVAR STRIDE=1
+      72             : 
+      73             : \endplumedfile
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : class fusionPoreNucleationP : public Colvar
+      78             : {
+      79             :   std::vector<AtomNumber> UMEM, LMEM, TAILS, WATERS, POXYGENS;
+      80             :   std::vector<double> NSMEM, DSMEM, HMEM, NS, DS, HCH, RCYL, ZETA, ONEOVERS2C2CUTOFF, XCYL, YCYL;
+      81             : 
+      82             : public:
+      83             :   explicit fusionPoreNucleationP(const ActionOptions &);
+      84             :   void calculate() override;
+      85             :   static void registerKeywords(Keywords &keys);
+      86             : };
+      87             : 
+      88       12506 : PLUMED_REGISTER_ACTION(fusionPoreNucleationP, "FUSIONPORENUCLEATIONP")
+      89             : 
+      90           3 : void fusionPoreNucleationP::registerKeywords(Keywords &keys)
+      91             : {
+      92           3 :   Colvar::registerKeywords(keys);
+      93           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane.");
+      94           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane.");
+      95           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system.");
+      96           6 :   keys.add("atoms", "WATERS", "all the water beads of the system.");
+      97           6 :   keys.add("atoms", "PHOSPHATEOXYGENS", "all the lipid phosphateoxygens beads of the system.");
+      98           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder.");
+      99           6 :   keys.add("optional", "DSMEM", "( default=0.1 ) thickness of the slices of the membrane fusion cylinder.");
+     100           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+     101           6 :   keys.add("compulsory", "NS", "the number of slices of the membrane-spanning cylinder in such a way that when the bilayers are flat and parallel the CV is equal to 0.2.");
+     102           6 :   keys.add("optional", "DS", "( default=0.25 ) thickness of the slices of the membrane-spanning cylinder.");
+     103           6 :   keys.add("optional", "HCH", "( default=0.25 ) parameter of the step function θ(x,h) for the CV.");
+     104           6 :   keys.add("optional", "RCYL", "( default=0.8 ) the radius of the membrane-spanning cylinder.");
+     105           6 :   keys.add("optional", "ZETA", "( default=0.75 ) parameter of the switch function ψ(x,ζ).");
+     106           6 :   keys.add("optional", "ONEOVERS2C2CUTOFF", "( default=500 ) cut off large values for the derivative of the atan2 function to avoid violate energy.");
+     107           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     108           6 :   keys.add("optional", "YCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     109           3 : }
+     110             : 
+     111           1 : fusionPoreNucleationP::fusionPoreNucleationP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     112             : {
+     113           2 :   parseAtomList("UMEMBRANE", UMEM);
+     114           1 :   if (UMEM.size() == 0)
+     115           0 :     error("UMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("LMEMBRANE", LMEM);
+     118           1 :   if (LMEM.size() == 0)
+     119           0 :     error("LMEMBRANE has not any atom specified.");
+     120             : 
+     121           2 :   parseAtomList("TAILS", TAILS);
+     122           1 :   if (TAILS.size() == 0)
+     123           0 :     error("TAILS has not any atom specified.");
+     124             : 
+     125           2 :   parseAtomList("WATERS", WATERS);
+     126           1 :   if (WATERS.size() == 0)
+     127           0 :     error("WATERS has not any atom specified.");
+     128             : 
+     129           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     130           1 :   if (POXYGENS.size() == 0)
+     131           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     132             : 
+     133           2 :   parseVector("NSMEM", NSMEM);
+     134           1 :   if (NSMEM.size() > 1)
+     135           0 :     error("NSMEM cannot take more than one value.");
+     136             : 
+     137           2 :   parseVector("DSMEM", DSMEM);
+     138           1 :   if (DSMEM.size() > 1)
+     139           0 :     error("DSMEM cannot take more than one value.");
+     140           1 :   if (DSMEM.size() == 0)
+     141           0 :     DSMEM.push_back(0.1);
+     142             : 
+     143           2 :   parseVector("HMEM", HMEM);
+     144           1 :   if (HMEM.size() > 1)
+     145           0 :     error("HMEM cannot take more than one value.");
+     146           1 :   if (HMEM.size() == 0)
+     147           0 :     HMEM.push_back(0.25);
+     148             : 
+     149           2 :   parseVector("NS", NS);
+     150           1 :   if (NS.size() > 1)
+     151           0 :     error("NS cannot take more than one value.");
+     152             : 
+     153           2 :   parseVector("DS", DS);
+     154           1 :   if (DS.size() > 1)
+     155           0 :     error("DS cannot take more than one value.");
+     156           1 :   if (DS.size() == 0)
+     157           0 :     DS.push_back(0.25);
+     158             : 
+     159           2 :   parseVector("HCH", HCH);
+     160           1 :   if (HCH.size() > 1)
+     161           0 :     error("H cannot take more than one value.");
+     162           1 :   if (HCH.size() == 0)
+     163           0 :     HCH.push_back(0.25);
+     164             : 
+     165           2 :   parseVector("RCYL", RCYL);
+     166           1 :   if (RCYL.size() > 1)
+     167           0 :     error("RCYL cannot take more than one value.");
+     168           1 :   if (RCYL.size() == 0)
+     169           0 :     RCYL.push_back(0.8);
+     170             : 
+     171           2 :   parseVector("ZETA", ZETA);
+     172           1 :   if (ZETA.size() > 1)
+     173           0 :     error("ZETA cannot take more than one value.");
+     174           1 :   if (ZETA.size() == 0)
+     175           0 :     ZETA.push_back(0.75);
+     176             : 
+     177           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     178           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     179           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     180           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     181           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     182             : 
+     183           2 :   parseVector("XCYL", XCYL);
+     184           1 :   if (XCYL.size() > 1)
+     185           0 :     error("XCYL cannot take more than one value.");
+     186           1 :   if (XCYL.size() == 0)
+     187           1 :     XCYL.push_back(-1.0);
+     188             : 
+     189           2 :   parseVector("YCYL", YCYL);
+     190           1 :   if (YCYL.size() > 1)
+     191           0 :     error("YCYL cannot take more than one value.");
+     192           1 :   if (YCYL.size() == 0)
+     193           1 :     YCYL.push_back(-1.0);
+     194             : 
+     195           1 :   checkRead();
+     196             : 
+     197             :   std::vector<AtomNumber> atoms;
+     198       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     199             :   {
+     200       12444 :     atoms.push_back(UMEM[i]);
+     201             :   }
+     202       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     203             :   {
+     204       12444 :     atoms.push_back(LMEM[i]);
+     205             :   }
+     206        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     207             :   {
+     208        4096 :     atoms.push_back(TAILS[i]);
+     209             :   }
+     210       31603 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     211             :   {
+     212       31602 :     atoms.push_back(WATERS[i]);
+     213             :   }
+     214        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     215             :   {
+     216        2048 :     atoms.push_back(POXYGENS[i]);
+     217             :   }
+     218             : 
+     219           1 :   addValueWithDerivatives();
+     220           1 :   setNotPeriodic();
+     221           1 :   requestAtoms(atoms);
+     222           1 : }
+     223             : 
+     224           4 : void fusionPoreNucleationP::calculate()
+     225             : {
+     226             :   /*************************
+     227             :   *                        *
+     228             :   *         System         *
+     229             :   *                        *
+     230             :   **************************/
+     231             : 
+     232             :   // Box dimensions.
+     233           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     234             : 
+     235             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     236             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     237             : 
+     238             : #ifdef _OPENMP
+     239             : #if _OPENMP >= 201307
+     240           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     241             : #endif
+     242             : #endif
+     243             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     244             :   {
+     245             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     246             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     247             :     ZuMemcos += cos(uMemAngle);
+     248             :     ZuMemsin += sin(uMemAngle);
+     249             :     ZlMemcos += cos(lMemAngle);
+     250             :     ZlMemsin += sin(lMemAngle);
+     251             :   }
+     252           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     253           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     254           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     255           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     256           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     257           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     258             : 
+     259             :   // Z center of the boths membranes (upper and lower).
+     260           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     261             : 
+     262             :   /**************************
+     263             :   *                         *
+     264             :   *   Xcyl_Mem & Ycyl_Mem   *
+     265             :   *                         *
+     266             :   ***************************/
+     267             : 
+     268             :   // Quantity of beads of the membranes.
+     269           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     270             : 
+     271             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     272             :   double ZTailDistance;
+     273             : 
+     274             :   // Z position of the first slice.
+     275           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     276             : 
+     277             :   // Z distance between the first slice and the Z center of the membrane.
+     278           4 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     279             : 
+     280             :   // Position in the cylinder.
+     281             :   double PositionS_Mem;
+     282             : 
+     283             :   // Slices to analyze per particle.
+     284             :   unsigned s1_Mem, s2_Mem;
+     285             : 
+     286             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     287           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     288             : 
+     289             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     290           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     291             : 
+     292             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     293           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     294             : 
+     295             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     296             :   double W_Mem = 0.0;
+     297             : 
+     298             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     299           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     300             : 
+     301             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     302             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     303             : 
+     304             :   // Aux.
+     305             :   double x, aux;
+     306             : 
+     307             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     308           4 :   Vector TailPosition;
+     309             : 
+     310             : #ifdef _OPENMP
+     311             : #if _OPENMP >= 201307
+     312             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     313             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     314             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     315             : #endif
+     316             : #endif
+     317             : 
+     318             : #ifdef _OPENMP
+     319             : #if _OPENMP >= 201307
+     320           4 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, s1_Mem, s2_Mem, TailPosition, x, aux) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     321             : #endif
+     322             : #endif
+     323             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     324             :   {
+     325             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     326             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     327             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     328             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     329             :     {
+     330             :       //Defining the slices to analyze each particle.
+     331             :       if (PositionS_Mem < 1)
+     332             :       {
+     333             :         s1_Mem = 0;
+     334             :         s2_Mem = 2;
+     335             :       }
+     336             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     337             :       {
+     338             :         s1_Mem = floor(PositionS_Mem) - 1;
+     339             :         s2_Mem = floor(PositionS_Mem) + 1;
+     340             :       }
+     341             :       else
+     342             :       {
+     343             :         s1_Mem = NSMEM[0] - 3;
+     344             :         s2_Mem = NSMEM[0] - 1;
+     345             :       }
+     346             : 
+     347             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     348             : 
+     349             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     350             :       {
+     351             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     352             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     353             :         {
+     354             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     355             :           {
+     356             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     357             :             Fs_Mem[s] += 1.0;
+     358             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     359             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     360             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     361             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     362             :           }
+     363             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     364             :           {
+     365             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     366             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     367             :             Fs_Mem[s] += aux;
+     368             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     369             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     370             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     371             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     372             :           }
+     373             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     374             :           {
+     375             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     376             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     377             :             Fs_Mem[s] += aux;
+     378             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     379             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     380             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     381             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     382             :           }
+     383             :         }
+     384             :       }
+     385             :     }
+     386             :   }
+     387             : 
+     388         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     389             :   {
+     390         340 :     if (Fs_Mem[s] != 0.0)
+     391             :     {
+     392         339 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     393         339 :       W_Mem += ws_Mem[s];
+     394         339 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     395         339 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     396         339 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     397         339 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     398         339 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     399         339 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     400         339 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     401         339 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     402             :     }
+     403             :   }
+     404             : 
+     405           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     406           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     407           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     408           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     409             : 
+     410             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     411             :   double Xcyl_Mem, Ycyl_Mem;
+     412             : 
+     413           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     414             :   {
+     415             :     Xcyl_Mem = XCYL[0];
+     416             :     Ycyl_Mem = YCYL[0];
+     417             :   }
+     418             :   else
+     419             :   {
+     420           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     421           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     422             :   }
+     423             : 
+     424             :   /*************************
+     425             :   *                        *
+     426             :   *        Xi_n            *
+     427             :   *                        *
+     428             :   **************************/
+     429             : 
+     430             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     431           4 :   double Xi_n = 0.0;
+     432             : 
+     433             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     434           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     435             : 
+     436             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     437           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     438             : 
+     439             :   // Z Distances from the oxygens to the geometric center of the membranes.
+     440             :   double ZMemDistance;
+     441             : 
+     442             :   // Scaled positions of the oxygens to respect of the origin of coordinates.
+     443           4 :   Vector Position;
+     444             : 
+     445             :   // Distance from the water/phosphate group to the defect cylinder.
+     446           4 :   Vector distCylinder;
+     447             : 
+     448             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     449           4 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     450             : 
+     451             :   // Average of the radius of the water and lipid cylinder.
+     452           4 :   double RCYLAVERAGE = RCYL[0] * (1 + HCH[0]);
+     453             : 
+     454             :   // Conditions.
+     455             :   bool condition1, condition2, condition3;
+     456             : 
+     457             :   // Z position of the first slice.
+     458           4 :   double firstSliceZ = ZMems + (0.0 + 0.5 - NS[0] / 2.0) * DS[0];
+     459             : 
+     460             :   // Z distance between the first slice and the Z center of the membrane.
+     461           4 :   double firstSliceZDist = pbcDistance(Vector(0.0, 0.0, firstSliceZ), Vector(0.0, 0.0, ZMems))[2];
+     462             : 
+     463             :   // Position in the cylinder.
+     464             :   double PositionS;
+     465             : 
+     466             :   // Mark the particles to analyze.
+     467           4 :   std::vector<double> analyzeThisParticle(chainBeads);
+     468             : 
+     469             :   // Slices to analyze per particle.
+     470           4 :   std::vector<unsigned> s1(chainBeads), s2(chainBeads);
+     471             : 
+     472             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     473           4 :   std::vector<double> faxial(chainBeads * NS[0]);
+     474             : 
+     475             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     476           4 :   std::vector<double> d_faxial_dz(chainBeads * NS[0]);
+     477             : 
+     478             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     479           4 :   std::vector<double> Fs(NS[0]);
+     480             : 
+     481             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     482           4 :   std::vector<double> ws(NS[0]);
+     483             : 
+     484             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     485             :   double W = 0.0;
+     486             : 
+     487             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     488           4 :   std::vector<double> sx(NS[0]), sy(NS[0]), cx(NS[0]), cy(NS[0]);
+     489             : 
+     490             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     491             :   double Xsc = 0.0, Xcc = 0.0, Ysc = 0.0, Ycc = 0.0;
+     492             : 
+     493             : #ifdef _OPENMP
+     494             : #if _OPENMP >= 201307
+     495           4 :   #pragma omp parallel for private(distCylinder, aux, condition1, condition2, condition3, ZMemDistance, PositionS, Position, x) reduction(vec_double_plus:Fs, sx, sy, cx, cy)
+     496             : #endif
+     497             : #endif
+     498             :   for (unsigned i = 0; i < chainBeads; i++)
+     499             : {
+     500             :   distCylinder = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     501             :     aux = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     502             :     condition1 = ((aux / RCYLAVERAGE) < 1.0);
+     503             :     condition2 = ((pbcDistance(Vector(0.0, 0.0, ZuMem), getPosition(i + noChainBeads))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     504             :     condition3 = ((pbcDistance(getPosition(i + noChainBeads), Vector(0.0, 0.0, ZlMem))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     505             :     if (condition1 || condition2 || condition3)
+     506             :     {
+     507             :       ZMemDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + noChainBeads))[2];
+     508             :       PositionS = (ZMemDistance + firstSliceZDist) / DS[0];
+     509             :       // If the following condition is met the particle is in the Z space of the cylinder.
+     510             :       if ((PositionS >= (-0.5 - HCH[0])) && (PositionS <= (NS[0] + 0.5 - 1.0 + HCH[0])))
+     511             :       {
+     512             :         analyzeThisParticle[i] = 1.0;
+     513             : 
+     514             :         //Defining the slices to analyze each particle.
+     515             :         if (PositionS < 1)
+     516             :         {
+     517             :           s1[i] = 0;
+     518             :           s2[i] = 2;
+     519             :         }
+     520             :         else if (PositionS <= (NS[0] - 2.0))
+     521             :         {
+     522             :           s1[i] = floor(PositionS) - 1;
+     523             :           s2[i] = floor(PositionS) + 1;
+     524             :         }
+     525             :         else
+     526             :         {
+     527             :           s1[i] = NS[0] - 3;
+     528             :           s2[i] = NS[0] - 1;
+     529             :         }
+     530             : 
+     531             :         Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     532             : 
+     533             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     534             :         {
+     535             :           x = (ZMemDistance - (s + 0.5 - NS[0] / 2.0) * DS[0]) * 2.0 / DS[0];
+     536             :           if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     537             :           {
+     538             :             if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     539             :             {
+     540             :               faxial[i + chainBeads * s] = 1.0;
+     541             :               Fs[s] += 1.0;
+     542             :               sx[s] += sin(2.0 * M_PI * Position[0]);
+     543             :               sy[s] += sin(2.0 * M_PI * Position[1]);
+     544             :               cx[s] += cos(2.0 * M_PI * Position[0]);
+     545             :               cy[s] += cos(2.0 * M_PI * Position[1]);
+     546             :             }
+     547             :             else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     548             :             {
+     549             :               aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     550             :               faxial[i + chainBeads * s] = aux;
+     551             :               d_faxial_dz[i + chainBeads * s] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * 2.0 / DS[0];
+     552             :               Fs[s] += aux;
+     553             :               sx[s] += aux * sin(2.0 * M_PI * Position[0]);
+     554             :               sy[s] += aux * sin(2.0 * M_PI * Position[1]);
+     555             :               cx[s] += aux * cos(2.0 * M_PI * Position[0]);
+     556             :               cy[s] += aux * cos(2.0 * M_PI * Position[1]);
+     557             :             }
+     558             :             else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     559             :             {
+     560             :               aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     561             :               faxial[i + chainBeads * s] = aux;
+     562             :               d_faxial_dz[i + chainBeads * s] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * 2.0 / DS[0];
+     563             :               Fs[s] += aux;
+     564             :               sx[s] += (aux * sin(2.0 * M_PI * Position[0]));
+     565             :               sy[s] += (aux * sin(2.0 * M_PI * Position[1]));
+     566             :               cx[s] += (aux * cos(2.0 * M_PI * Position[0]));
+     567             :               cy[s] += (aux * cos(2.0 * M_PI * Position[1]));
+     568             :             }
+     569             :           }
+     570             :         }
+     571             :       }
+     572             :     }
+     573             :   }
+     574             : 
+     575         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     576             :   {
+     577         180 :     if (Fs[s] != 0.0)
+     578             :     {
+     579          49 :       ws[s] = tanh(Fs[s]);
+     580          49 :       W += ws[s];
+     581          49 :       sx[s] = sx[s] / Fs[s];
+     582          49 :       sy[s] = sy[s] / Fs[s];
+     583          49 :       cx[s] = cx[s] / Fs[s];
+     584          49 :       cy[s] = cy[s] / Fs[s];
+     585          49 :       Xsc += sx[s] * ws[s];
+     586          49 :       Ysc += sy[s] * ws[s];
+     587          49 :       Xcc += cx[s] * ws[s];
+     588          49 :       Ycc += cy[s] * ws[s];
+     589             :     }
+     590             :   }
+     591             : 
+     592           4 :   Xsc = Xsc / W;
+     593           4 :   Ysc = Ysc / W;
+     594           4 :   Xcc = Xcc / W;
+     595           4 :   Ycc = Ycc / W;
+     596             : 
+     597             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     598             :   double Xcyl, Ycyl;
+     599             : 
+     600             :   Xcyl = Xcyl_Mem;
+     601             :   Ycyl = Ycyl_Mem;
+     602             : 
+     603             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     604             :   double d_sx_dx, d_sx_dz, d_sy_dy, d_sy_dz, d_cx_dx, d_cx_dz, d_cy_dy, d_cy_dz;
+     605             : 
+     606             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     607             :   double d_ws_dz;
+     608             : 
+     609             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     610             :   double d_Xsc_dx, d_Xsc_dz, d_Xcc_dx, d_Xcc_dz, d_Ysc_dy, d_Ysc_dz, d_Ycc_dy, d_Ycc_dz;
+     611             : 
+     612             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     613           4 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl, Ycyl, ZMems));
+     614             : 
+     615             :   // Distances from the oxygens to center of the cylinder.
+     616           4 :   std::vector<Vector> CylDistances(chainBeads);
+     617             : 
+     618             :   // Modulo of the XY distances from the oxygens to the center of the cylinder.
+     619             :   double ri;
+     620             : 
+     621             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     622             :   double fradial;
+     623             : 
+     624             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     625           4 :   std::vector<double> d_fradial_dx(chainBeads), d_fradial_dy(chainBeads);
+     626             : 
+     627             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     628           4 :   std::vector<double> d_Xcyl_dx(chainBeads), d_Xcyl_dz(chainBeads), d_Ycyl_dy(chainBeads), d_Ycyl_dz(chainBeads);
+     629             : 
+     630             :   // To avoid rare instabilities auxX and auxY are truncated at a configurable value (default 500).
+     631           4 :   double auxX = (1 / (pow(Xsc, 2) + pow(Xcc, 2))), auxY = (1 / (pow(Ysc, 2) + pow(Ycc, 2)));
+     632             : 
+     633           4 :   if (auxX > ONEOVERS2C2CUTOFF[0])
+     634             :   {
+     635           0 :     auxX = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     636             :   }
+     637             :   else
+     638             :   {
+     639           4 :     auxX = Lx * auxX / (2 * M_PI);
+     640             :   }
+     641             : 
+     642           4 :   if (auxY > ONEOVERS2C2CUTOFF[0])
+     643             :   {
+     644           0 :     auxY = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     645             :   }
+     646             :   else
+     647             :   {
+     648           4 :     auxY = Ly * auxY / (2 * M_PI);
+     649             :   }
+     650             : 
+     651             :   //Number of oxygens within the slice s of the membrane-spanning cylinder.
+     652           4 :   std::vector<double> Nsp(NS[0]), psi(NS[0]), d_psi(NS[0]);
+     653             : 
+     654             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     655           4 :   double b = (ZETA[0] / (1.0 - ZETA[0])), c = ((1.0 - ZETA[0]) * exp(b));
+     656             : 
+     657             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     658           4 :   std::vector<double> fradial_d_faxial_dz(chainBeads * NS[0]);
+     659             : 
+     660             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     661           4 :   std::vector<double> Axs(NS[0]), Ays(NS[0]);
+     662             : 
+     663             : #ifdef _OPENMP
+     664             : #if _OPENMP >= 201307
+     665           4 :   #pragma omp parallel for private(d_Xsc_dx,d_Xcc_dx,d_Ysc_dy,d_Ycc_dy,d_Xsc_dz,d_Xcc_dz,d_Ysc_dz,d_Ycc_dz,d_sx_dx,d_sy_dy,d_cx_dx,d_cy_dy,d_sx_dz,d_sy_dz,d_cx_dz,d_cy_dz,d_ws_dz,ri,x,fradial) reduction(vec_double_plus: Nsp, Axs, Ays)
+     666             : #endif
+     667             : #endif
+     668             :   for (unsigned i = 0; i < chainBeads; i++)
+     669             : {
+     670             :   CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     671             :     if (analyzeThisParticle[i])
+     672             :     {
+     673             :       Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     674             :       d_Xsc_dx = 0.0;
+     675             :       d_Xcc_dx = 0.0;
+     676             :       d_Ysc_dy = 0.0;
+     677             :       d_Ycc_dy = 0.0;
+     678             :       d_Xsc_dz = 0.0;
+     679             :       d_Xcc_dz = 0.0;
+     680             :       d_Ysc_dz = 0.0;
+     681             :       d_Ycc_dz = 0.0;
+     682             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     683             :       {
+     684             :         if (Fs[s] != 0.0)
+     685             :         {
+     686             :           d_sx_dx = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     687             :           d_sy_dy = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     688             :           d_cx_dx = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     689             :           d_cy_dy = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     690             :           d_Xsc_dx += ws[s] * d_sx_dx / W;
+     691             :           d_Xcc_dx += ws[s] * d_cx_dx / W;
+     692             :           d_Ysc_dy += ws[s] * d_sy_dy / W;
+     693             :           d_Ycc_dy += ws[s] * d_cy_dy / W;
+     694             : 
+     695             :           d_sx_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[0]) - sx[s]) / Fs[s];
+     696             :           d_sy_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[1]) - sy[s]) / Fs[s];
+     697             :           d_cx_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[0]) - cx[s]) / Fs[s];
+     698             :           d_cy_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[1]) - cy[s]) / Fs[s];
+     699             :           d_ws_dz = (1 - pow(ws[s], 2)) * d_faxial_dz[i + chainBeads * s];
+     700             :           d_Xsc_dz += (ws[s] * d_sx_dz + d_ws_dz * (sx[s] - Xsc)) / W;
+     701             :           d_Xcc_dz += (ws[s] * d_cx_dz + d_ws_dz * (cx[s] - Xcc)) / W;
+     702             :           d_Ysc_dz += (ws[s] * d_sy_dz + d_ws_dz * (sy[s] - Ysc)) / W;
+     703             :           d_Ycc_dz += (ws[s] * d_cy_dz + d_ws_dz * (cy[s] - Ycc)) / W;
+     704             :         }
+     705             :       }
+     706             :       d_Xcyl_dx[i] = auxX * (-Xsc * d_Xcc_dx + Xcc * d_Xsc_dx);
+     707             :       d_Xcyl_dz[i] = auxX * (-Xsc * d_Xcc_dz + Xcc * d_Xsc_dz);
+     708             :       d_Ycyl_dy[i] = auxY * (-Ysc * d_Ycc_dy + Ycc * d_Ysc_dy);
+     709             :       d_Ycyl_dz[i] = auxY * (-Ysc * d_Ycc_dz + Ycc * d_Ysc_dz);
+     710             : 
+     711             :       ri = sqrt(pow(CylDistances[i][0], 2) + pow(CylDistances[i][1], 2));
+     712             :       x = ri / RCYL[0];
+     713             :       if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     714             :       {
+     715             :         if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     716             :         {
+     717             :           fradial = 1.0;
+     718             :         }
+     719             :         else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     720             :         {
+     721             :           fradial = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     722             :           d_fradial_dx[i] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][0] / (RCYL[0] * ri);
+     723             :           d_fradial_dy[i] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][1] / (RCYL[0] * ri);
+     724             :         }
+     725             :         else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     726             :         {
+     727             :           fradial = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     728             :           d_fradial_dx[i] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][0] / (RCYL[0] * ri);
+     729             :           d_fradial_dy[i] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][1] / (RCYL[0] * ri);
+     730             :         }
+     731             : 
+     732             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     733             :         {
+     734             :           Nsp[s] += fradial * faxial[i + chainBeads * s];
+     735             :           Axs[s] += faxial[i + chainBeads * s] * d_fradial_dx[i];
+     736             :           Ays[s] += faxial[i + chainBeads * s] * d_fradial_dy[i];
+     737             :           fradial_d_faxial_dz[i + chainBeads * s] = fradial * d_faxial_dz[i + chainBeads * s];
+     738             :         }
+     739             :       }
+     740             :     }
+     741             :   }
+     742             : 
+     743         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     744             :   {
+     745         180 :     if (Nsp[s] <= 1.0)
+     746             :     {
+     747         149 :       psi[s] = ZETA[0] * Nsp[s];
+     748         149 :       d_psi[s] = ZETA[0];
+     749         149 :       Xi_n += psi[s];
+     750             :     }
+     751             :     else
+     752             :     {
+     753          31 :       psi[s] = 1.0 - c * exp(-b * Nsp[s]);
+     754          31 :       d_psi[s] = b * c * exp(-b * Nsp[s]);
+     755          31 :       Xi_n += psi[s];
+     756             :     }
+     757             :   }
+     758             : 
+     759           4 :   Xi_n = Xi_n / NS[0];
+     760             : 
+     761             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     762           4 :   std::vector<double> faxial_d_fradial_dx(chainBeads * NS[0]), faxial_d_fradial_dy(chainBeads * NS[0]), faxial_d_fradial_dz(chainBeads * NS[0]);
+     763             : 
+     764             :   // Eq. 13 Hub & Awasthi JCTC 2017 modified to considere the Heaviside_Chain step function (this only affect during the transition).
+     765           4 :   std::vector<Vector> derivatives_Chain(chainBeads);
+     766             : 
+     767             : #ifdef _OPENMP
+     768             : #if _OPENMP >= 201307
+     769           4 :   #pragma omp parallel for private(aux)
+     770             : #endif
+     771             : #endif
+     772             :   for (unsigned i = 0; i < chainBeads; i++)
+     773             : {
+     774             :   if (analyzeThisParticle[i])
+     775             :     {
+     776             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     777             :       {
+     778             :         if (faxial[i + chainBeads * s])
+     779             :         {
+     780             :           faxial_d_fradial_dx[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dx[i] - d_Xcyl_dx[i] * Axs[s];
+     781             :           faxial_d_fradial_dy[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dy[i] - d_Ycyl_dy[i] * Ays[s];
+     782             :           faxial_d_fradial_dz[i + chainBeads * s] = -d_Xcyl_dz[i] * Axs[s] - d_Ycyl_dz[i] * Ays[s];
+     783             :         }
+     784             :       }
+     785             : 
+     786             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     787             :       {
+     788             :         aux = d_psi[s] / NS[0];
+     789             :         derivatives_Chain[i][0] += aux * faxial_d_fradial_dx[i + chainBeads * s];
+     790             :         derivatives_Chain[i][1] += aux * faxial_d_fradial_dy[i + chainBeads * s];
+     791             :         derivatives_Chain[i][2] += aux * (faxial_d_fradial_dz[i + chainBeads * s] + fradial_d_faxial_dz[i + chainBeads * s]);
+     792             :       }
+     793             :     }
+     794             :   }
+     795             : 
+     796           4 :   Tensor virial;
+     797      134604 :   for (unsigned i = 0; i < chainBeads; i++)
+     798             : {
+     799      134600 :   setAtomsDerivatives((i + noChainBeads), derivatives_Chain[i]);
+     800      134600 :     virial -= Tensor(CylDistances[i], derivatives_Chain[i]);
+     801             :   }
+     802             : 
+     803           4 :   setValue(Xi_n);
+     804           4 :   setBoxDerivatives(virial);
+     805           4 : }
+     806             : }
+     807             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html b/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html new file mode 100644 index 0000000000..6d6ba7d613 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13415188.7 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe896createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe89C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe89D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.func.html b/coverage/membranefusion/MemFusionP.cpp.func.html new file mode 100644 index 0000000000..d5a9f1e5dd --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13415188.7 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe896createERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe89C2Ev4168
_ZN4PLMD14membranefusion12_GLOBAL__N_122memFusionPRegisterMe89D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.gcov.html b/coverage/membranefusion/MemFusionP.cpp.gcov.html new file mode 100644 index 0000000000..84e5588aeb --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.gcov.html @@ -0,0 +1,684 @@ + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13415188.7 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR MEMFUSIONP
+      35             : /*
+      36             : Calculate a CV that can induce the formation of the hemifusion stalk between two initially flat and planar bilayers.
+      37             : 
+      38             : Calculate the collective variable designed by Hub and collaborators \cite Hub2017 and
+      39             : implemented into PLUMED by Masone and collaborators \cite DiBartolo2022 .
+      40             : This CV is capable of inducing the formation of the hemifusion stalk between two initially flat and planar bilayers
+      41             : surrounded by water molecules.
+      42             : 
+      43             : \f[
+      44             : \xi_f = \frac{1}{N_{sf}} \sum_{s=0}^{N_{sf}-1} \delta_{sf} (N_{sf}^{(p)})
+      45             : \f]
+      46             : 
+      47             : Where \f$\xi_f\f$ is the CV, \f$N_{sf}\f$ is the number of slices of the cylinder that make up the CV,
+      48             : \f$\delta_{sf}\f$ is a continuos function in the interval [0 1] (\f$\delta_{sf} = 0\f$ for no beads in the slice s, and
+      49             : \f$\delta_{sf} = 1\f$ for 1 or more beads in the slice s) and \f$N_{sf}^{(p)}\f$ accounts for the number of tail beads
+      50             : within the slice s.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : This example induces a hemifusion stalk (\f$\xi_f = 0.85\f$) from a pair of initially flat membranes (\f$\xi_f = 0.2\f$).
+      55             : 
+      56             : \plumedfile
+      57             : lMem: GROUP ATOMS=1-12288 #All the lower membrane beads.
+      58             : uMem: GROUP ATOMS=12289-24576 #All the upper membrane beads.
+      59             : tails: GROUP ATOMS=8-24572:12,12-24576:12 #All the lipid tails beads (from the lower and upper membrane).
+      60             : 
+      61             : memFusion: MEMFUSIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails NSMEM=70 DSMEM=0.1 HMEM=0.25 RCYLMEM=1.75 ZETAMEM=0.5
+      62             : 
+      63             : MOVINGRESTRAINT ...
+      64             :     ARG=memFusion
+      65             :     STEP0=0 AT0=0.2 KAPPA0=10000.0
+      66             :     STEP1=500000 AT1=0.85 KAPPA1=10000.0
+      67             : ...
+      68             : 
+      69             : PRINT ARG=memFusion FILE=COLVAR STRIDE=1
+      70             : 
+      71             : \endplumedfile
+      72             : 
+      73             : You can test this CV with another example in this <a href="https://github.com/lautarodibartolo/MemFusion/tree/main/ExampleParallel">GitHub folder</a>.
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : class memFusionP : public Colvar
+      79             : {
+      80             :   std::vector<AtomNumber> UMEM, LMEM, TAILS;
+      81             :   std::vector<double> NSMEM, DSMEM, HMEM, RCYLMEM, ZETAMEM, ONEOVERS2C2CUTOFF, XCYL, YCYL;
+      82             : 
+      83             : public:
+      84             :   explicit memFusionP(const ActionOptions &);
+      85             :   void calculate() override;
+      86             :   static void registerKeywords(Keywords &keys);
+      87             : };
+      88             : 
+      89       12506 : PLUMED_REGISTER_ACTION(memFusionP, "MEMFUSIONP")
+      90             : 
+      91           3 : void memFusionP::registerKeywords(Keywords &keys)
+      92             : {
+      93           3 :   Colvar::registerKeywords(keys);
+      94           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane");
+      95           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane");
+      96           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system");
+      97           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder in such a way that when the bilayers are flat and parallel the CV is equal to 0.2.");
+      98           6 :   keys.add("optional", "DSMEM", "( default=0.1) thickness of the slices of the membrane fusion cylinder.");
+      99           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+     100           6 :   keys.add("optional", "RCYLMEM", "( default=1.75 ) the radius of the membrane fusion cylinder.");
+     101           6 :   keys.add("optional", "ZETAMEM", "( default=0.5 ) occupation factor.");
+     102           6 :   keys.add("optional", "ONEOVERS2C2CUTOFF", "( default=500 ) cut off large values for the derivative of the atan2 function.");
+     103           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     104           6 :   keys.add("optional", "YCYL", "Y coordinate of the fixed cylinder, if not present this will be calculated.");
+     105           3 : }
+     106             : 
+     107           1 : memFusionP::memFusionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     108             : {
+     109           2 :   parseAtomList("UMEMBRANE", UMEM);
+     110           1 :   if (UMEM.size() == 0)
+     111           0 :     error("UMEMBRANE has not any atom specified.");
+     112             : 
+     113           2 :   parseAtomList("LMEMBRANE", LMEM);
+     114           1 :   if (LMEM.size() == 0)
+     115           0 :     error("LMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("TAILS", TAILS);
+     118           1 :   if (TAILS.size() == 0)
+     119           0 :     error("TAILS has not any atom specified.");
+     120             : 
+     121           2 :   parseVector("NSMEM", NSMEM);
+     122           1 :   if (NSMEM.size() > 1)
+     123           0 :     error("NSMEM cannot take more than one value.");
+     124             : 
+     125           2 :   parseVector("DSMEM", DSMEM);
+     126           1 :   if (DSMEM.size() > 1)
+     127           0 :     error("DSMEM cannot take more than one value.");
+     128           1 :   if (DSMEM.size() == 0)
+     129           0 :     DSMEM.push_back(0.1);
+     130             : 
+     131           2 :   parseVector("HMEM", HMEM);
+     132           1 :   if (HMEM.size() > 1)
+     133           0 :     error("HMEM cannot take more than one value.");
+     134           1 :   if (HMEM.size() == 0)
+     135           0 :     HMEM.push_back(0.25);
+     136             : 
+     137           2 :   parseVector("RCYLMEM", RCYLMEM);
+     138           1 :   if (RCYLMEM.size() > 1)
+     139           0 :     error("RCYLMEM cannot take more than one value.");
+     140           1 :   if (RCYLMEM.size() == 0)
+     141           0 :     RCYLMEM.push_back(1.75);
+     142             : 
+     143           2 :   parseVector("ZETAMEM", ZETAMEM);
+     144           1 :   if (ZETAMEM.size() > 1)
+     145           0 :     error("ZETA cannot take more than one value.");
+     146           1 :   if (ZETAMEM.size() == 0)
+     147           0 :     ZETAMEM.push_back(0.5);
+     148             : 
+     149           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     150           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     151           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     152           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     153           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     154             : 
+     155           2 :   parseVector("XCYL", XCYL);
+     156           1 :   if (XCYL.size() > 1)
+     157           0 :     error("XCYL cannot take more than one value.");
+     158           1 :   if (XCYL.size() == 0)
+     159           1 :     XCYL.push_back(-1.0);
+     160             : 
+     161           2 :   parseVector("YCYL", YCYL);
+     162           1 :   if (YCYL.size() > 1)
+     163           0 :     error("YCYL cannot take more than one value.");
+     164           1 :   if (YCYL.size() == 0)
+     165           1 :     YCYL.push_back(-1.0);
+     166             : 
+     167           1 :   checkRead();
+     168             : 
+     169             :   std::vector<AtomNumber> atoms;
+     170       12289 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     171             :   {
+     172       12288 :     atoms.push_back(UMEM[i]);
+     173             :   }
+     174       12289 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     175             :   {
+     176       12288 :     atoms.push_back(LMEM[i]);
+     177             :   }
+     178        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     179             :   {
+     180        4096 :     atoms.push_back(TAILS[i]);
+     181             :   }
+     182             : 
+     183           1 :   addValueWithDerivatives();
+     184           1 :   setNotPeriodic();
+     185           1 :   requestAtoms(atoms);
+     186           1 : }
+     187             : 
+     188           3 : void memFusionP::calculate()
+     189             : {
+     190             :   /**************************
+     191             :    *                        *
+     192             :    *         System         *
+     193             :    *                        *
+     194             :    **************************/
+     195             : 
+     196             :   // Box dimensions.
+     197           3 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     198             : 
+     199             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     200             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     201             : 
+     202             : #ifdef _OPENMP
+     203             : #if _OPENMP >= 201307
+     204           3 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     205             : #endif
+     206             : #endif
+     207             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     208             :   {
+     209             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     210             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     211             :     ZuMemcos += cos(uMemAngle);
+     212             :     ZuMemsin += sin(uMemAngle);
+     213             :     ZlMemcos += cos(lMemAngle);
+     214             :     ZlMemsin += sin(lMemAngle);
+     215             :   }
+     216             : 
+     217           3 :   ZuMemcos = ZuMemcos / UMEM.size();
+     218           3 :   ZuMemsin = ZuMemsin / UMEM.size();
+     219           3 :   ZlMemcos = ZlMemcos / UMEM.size();
+     220           3 :   ZlMemsin = ZlMemsin / UMEM.size();
+     221             : 
+     222           3 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     223           3 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     224             : 
+     225             :   // Z center of the boths membranes (upper and lower).
+     226           3 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     227             : 
+     228             :   /*************************
+     229             :    *                        *
+     230             :    *         Xi_Mem         *
+     231             :    *                        *
+     232             :    **************************/
+     233             : 
+     234             :   // Quantity of beads of the membranes.
+     235           3 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     236             : 
+     237             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     238             :   double ZTailDistance;
+     239             : 
+     240             :   // Z position of the first slice.
+     241           3 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     242             : 
+     243             :   // Z distance between the first slice and the Z center of the membrane.
+     244           3 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     245             : 
+     246             :   // Position in the cylinder.
+     247             :   double PositionS_Mem;
+     248             : 
+     249             :   // Slices to analyze per particle.
+     250           3 :   std::vector<unsigned> s1_Mem(TAILS.size()), s2_Mem(TAILS.size());
+     251             : 
+     252             :   // Mark the particles to analyze.
+     253           3 :   std::vector<double> analyzeThisParticle_Mem(TAILS.size());
+     254             : 
+     255             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     256           3 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     257             : 
+     258             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     259           3 :   std::vector<double> d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     260             : 
+     261             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     262           3 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     263             : 
+     264             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     265           3 :   std::vector<double> ws_Mem(NSMEM[0]);
+     266             : 
+     267             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     268             :   double W_Mem = 0.0;
+     269             : 
+     270             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     271           3 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     272             : 
+     273             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     274             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     275             : 
+     276             :   // Aux.
+     277             :   double x, aux;
+     278             : 
+     279             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     280           3 :   Vector TailPosition;
+     281             : 
+     282             :   // Thanks stack overflow.
+     283             : #ifdef _OPENMP
+     284             : #if _OPENMP >= 201307
+     285             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     286             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     287             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     288             : #endif
+     289             : #endif
+     290             : 
+     291             : #ifdef _OPENMP
+     292             : #if _OPENMP >= 201307
+     293           3 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, TailPosition, x, aux) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     294             : #endif
+     295             : #endif
+     296             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     297             :   {
+     298             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     299             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     300             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     301             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     302             :     {
+     303             :       analyzeThisParticle_Mem[i] = 1.0;
+     304             :       // Defining the slices to analyze each particle.
+     305             :       if (PositionS_Mem < 1)
+     306             :       {
+     307             :         s1_Mem[i] = 0;
+     308             :         s2_Mem[i] = 2;
+     309             :       }
+     310             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     311             :       {
+     312             :         s1_Mem[i] = floor(PositionS_Mem) - 1;
+     313             :         s2_Mem[i] = floor(PositionS_Mem) + 1;
+     314             :       }
+     315             :       else
+     316             :       {
+     317             :         s1_Mem[i] = NSMEM[0] - 3;
+     318             :         s2_Mem[i] = NSMEM[0] - 1;
+     319             :       }
+     320             : 
+     321             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     322             : 
+     323             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     324             :       {
+     325             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     326             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     327             :         {
+     328             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     329             :           {
+     330             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     331             :             Fs_Mem[s] += 1.0;
+     332             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     333             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     334             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     335             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     336             :           }
+     337             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     338             :           {
+     339             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     340             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     341             :             d_faxial_Mem_dz[i + TAILS.size() * s] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * 2.0 / DSMEM[0];
+     342             :             Fs_Mem[s] += aux;
+     343             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     344             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     345             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     346             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     347             :           }
+     348             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     349             :           {
+     350             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     351             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     352             :             d_faxial_Mem_dz[i + TAILS.size() * s] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * 2.0 / DSMEM[0];
+     353             :             Fs_Mem[s] += aux;
+     354             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     355             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     356             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     357             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     358             :           }
+     359             :         }
+     360             :       }
+     361             :     }
+     362             :   }
+     363             : 
+     364         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     365             :   {
+     366         210 :     if (Fs_Mem[s] != 0.0)
+     367             :     {
+     368         106 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     369         106 :       W_Mem += ws_Mem[s];
+     370         106 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     371         106 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     372         106 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     373         106 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     374         106 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     375         106 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     376         106 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     377         106 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     378             :     }
+     379             :   }
+     380             : 
+     381           3 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     382           3 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     383           3 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     384           3 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     385             : 
+     386             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     387             :   double Xcyl_Mem, Ycyl_Mem;
+     388             : 
+     389           3 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     390             :   {
+     391             :     Xcyl_Mem = XCYL[0];
+     392             :     Ycyl_Mem = YCYL[0];
+     393             :   }
+     394             :   else
+     395             :   {
+     396           3 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     397           3 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     398             :   }
+     399             : 
+     400             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     401             :   double d_sx_Mem_dx, d_sx_Mem_dz, d_sy_Mem_dy, d_sy_Mem_dz, d_cx_Mem_dx, d_cx_Mem_dz, d_cy_Mem_dy, d_cy_Mem_dz;
+     402             : 
+     403             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     404             :   double d_ws_Mem_dz;
+     405             : 
+     406             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     407             :   double d_Xsc_Mem_dx, d_Xsc_Mem_dz, d_Xcc_Mem_dx, d_Xcc_Mem_dz, d_Ysc_Mem_dy, d_Ysc_Mem_dz, d_Ycc_Mem_dy, d_Ycc_Mem_dz;
+     408             : 
+     409             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     410           3 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     411             : 
+     412             :   // Distances from the lipid tails to center of the cylinder.
+     413           3 :   std::vector<Vector> CylDistances_Mem(TAILS.size());
+     414             : 
+     415             :   // XY distance from the lipid tails to the center of the cylinder.
+     416             :   double ri_Mem;
+     417             : 
+     418             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     419             :   double fradial_Mem = 0;
+     420             : 
+     421             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     422           3 :   std::vector<double> d_fradial_Mem_dx(TAILS.size()), d_fradial_Mem_dy(TAILS.size());
+     423             : 
+     424             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     425           3 :   std::vector<double> d_Xcyl_Mem_dx(TAILS.size()), d_Xcyl_Mem_dz(TAILS.size()), d_Ycyl_Mem_dy(TAILS.size()), d_Ycyl_Mem_dz(TAILS.size());
+     426             : 
+     427             :   // To avoid rare instabilities auxX_Mem and auxY_Mem are truncated at a configurable value (default = 500).
+     428           3 :   double auxX_Mem = (1 / (pow(Xsc_Mem, 2) + pow(Xcc_Mem, 2))), auxY_Mem = (1 / (pow(Ysc_Mem, 2) + pow(Ycc_Mem, 2)));
+     429             : 
+     430           3 :   if (auxX_Mem > ONEOVERS2C2CUTOFF[0])
+     431             :   {
+     432           0 :     auxX_Mem = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     433             :   }
+     434             :   else
+     435             :   {
+     436           3 :     auxX_Mem = Lx * auxX_Mem / (2 * M_PI);
+     437             :   }
+     438             : 
+     439           3 :   if (auxY_Mem > ONEOVERS2C2CUTOFF[0])
+     440             :   {
+     441           0 :     auxY_Mem = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     442             :   }
+     443             :   else
+     444             :   {
+     445           3 :     auxY_Mem = Ly * auxY_Mem / (2 * M_PI);
+     446             :   }
+     447             : 
+     448             :   // Number of lipid tails within the slice s of the membranes cylinder.
+     449           3 :   std::vector<double> Nsp_Mem(NSMEM[0]), psi_Mem(NSMEM[0]), d_psi_Mem(NSMEM[0]);
+     450             : 
+     451             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     452           3 :   double b_Mem = (ZETAMEM[0] / (1.0 - ZETAMEM[0])), c_Mem = ((1.0 - ZETAMEM[0]) * exp(b_Mem));
+     453             : 
+     454             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     455           3 :   std::vector<double> fradial_Mem_d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     456             : 
+     457             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     458           3 :   std::vector<double> Axs_Mem(NSMEM[0]), Ays_Mem(NSMEM[0]);
+     459             : 
+     460             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     461           3 :   double Xi_Mem = 0.0;
+     462             : 
+     463             : #ifdef _OPENMP
+     464             : #if _OPENMP >= 201307
+     465           3 :   #pragma omp parallel for private(TailPosition,d_Xsc_Mem_dx,d_Xcc_Mem_dx,d_Ysc_Mem_dy,d_Ycc_Mem_dy,d_Xsc_Mem_dz,d_Xcc_Mem_dz,d_Ysc_Mem_dz,d_Ycc_Mem_dz,d_sx_Mem_dx,d_sy_Mem_dy,d_cx_Mem_dx,d_cy_Mem_dy,d_sx_Mem_dz,d_sy_Mem_dz,d_cx_Mem_dz,d_cy_Mem_dz,d_ws_Mem_dz,ri_Mem,x,fradial_Mem) reduction(vec_double_plus: Nsp_Mem, Axs_Mem, Ays_Mem)
+     466             : #endif
+     467             : #endif
+     468             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     469             :   {
+     470             :     if (analyzeThisParticle_Mem[i])
+     471             :     {
+     472             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     473             :       d_Xsc_Mem_dx = 0.0;
+     474             :       d_Xcc_Mem_dx = 0.0;
+     475             :       d_Ysc_Mem_dy = 0.0;
+     476             :       d_Ycc_Mem_dy = 0.0;
+     477             :       d_Xsc_Mem_dz = 0.0;
+     478             :       d_Xcc_Mem_dz = 0.0;
+     479             :       d_Ysc_Mem_dz = 0.0;
+     480             :       d_Ycc_Mem_dz = 0.0;
+     481             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     482             :       {
+     483             :         if (Fs_Mem[s] != 0.0)
+     484             :         {
+     485             :           d_sx_Mem_dx = faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * cos(2.0 * M_PI * TailPosition[0]) / (Lx * Fs_Mem[s]);
+     486             :           d_sy_Mem_dy = faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * cos(2.0 * M_PI * TailPosition[1]) / (Ly * Fs_Mem[s]);
+     487             :           d_cx_Mem_dx = -faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * sin(2.0 * M_PI * TailPosition[0]) / (Lx * Fs_Mem[s]);
+     488             :           d_cy_Mem_dy = -faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * sin(2.0 * M_PI * TailPosition[1]) / (Ly * Fs_Mem[s]);
+     489             :           d_Xsc_Mem_dx += ws_Mem[s] * d_sx_Mem_dx / W_Mem;
+     490             :           d_Xcc_Mem_dx += ws_Mem[s] * d_cx_Mem_dx / W_Mem;
+     491             :           d_Ysc_Mem_dy += ws_Mem[s] * d_sy_Mem_dy / W_Mem;
+     492             :           d_Ycc_Mem_dy += ws_Mem[s] * d_cy_Mem_dy / W_Mem;
+     493             : 
+     494             :           d_sx_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (sin(2.0 * M_PI * TailPosition[0]) - sx_Mem[s]) / Fs_Mem[s];
+     495             :           d_sy_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (sin(2.0 * M_PI * TailPosition[1]) - sy_Mem[s]) / Fs_Mem[s];
+     496             :           d_cx_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (cos(2.0 * M_PI * TailPosition[0]) - cx_Mem[s]) / Fs_Mem[s];
+     497             :           d_cy_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (cos(2.0 * M_PI * TailPosition[1]) - cy_Mem[s]) / Fs_Mem[s];
+     498             :           d_ws_Mem_dz = (1 - pow(ws_Mem[s], 2)) * d_faxial_Mem_dz[i + TAILS.size() * s];
+     499             :           d_Xsc_Mem_dz += (ws_Mem[s] * d_sx_Mem_dz + d_ws_Mem_dz * (sx_Mem[s] - Xsc_Mem)) / W_Mem;
+     500             :           d_Xcc_Mem_dz += (ws_Mem[s] * d_cx_Mem_dz + d_ws_Mem_dz * (cx_Mem[s] - Xcc_Mem)) / W_Mem;
+     501             :           d_Ysc_Mem_dz += (ws_Mem[s] * d_sy_Mem_dz + d_ws_Mem_dz * (sy_Mem[s] - Ysc_Mem)) / W_Mem;
+     502             :           d_Ycc_Mem_dz += (ws_Mem[s] * d_cy_Mem_dz + d_ws_Mem_dz * (cy_Mem[s] - Ycc_Mem)) / W_Mem;
+     503             :         }
+     504             :       }
+     505             :       d_Xcyl_Mem_dx[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dx + Xcc_Mem * d_Xsc_Mem_dx);
+     506             :       d_Xcyl_Mem_dz[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dz + Xcc_Mem * d_Xsc_Mem_dz);
+     507             :       d_Ycyl_Mem_dy[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dy + Ycc_Mem * d_Ysc_Mem_dy);
+     508             :       d_Ycyl_Mem_dz[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dz + Ycc_Mem * d_Ysc_Mem_dz);
+     509             : 
+     510             :       CylDistances_Mem[i] = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     511             :       ri_Mem = sqrt(pow(CylDistances_Mem[i][0], 2) + pow(CylDistances_Mem[i][1], 2));
+     512             :       x = ri_Mem / RCYLMEM[0];
+     513             :       if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     514             :       {
+     515             :         if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     516             :         {
+     517             :           fradial_Mem = 1.0;
+     518             :         }
+     519             :         else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     520             :         {
+     521             :           fradial_Mem = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     522             :           d_fradial_Mem_dx[i] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][0] / (RCYLMEM[0] * ri_Mem);
+     523             :           d_fradial_Mem_dy[i] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][1] / (RCYLMEM[0] * ri_Mem);
+     524             :         }
+     525             :         else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     526             :         {
+     527             :           fradial_Mem = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     528             :           d_fradial_Mem_dx[i] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][0] / (RCYLMEM[0] * ri_Mem);
+     529             :           d_fradial_Mem_dy[i] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][1] / (RCYLMEM[0] * ri_Mem);
+     530             :         }
+     531             : 
+     532             :         for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     533             :         {
+     534             :           Nsp_Mem[s] += fradial_Mem * faxial_Mem[i + TAILS.size() * s];
+     535             :           Axs_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dx[i];
+     536             :           Ays_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dy[i];
+     537             :           fradial_Mem_d_faxial_Mem_dz[i + TAILS.size() * s] = fradial_Mem * d_faxial_Mem_dz[i + TAILS.size() * s];
+     538             :         }
+     539             :       }
+     540             :     }
+     541             :   }
+     542             : 
+     543         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     544             :   {
+     545         210 :     if (Nsp_Mem[s] <= 1.0)
+     546             :     {
+     547         166 :       psi_Mem[s] = ZETAMEM[0] * Nsp_Mem[s];
+     548         166 :       d_psi_Mem[s] = ZETAMEM[0];
+     549         166 :       Xi_Mem += psi_Mem[s];
+     550             :     }
+     551             :     else
+     552             :     {
+     553          44 :       psi_Mem[s] = 1.0 - c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     554          44 :       d_psi_Mem[s] = b_Mem * c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     555          44 :       Xi_Mem += psi_Mem[s];
+     556             :     }
+     557             :   }
+     558             : 
+     559           3 :   Xi_Mem = Xi_Mem / NSMEM[0];
+     560             : 
+     561             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     562           3 :   std::vector<double> faxial_Mem_d_fradial_Mem_dx(TAILS.size() * NSMEM[0]), faxial_Mem_d_fradial_Mem_dy(TAILS.size() * NSMEM[0]), faxial_Mem_d_fradial_Mem_dz(TAILS.size() * NSMEM[0]);
+     563             : 
+     564             :   // Eq. 13 Hub & Awasthi JCTC 2017.
+     565           3 :   std::vector<Vector> derivatives_Mem(TAILS.size());
+     566             : 
+     567             : #ifdef _OPENMP
+     568             : #if _OPENMP >= 201307
+     569           3 :   #pragma omp parallel for private(aux)
+     570             : #endif
+     571             : #endif
+     572             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     573             :   {
+     574             :     if (analyzeThisParticle_Mem[i])
+     575             :     {
+     576             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     577             :       {
+     578             :         if (faxial_Mem[i + TAILS.size() * s])
+     579             :         {
+     580             :           faxial_Mem_d_fradial_Mem_dx[i + TAILS.size() * s] = faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dx[i] - d_Xcyl_Mem_dx[i] * Axs_Mem[s];
+     581             :           faxial_Mem_d_fradial_Mem_dy[i + TAILS.size() * s] = faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dy[i] - d_Ycyl_Mem_dy[i] * Ays_Mem[s];
+     582             :           faxial_Mem_d_fradial_Mem_dz[i + TAILS.size() * s] = -d_Xcyl_Mem_dz[i] * Axs_Mem[s] - d_Ycyl_Mem_dz[i] * Ays_Mem[s];
+     583             :         }
+     584             :       }
+     585             : 
+     586             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     587             :       {
+     588             :         aux = d_psi_Mem[s] / NSMEM[0];
+     589             :         derivatives_Mem[i][0] += aux * faxial_Mem_d_fradial_Mem_dx[i + TAILS.size() * s];
+     590             :         derivatives_Mem[i][1] += aux * faxial_Mem_d_fradial_Mem_dy[i + TAILS.size() * s];
+     591             :         derivatives_Mem[i][2] += aux * (faxial_Mem_d_fradial_Mem_dz[i + TAILS.size() * s] + fradial_Mem_d_faxial_Mem_dz[i + TAILS.size() * s]);
+     592             :       }
+     593             :     }
+     594             :   }
+     595             : 
+     596             :   // Derivatives and virial for the Xi_Mem.
+     597           3 :   Tensor virial;
+     598       12291 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     599             :   {
+     600       12288 :     setAtomsDerivatives((i + membraneBeads), derivatives_Mem[i]);
+     601       12288 :     virial -= Tensor(CylDistances_Mem[i], derivatives_Mem[i]);
+     602             :   }
+     603             : 
+     604           3 :   setValue(Xi_Mem);
+     605           3 :   setBoxDerivatives(virial);
+     606           3 : }
+     607             : }
+     608             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index-sort-f.html b/coverage/membranefusion/index-sort-f.html new file mode 100644 index 0000000000..cd6e3abc72 --- /dev/null +++ b/coverage/membranefusion/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-05-27 13:05:14Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15885.7 %6 / 7
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15185.7 %6 / 7
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20885.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index-sort-l.html b/coverage/membranefusion/index-sort-l.html new file mode 100644 index 0000000000..0613c1a6d1 --- /dev/null +++ b/coverage/membranefusion/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-05-27 13:05:14Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15885.7 %6 / 7
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20885.7 %6 / 7
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15185.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index.html b/coverage/membranefusion/index.html new file mode 100644 index 0000000000..d60fd54700 --- /dev/null +++ b/coverage/membranefusion/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45651788.2 %
Date:2024-05-27 13:05:14Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %138 / 15885.7 %6 / 7
FusionPoreNucleationP.cpp +
88.5%88.5%
+
88.5 %184 / 20885.7 %6 / 7
MemFusionP.cpp +
88.7%88.7%
+
88.7 %134 / 15185.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html b/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html new file mode 100644 index 0000000000..87752447b3 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE40
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.func.html b/coverage/multicolvar/ActionVolume.cpp.func.html new file mode 100644 index 0000000000..7cd728a775 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.gcov.html b/coverage/multicolvar/ActionVolume.cpp.gcov.html new file mode 100644 index 0000000000..5b8b149ca2 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.gcov.html @@ -0,0 +1,160 @@ + + + + + + + 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-05-27 13:05: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          40 : void ActionVolume::registerKeywords( Keywords& keys ) {
+      28          40 :   VolumeGradientBase::registerKeywords( keys );
+      29         120 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30         120 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN");
+      31         120 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("SUM");
+      32          80 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      33          80 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      34          80 :   keys.addFlag("OUTSIDE",false,"calculate quantities for colvars that are on atoms outside the region of interest");
+      35          40 : }
+      36             : 
+      37          28 : ActionVolume::ActionVolume(const ActionOptions&ao):
+      38             :   Action(ao),
+      39          28 :   VolumeGradientBase(ao)
+      40             : {
+      41             :   // Find number of quantities
+      42          28 :   if( getPntrToMultiColvar()->isDensity() ) nquantities=2;                           // Value + weight
+      43          17 :   else if( getPntrToMultiColvar()->getNumberOfQuantities()==2 ) nquantities=2;       // Value + weight
+      44           2 :   else nquantities = 1 + getPntrToMultiColvar()->getNumberOfQuantities()-2 + 1;      // Norm  + vector + weight
+      45             : 
+      46             :   // Output some nice information
+      47          28 :   std::string functype=getPntrToMultiColvar()->getName();
+      48         279 :   std::transform( functype.begin(), functype.end(), functype.begin(), [](unsigned char c) { return std::tolower(c); } );
+      49          28 :   log.printf("  calculating %s inside region of insterest\n",functype.c_str() );
+      50             : 
+      51          28 :   parseFlag("OUTSIDE",not_in); sigma=0.0;
+      52          81 :   if( keywords.exists("SIGMA") ) parse("SIGMA",sigma);
+      53          84 :   if( keywords.exists("KERNEL") ) parse("KERNEL",kerneltype);
+      54             : 
+      55          28 :   if( getPntrToMultiColvar()->isDensity() ) {
+      56             :     std::string input;
+      57          22 :     addVessel( "SUM", input, -1 );  // -1 here means that this value will be named getLabel()
+      58             :   }
+      59          28 :   readVesselKeywords();
+      60          28 : }
+      61             : 
+      62       69358 : void ActionVolume::calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const {
+      63       69358 :   Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );
+      64             : 
+      65       69358 :   double weight; Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
+      66       69358 :   weight=calculateNumberInside( catom_pos, wdf, vir, refders );
+      67       69358 :   if( not_in ) {
+      68        4000 :     weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+      69        8000 :     for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+      70             :   }
+      71       69358 :   setNumberInVolume( 0, curr, weight, wdf, vir, refders, outvals );
+      72       69358 : }
+      73             : 
+      74      148129 : bool ActionVolume::inVolumeOfInterest( const unsigned& curr ) const {
+      75      148129 :   Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );
+      76      148129 :   Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
+      77      148129 :   double weight=calculateNumberInside( catom_pos, wdf, vir, refders );
+      78      148129 :   if( not_in ) weight = 1.0 - weight;
+      79      148129 :   if( weight<getTolerance() ) return false;
+      80             :   return true;
+      81             : }
+      82             : 
+      83             : }
+      84             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.func-sort-c.html b/coverage/multicolvar/ActionVolume.h.func-sort-c.html new file mode 100644 index 0000000000..89f36d78db --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.func.html b/coverage/multicolvar/ActionVolume.h.func.html new file mode 100644 index 0000000000..0e3ff52749 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.gcov.html b/coverage/multicolvar/ActionVolume.h.gcov.html new file mode 100644 index 0000000000..dfcbd73fbe --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html new file mode 100644 index 0000000000..ae3964ef9a --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func.html b/coverage/multicolvar/AlphaBeta.cpp.func.html new file mode 100644 index 0000000000..a53658ceaf --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe1066createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122AlphaBetaRegisterMe106D2Ev4168
_ZN4PLMD11multicolvar9AlphaBeta10isPeriodicEv0
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.gcov.html b/coverage/multicolvar/AlphaBeta.cpp.gcov.html new file mode 100644 index 0000000000..aa4b46d006 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.gcov.html @@ -0,0 +1,280 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(AlphaBeta,"ALPHABETA")
+     107             : 
+     108           3 : void AlphaBeta::registerKeywords( Keywords& keys ) {
+     109           3 :   MultiColvarBase::registerKeywords( keys );
+     110           6 :   keys.add("numbered","ATOMS","the atoms involved in each of the alpha-beta variables you wish to calculate. "
+     111             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one alpha-beta values will be "
+     112             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     113             :            "specify the indices of four atoms).  The eventual number of quantities calculated by this "
+     114             :            "action will depend on what functions of the distribution you choose to calculate.");
+     115           6 :   keys.reset_style("ATOMS","atoms");
+     116           6 :   keys.add("numbered","REFERENCE","the reference values for each of the torsional angles.  If you use a single REFERENCE value the "
+     117             :            "same reference value is used for all torsional angles");
+     118           6 :   keys.add("numbered","COEFFICIENT","the coefficient for each of the torsional angles.  If you use a single COEFFICIENT value the "
+     119             :            "same reference value is used for all torsional angles");
+     120           6 :   keys.reset_style("REFERENCE","compulsory");
+     121           6 :   keys.reset_style("COEFFICIENT","optional");
+     122           3 : }
+     123             : 
+     124           1 : AlphaBeta::AlphaBeta(const ActionOptions&ao):
+     125             :   Action(ao),
+     126           1 :   MultiColvarBase(ao)
+     127             : {
+     128             :   // Read in the atoms
+     129             :   std::vector<AtomNumber> all_atoms;
+     130           1 :   readAtomsLikeKeyword( "ATOMS", 4, all_atoms );
+     131           1 :   setupMultiColvarBase( all_atoms );
+     132             :   // Resize target
+     133           1 :   target.resize( getFullNumberOfTasks() );
+     134             :   // Resize coeff
+     135           1 :   coefficient.resize( getFullNumberOfTasks(), 1.0);
+     136             :   // Setup central atom indices
+     137           1 :   std::vector<bool> catom_ind(4, false);
+     138           1 :   catom_ind[1]=catom_ind[2]=true;
+     139           1 :   setAtomsForCentralAtom( catom_ind );
+     140             : 
+     141             :   // Read in reference values
+     142             :   unsigned ntarget=0;
+     143           1 :   for(unsigned i=0; i<target.size(); ++i) {
+     144           2 :     if( !parseNumbered( "REFERENCE", i+1, target[i] ) ) break;
+     145           0 :     ntarget++;
+     146             :   }
+     147           1 :   if( ntarget==0 ) {
+     148           1 :     parse("REFERENCE",target[0]);
+     149           8 :     for(unsigned i=1; i<target.size(); ++i) target[i]=target[0];
+     150           0 :   } else if( ntarget!=target.size() ) {
+     151           0 :     error("found wrong number of REFERENCE values");
+     152             :   }
+     153             : 
+     154             :   // Read in reference values
+     155             :   unsigned ncoefficient=0;
+     156           1 :   for(unsigned i=0; i<coefficient.size(); ++i) {
+     157           2 :     if( !parseNumbered( "COEFFICIENT", i+1, coefficient[i] ) ) break;
+     158           0 :     ncoefficient++;
+     159             :   }
+     160           1 :   if( ncoefficient==0 ) {
+     161           1 :     parse("COEFFICIENT",coefficient[0]);
+     162           8 :     for(unsigned i=1; i<coefficient.size(); ++i) coefficient[i]=coefficient[0];
+     163           0 :   } else if( ncoefficient !=coefficient.size() ) {
+     164           0 :     error("found wrong number of COEFFICIENT values");
+     165             :   }
+     166             : 
+     167             :   // And setup the ActionWithVessel
+     168           1 :   if( getNumberOfVessels()==0 ) {
+     169             :     std::string fake_input;
+     170           1 :     addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     171           1 :     readVesselKeywords();  // This makes sure resizing is done
+     172             :   }
+     173             : 
+     174             :   // And check everything has been read in correctly
+     175           1 :   checkRead();
+     176           1 : }
+     177             : 
+     178          40 : double AlphaBeta::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     179          40 :   const Vector d0=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     180          40 :   const Vector d1=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     181          40 :   const Vector d2=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     182             : 
+     183          40 :   Vector dd0,dd1,dd2;
+     184             :   PLMD::Torsion t;
+     185          40 :   const double value  = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     186          40 :   const double svalue = -0.5*coefficient[tindex]*std::sin(value-target[tindex]);
+     187          40 :   const double cvalue = coefficient[tindex]*(1.+std::cos(value-target[tindex]));
+     188             : 
+     189          40 :   dd0 *= svalue;
+     190          40 :   dd1 *= svalue;
+     191          40 :   dd2 *= svalue;
+     192             : 
+     193          40 :   addAtomDerivatives(1, 0, dd0, myatoms);
+     194          40 :   addAtomDerivatives(1, 1, dd1-dd0, myatoms);
+     195          40 :   addAtomDerivatives(1, 2, dd2-dd1, myatoms);
+     196          40 :   addAtomDerivatives(1, 3, -dd2, myatoms);
+     197             : 
+     198          40 :   myatoms.addBoxDerivatives(1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
+     199             : 
+     200          40 :   return 0.5*cvalue;
+     201             : }
+     202             : 
+     203             : }
+     204             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func-sort-c.html b/coverage/multicolvar/Angles.cpp.func-sort-c.html new file mode 100644 index 0000000000..da34ba3ccf --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101D2Ev4168
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func.html b/coverage/multicolvar/Angles.cpp.func.html new file mode 100644 index 0000000000..c87e8f48db --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119AnglesRegisterMe101D2Ev4168
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.gcov.html b/coverage/multicolvar/Angles.cpp.gcov.html new file mode 100644 index 0000000000..b14fd1ad39 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.gcov.html @@ -0,0 +1,296 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(Angles,"ANGLES")
+     102             : 
+     103           4 : void Angles::registerKeywords( Keywords& keys ) {
+     104           4 :   MultiColvarBase::registerKeywords( keys );
+     105           8 :   keys.use("MEAN"); keys.use("LESS_THAN");
+     106          12 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MORE_THAN");
+     107             :   // Could also add Region here in theory
+     108           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the angles you wish to calculate. "
+     109             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one angle will be "
+     110             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     111             :            "provide the indices of three atoms).  The eventual number of quantities calculated by this "
+     112             :            "action will depend on what functions of the distribution you choose to calculate.");
+     113           8 :   keys.reset_style("ATOMS","atoms");
+     114           8 :   keys.add("atoms-1","GROUP","Calculate angles for each distinct set of three atoms in the group");
+     115           8 :   keys.add("atoms-2","GROUPA","A group of central atoms about which angles should be calculated");
+     116           8 :   keys.add("atoms-2","GROUPB","When used in conjunction with GROUPA this keyword instructs plumed "
+     117             :            "to calculate all distinct angles involving one atom from GROUPA "
+     118             :            "and two atoms from GROUPB. The atom from GROUPA is the central atom.");
+     119           8 :   keys.add("atoms-3","GROUPC","This must be used in conjunction with GROUPA and GROUPB.  All angles "
+     120             :            "involving one atom from GROUPA, one atom from GROUPB and one atom from "
+     121             :            "GROUPC are calculated. The GROUPA atoms are assumed to be the central "
+     122             :            "atoms");
+     123           8 :   keys.add("optional","SWITCH","A switching function that ensures that only angles between atoms that "
+     124             :            "are within a certain fixed cutoff are calculated. The following provides "
+     125             :            "information on the \\ref switchingfunction that are available.");
+     126           8 :   keys.add("optional","SWITCHA","A switching function on the distance between the atoms in group A and the atoms in "
+     127             :            "group B");
+     128           8 :   keys.add("optional","SWITCHB","A switching function on the distance between the atoms in group A and the atoms in "
+     129             :            "group B");
+     130           4 : }
+     131             : 
+     132           2 : Angles::Angles(const ActionOptions&ao):
+     133             :   Action(ao),
+     134             :   MultiColvarBase(ao),
+     135           2 :   use_sf(false)
+     136             : {
+     137           4 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     138           2 :   if( sfinput.length()>0 ) {
+     139           2 :     use_sf=true;
+     140           2 :     weightHasDerivatives=true;
+     141           2 :     sf1.set(sfinput,errors);
+     142           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     143           2 :     sf2.set(sfinput,errors);
+     144           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     145           4 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     146             :   } else {
+     147           0 :     parse("SWITCHA",sfinput);
+     148           0 :     if(sfinput.length()>0) {
+     149           0 :       use_sf=true;
+     150           0 :       weightHasDerivatives=true;
+     151           0 :       sf1.set(sfinput,errors);
+     152           0 :       if( errors.length()!=0 ) error("problem reading SWITCHA keyword : " + errors );
+     153           0 :       sfinput.clear(); parse("SWITCHB",sfinput);
+     154           0 :       if(sfinput.length()==0) error("found SWITCHA keyword without SWITCHB");
+     155           0 :       sf2.set(sfinput,errors);
+     156           0 :       if( errors.length()!=0 ) error("problem reading SWITCHB keyword : " + errors );
+     157           0 :       log.printf("  only calculating angles when the distance between GROUPA and GROUPB atoms is less than %s\n", sf1.description().c_str() );
+     158           0 :       log.printf("  only calculating angles when the distance between GROUPA and GROUPC atoms is less than %s\n", sf2.description().c_str() );
+     159             :     }
+     160             :   }
+     161             :   // Read in the atoms
+     162             :   std::vector<AtomNumber> all_atoms;
+     163           4 :   readGroupKeywords( "GROUP", "GROUPA", "GROUPB", "GROUPC", false, true, all_atoms );
+     164           2 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 3, all_atoms );
+     165           2 :   setupMultiColvarBase( all_atoms );
+     166             :   // Set cutoff for link cells
+     167           2 :   if( use_sf ) {
+     168           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     169           2 :     rcut2_1=sf1.get_dmax()*sf1.get_dmax();
+     170           2 :     rcut2_2=sf2.get_dmax()*sf2.get_dmax();
+     171             :   }
+     172             : 
+     173             :   // And check everything has been read in correctly
+     174           2 :   checkRead();
+     175             :   // Setup stuff for central atom
+     176           2 :   std::vector<bool> catom_ind(3, false); catom_ind[0]=true;
+     177           2 :   setAtomsForCentralAtom( catom_ind );
+     178           2 : }
+     179             : 
+     180       48510 : double Angles::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     181       48510 :   if(!use_sf) return 1.0;
+     182       48510 :   Vector dij=getSeparation( myatoms.getPosition(0), myatoms.getPosition(2) );
+     183       48510 :   Vector dik=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     184             : 
+     185             :   double w1, w2, dw1, dw2, wtot;
+     186       48510 :   double ldij = dij.modulo2(), ldik = dik.modulo2();
+     187             : 
+     188       48510 :   if( use_sf ) {
+     189       48510 :     if( ldij>rcut2_1 || ldik>rcut2_2 ) return 0.0;
+     190             :   }
+     191             : 
+     192       48510 :   w1=sf1.calculateSqr( ldij, dw1 );
+     193       48510 :   w2=sf2.calculateSqr( ldik, dw2 );
+     194       48510 :   wtot=w1*w2; dw1*=weight*w2; dw2*=weight*w1;
+     195             : 
+     196       48510 :   addAtomDerivatives( 0, 1, dw2*dik, myatoms );
+     197       48510 :   addAtomDerivatives( 0, 0, -dw1*dij - dw2*dik, myatoms );
+     198       48510 :   addAtomDerivatives( 0, 2, dw1*dij, myatoms );
+     199       48510 :   myatoms.addBoxDerivatives( 0, (-dw1)*Tensor(dij,dij) + (-dw2)*Tensor(dik,dik) );
+     200       48510 :   return wtot;
+     201             : }
+     202             : 
+     203       26964 : double Angles::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     204       26964 :   Vector dij=getSeparation( myatoms.getPosition(0), myatoms.getPosition(2) );
+     205       26964 :   Vector dik=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     206             : 
+     207       26964 :   Vector ddij,ddik; PLMD::Angle a;
+     208       26964 :   double angle=a.compute(dij,dik,ddij,ddik);
+     209             : 
+     210             :   // And finish the calculation
+     211       26964 :   addAtomDerivatives( 1, 1, ddik, myatoms );
+     212       26964 :   addAtomDerivatives( 1, 0, - ddik - ddij, myatoms );
+     213       26964 :   addAtomDerivatives( 1, 2, ddij, myatoms );
+     214       26964 :   myatoms.addBoxDerivatives( 1, -(Tensor(dij,ddij)+Tensor(dik,ddik)) );
+     215             : 
+     216       26964 :   return angle;
+     217             : }
+     218             : 
+     219             : }
+     220             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html b/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html new file mode 100644 index 0000000000..dcee7ee28b --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE220663
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE448077
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv516365
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE905762
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.func.html b/coverage/multicolvar/AtomValuePack.cpp.func.html new file mode 100644 index 0000000000..bce78bfac8 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE905762
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv516365
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE220663
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE448077
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.gcov.html b/coverage/multicolvar/AtomValuePack.cpp.gcov.html new file mode 100644 index 0000000000..0ade3e7d9e --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + 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-05-27 13:05: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      448077 : AtomValuePack::AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv ):
+      30      448077 :   myvals(vals),
+      31      448077 :   mycolv(mcolv),
+      32      448077 :   natoms(0),
+      33      448077 :   indices( vals.getIndices() ),
+      34      448077 :   sort_vector( vals.getSortIndices() ),
+      35      448077 :   myatoms( vals.getAtomVector() )
+      36             : {
+      37      448077 :   if( indices.size()!=mcolv->getNumberOfAtoms() ) {
+      38       23863 :     indices.resize( mcolv->getNumberOfAtoms() );
+      39       23863 :     sort_vector.resize( mcolv->getNumberOfAtoms() );
+      40       23863 :     myatoms.resize( mcolv->getNumberOfAtoms() );
+      41             :   }
+      42      448077 : }
+      43             : 
+      44      220663 : unsigned AtomValuePack::setupAtomsFromLinkCells( const std::vector<unsigned>& cind, const Vector& cpos, const LinkCells& linkcells ) {
+      45      220663 :   if( cells_required.size()!=linkcells.getNumberOfCells() ) cells_required.resize( linkcells.getNumberOfCells() );
+      46             :   // Build the list of cells that we need
+      47      220663 :   unsigned ncells_required=0; linkcells.addRequiredCells( linkcells.findMyCell( cpos ), ncells_required, cells_required );
+      48             :   // Now build the list of atoms we need
+      49      481142 :   natoms=cind.size(); for(unsigned i=0; i<natoms; ++i) indices[i]=cind[i];
+      50      220663 :   linkcells.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+      51             : //  linkcells.retrieveNeighboringAtoms( cpos, natoms, indices );
+      52   404345371 :   for(unsigned i=0; i<natoms; ++i) myatoms[i]=mycolv->getPositionOfAtomForLinkCells( indices[i] ) - cpos;
+      53      220663 :   if( mycolv->usesPbc() ) mycolv->applyPbc( myatoms, natoms );
+      54      220663 :   return natoms;
+      55             : }
+      56             : 
+      57      516365 : void AtomValuePack::updateUsingIndices() {
+      58      516365 :   if( myvals.updateComplete() ) return;
+      59             : 
+      60             :   unsigned jactive=0;
+      61   402807162 :   for(unsigned i=0; i<natoms; ++i) {
+      62   402492393 :     unsigned base=3*indices[i];
+      63   402492393 :     if( myvals.isActive( base ) ) { sort_vector[jactive]=indices[i]; jactive++; }
+      64             :   }
+      65      314769 :   std::sort( sort_vector.begin(), sort_vector.begin()+jactive );
+      66             : 
+      67      314769 :   myvals.emptyActiveMembers();
+      68     4413816 :   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      314769 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+      75      314769 :   if( myvals.isActive( nvir ) ) {
+      76     2060650 :     for(unsigned i=0; i<9; ++i) myvals.putIndexInActiveArray( nvir + i );
+      77             :   }
+      78      314769 :   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.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.func-sort-c.html b/coverage/multicolvar/AtomValuePack.h.func-sort-c.html new file mode 100644 index 0000000000..c89af5f041 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.func.html b/coverage/multicolvar/AtomValuePack.h.func.html new file mode 100644 index 0000000000..c7bb2787e6 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.gcov.html b/coverage/multicolvar/AtomValuePack.h.gcov.html new file mode 100644 index 0000000000..edd95e4e82 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.gcov.html @@ -0,0 +1,291 @@ + + + + + + + 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-05-27 13:05: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      448023 : 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   524950726 :   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   679827770 :   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   142087490 :   return myatoms[iatom];
+     151             : }
+     152             : 
+     153             : inline
+     154             : void AtomValuePack::setValue( const unsigned& ival, const double& vv ) {
+     155      695731 :   myvals.setValue( ival, vv );
+     156             : }
+     157             : 
+     158             : inline
+     159             : void AtomValuePack::addValue( const unsigned& ival, const double& vv ) {
+     160    62235725 :   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.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.func-sort-c.html b/coverage/multicolvar/Bridge.cpp.func-sort-c.html new file mode 100644 index 0000000000..bbb59beb3f --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.func.html b/coverage/multicolvar/Bridge.cpp.func.html new file mode 100644 index 0000000000..c4f6bfc0f6 --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe736createERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_118BridgeRegisterMe73D2Ev4168
_ZN4PLMD11multicolvar6Bridge10isPeriodicEv0
_ZN4PLMD11multicolvar6Bridge16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD11multicolvar6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6BridgeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.gcov.html b/coverage/multicolvar/Bridge.cpp.gcov.html new file mode 100644 index 0000000000..93fc3bb91d --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(Bridge,"BRIDGE")
+      74             : 
+      75          10 : void Bridge::registerKeywords( Keywords& keys ) {
+      76          10 :   MultiColvarBase::registerKeywords( keys );
+      77          20 :   keys.add("atoms-2","BRIDGING_ATOMS","The list of atoms that can form the bridge between the two interesting parts "
+      78             :            "of the structure.");
+      79          20 :   keys.add("atoms-2","GROUPA","The list of atoms that are in the first interesting part of the structure");
+      80          20 :   keys.add("atoms-2","GROUPB","The list of atoms that are in the second interesting part of the structure");
+      81          20 :   keys.add("optional","SWITCH","The parameters of the two \\ref switchingfunction in the above formula");
+      82          20 :   keys.add("optional","SWITCHA","The \\ref switchingfunction on the distance between bridging atoms and the atoms in "
+      83             :            "group A");
+      84          20 :   keys.add("optional","SWITCHB","The \\ref switchingfunction on the distance between the bridging atoms and the atoms in "
+      85             :            "group B");
+      86          10 : }
+      87             : 
+      88           8 : Bridge::Bridge(const ActionOptions&ao):
+      89             :   Action(ao),
+      90           8 :   MultiColvarBase(ao)
+      91             : {
+      92             :   // Read in the atoms
+      93             :   std::vector<AtomNumber> all_atoms;
+      94          16 :   readThreeGroups("GROUPA","GROUPB","BRIDGING_ATOMS",false,true,all_atoms);
+      95             :   // Setup the multicolvar base
+      96           8 :   setupMultiColvarBase( all_atoms );
+      97             :   // Setup Central atom atoms
+      98           8 :   std::vector<bool> catom_ind(3, false); catom_ind[0]=true;
+      99           8 :   setAtomsForCentralAtom( catom_ind );
+     100             : 
+     101          16 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     102           8 :   if( sfinput.length()>0 ) {
+     103           8 :     sf1.set(sfinput,errors);
+     104           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     105           8 :     sf2.set(sfinput,errors);
+     106           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     107             :   } else {
+     108           0 :     parse("SWITCHA",sfinput);
+     109           0 :     if(sfinput.length()>0) {
+     110           0 :       weightHasDerivatives=true;
+     111           0 :       sf1.set(sfinput,errors);
+     112           0 :       if( errors.length()!=0 ) error("problem reading SWITCHA keyword : " + errors );
+     113           0 :       sfinput.clear(); parse("SWITCHB",sfinput);
+     114           0 :       if(sfinput.length()==0) error("found SWITCHA keyword without SWITCHB");
+     115           0 :       sf2.set(sfinput,errors);
+     116           0 :       if( errors.length()!=0 ) error("problem reading SWITCHB keyword : " + errors );
+     117             :     } else {
+     118           0 :       error("missing definition of switching functions");
+     119             :     }
+     120             :   }
+     121           8 :   log.printf("  distance between bridging atoms and atoms in GROUPA must be less than %s\n",sf1.description().c_str());
+     122           8 :   log.printf("  distance between bridging atoms and atoms in GROUPB must be less than %s\n",sf2.description().c_str());
+     123             : 
+     124             :   // Setup link cells
+     125           8 :   setLinkCellCutoff( sf1.get_dmax() + sf2.get_dmax() );
+     126             : 
+     127             :   // And setup the ActionWithVessel
+     128           8 :   if( getNumberOfVessels()!=0 ) error("should not have vessels for this action");
+     129             :   std::string fake_input;
+     130           8 :   addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     131           8 :   readVesselKeywords();
+     132             :   // And check everything has been read in correctly
+     133           8 :   checkRead();
+     134           8 : }
+     135             : 
+     136         537 : double Bridge::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     137             :   double tot=0;
+     138       21359 :   for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     139       20822 :     Vector dij=getSeparation( myatoms.getPosition(i), myatoms.getPosition(0) );
+     140       20822 :     double dw1, w1=sf1.calculateSqr( dij.modulo2(), dw1 );
+     141       20822 :     Vector dik=getSeparation( myatoms.getPosition(i), myatoms.getPosition(1) );
+     142       20822 :     double dw2, w2=sf2.calculateSqr( dik.modulo2(), dw2 );
+     143             : 
+     144       20822 :     tot += w1*w2;
+     145             :     // And finish the calculation
+     146       20822 :     addAtomDerivatives( 1, 0,  w2*dw1*dij, myatoms );
+     147       20822 :     addAtomDerivatives( 1, 1,  w1*dw2*dik, myatoms );
+     148       20822 :     addAtomDerivatives( 1, i, -w1*dw2*dik-w2*dw1*dij, myatoms );
+     149       20822 :     myatoms.addBoxDerivatives( 1, w1*(-dw2)*Tensor(dik,dik)+w2*(-dw1)*Tensor(dij,dij) );
+     150             :   }
+     151         537 :   return tot;
+     152             : }
+     153             : 
+     154             : }
+     155             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html new file mode 100644 index 0000000000..13c51dd7be --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv45
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html new file mode 100644 index 0000000000..e131b45320 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv45
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html new file mode 100644 index 0000000000..928973e508 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-05-27 13:05: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          70 : void BridgedMultiColvarFunction::registerKeywords( Keywords& keys ) {
+      31          70 :   MultiColvarBase::registerKeywords( keys );
+      32         140 :   keys.add("compulsory","DATA","The multicolvar that calculates the set of base quantities that we are interested in");
+      33          70 : }
+      34             : 
+      35          44 : BridgedMultiColvarFunction::BridgedMultiColvarFunction(const ActionOptions&ao):
+      36             :   Action(ao),
+      37          44 :   MultiColvarBase(ao)
+      38             : {
+      39          44 :   std::string mlab; parse("DATA",mlab);
+      40          44 :   mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+      41          44 :   if(!mycolv) error("action labeled " + mlab + " does not exist or is not a multicolvar");
+      42             : 
+      43             :   // When using numerical derivatives here we must use numerical derivatives
+      44             :   // in base multicolvar
+      45          44 :   if( checkNumericalDerivatives() ) mycolv->useNumericalDerivatives();
+      46             : 
+      47          44 :   myBridgeVessel = mycolv->addBridgingVessel( this ); addDependency(mycolv);
+      48          44 :   weightHasDerivatives=true; usespecies=mycolv->usespecies;
+      49             :   // Number of tasks is the same as the number in the underlying MultiColvar
+      50       20060 :   for(unsigned i=0; i<mycolv->getFullNumberOfTasks(); ++i) addTaskToList( mycolv->getTaskCode(i) );
+      51          44 : }
+      52             : 
+      53          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.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html new file mode 100644 index 0000000000..bda385554d --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html new file mode 100644 index 0000000000..9197280e5a --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html new file mode 100644 index 0000000000..cc189bfc21 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.func-sort-c.html b/coverage/multicolvar/CatomPack.cpp.func-sort-c.html new file mode 100644 index 0000000000..8e107c941b --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.func.html b/coverage/multicolvar/CatomPack.cpp.func.html new file mode 100644 index 0000000000..65d9e4409e --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.gcov.html b/coverage/multicolvar/CatomPack.cpp.gcov.html new file mode 100644 index 0000000000..ef341a8841 --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.gcov.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.func-sort-c.html b/coverage/multicolvar/CatomPack.h.func-sort-c.html new file mode 100644 index 0000000000..d941b28b81 --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE638690
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3179913
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.func.html b/coverage/multicolvar/CatomPack.h.func.html new file mode 100644 index 0000000000..7e28a34f04 --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE638690
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3179913
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.gcov.html b/coverage/multicolvar/CatomPack.h.gcov.html new file mode 100644 index 0000000000..5c8df319c8 --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.gcov.html @@ -0,0 +1,154 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05: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      114695 : class CatomPack {
+      34             : private:
+      35             :   std::vector<unsigned> indices;
+      36             :   std::vector<Tensor> derivs;
+      37             : public:
+      38             :   void resize( const unsigned& );
+      39             :   void setIndex( const unsigned&, const unsigned& );
+      40             :   void setDerivative( const unsigned&, const Tensor& );
+      41             :   unsigned getNumberOfAtomsWithDerivatives() const ;
+      42             :   unsigned getIndex( const unsigned& ) const ;
+      43             :   double getDerivative( const unsigned&, const unsigned&, const Vector& ) const ;
+      44             : };
+      45             : 
+      46             : inline
+      47             : void CatomPack::setIndex( const unsigned& jind, const unsigned& ind ) {
+      48             :   plumed_dbg_assert( jind<indices.size() );
+      49      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.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html new file mode 100644 index 0000000000..760e625579 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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:778096.2 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html new file mode 100644 index 0000000000..73c6c17442 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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:778096.2 %
Date:2024-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131CenterOfMultiColvarRegisterMe96D2Ev4168
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..3ae4d85054 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html @@ -0,0 +1,297 @@ + + + + + + + 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:778096.2 %
Date:2024-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(CenterOfMultiColvar,"CENTER_OF_MULTICOLVAR")
+      97             : 
+      98           5 : void CenterOfMultiColvar::registerKeywords(Keywords& keys) {
+      99           5 :   ActionWithVirtualAtom::registerKeywords(keys);
+     100          10 :   keys.add("compulsory","DATA","find the average value for a multicolvar");
+     101          10 :   keys.add("optional","COMPONENT","if your input multicolvar is a vector then specify which component you would like to use in calculating the weight");
+     102           5 : }
+     103             : 
+     104           3 : CenterOfMultiColvar::CenterOfMultiColvar(const ActionOptions&ao):
+     105             :   Action(ao),
+     106           3 :   ActionWithVirtualAtom(ao)
+     107             : {
+     108           3 :   std::string mlab; parse("DATA",mlab);
+     109           3 :   mycolv= plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+     110           3 :   if(!mycolv) error("action labelled " +  mlab + " does not exist or does not have vessels");
+     111             :   // Copy the atoms from the input multicolvar
+     112           3 :   BridgedMultiColvarFunction* mybr=dynamic_cast<BridgedMultiColvarFunction*>( mycolv );
+     113           3 :   if( mybr ) {
+     114           2 :     requestAtoms( (mybr->getPntrToMultiColvar())->getAbsoluteIndexes() ); comp=1;
+     115             :   } else {
+     116           1 :     if( mycolv->getNumberOfQuantities()>5 ) {
+     117           0 :       int incomp=-1; parse("COMPONENT",incomp);
+     118           0 :       if( incomp<0 ) error("vector input but component was not specified");
+     119           0 :       comp=incomp;
+     120             :     } else {
+     121           1 :       comp=1;
+     122             :     }
+     123           1 :     requestAtoms( mycolv->getAbsoluteIndexes () );
+     124             :   }
+     125             :   // We need the derivatives
+     126           3 :   mycolv->turnOnDerivatives(); addDependency(mycolv);
+     127           3 :   mystash = mycolv->buildDataStashes( NULL );
+     128           3 :   log.printf("  building center of mass based on weights calculated in multicolvar action named %s \n",mycolv->getLabel().c_str() );
+     129           3 : }
+     130             : 
+     131           4 : void CenterOfMultiColvar::calculate() {
+     132             :   // Retrieve the periodic boundary conditions
+     133           4 :   const Pbc& pbc=mycolv->getPbc();
+     134           4 :   if( !pbc.isOrthorombic() ) error("Berry phase does not work for non orthorhombic cells");
+     135             : 
+     136             :   // Create a multivalue to store the derivatives
+     137           4 :   MultiValue myvals( 7, mycolv->getNumberOfDerivatives() ); myvals.clearAll();
+     138           4 :   MultiValue tvals( mycolv->getNumberOfQuantities(), mycolv->getNumberOfDerivatives() );
+     139           4 :   tvals.clearAll();
+     140             : 
+     141             :   // Now loop over all active multicolvars
+     142           4 :   Vector stmp, ctmp, scom, ccom, sder, cder;
+     143           4 :   scom.zero(); ccom.zero(); double norm=0;
+     144           4 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() );
+     145        1818 :   for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     146             :     // Retrieve value and derivatives
+     147        1814 :     mystash->retrieveSequentialValue( i, false, cvals );
+     148        1814 :     mystash->retrieveDerivatives( mycolv->getPositionInFullTaskList(i), false, tvals );
+     149             :     // Convert position into fractionals
+     150        1814 :     Vector fpos = pbc.realToScaled( mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(i) ) );
+     151             :     // Now accumulate Berry phase averages
+     152        7256 :     for(unsigned j=0; j<3; ++j) {
+     153        5442 :       stmp[j] = std::sin( 2*pi*fpos[j] ); ctmp[j] = std::cos( 2*pi*fpos[j] );
+     154        5442 :       scom[j] += cvals[0]*cvals[comp]*stmp[j]; ccom[j] += cvals[0]*cvals[comp]*ctmp[j];
+     155        5442 :       double icell = 1.0 / getPbc().getBox().getRow(j).modulo();
+     156        5442 :       sder[j] = 2*pi*icell*cvals[0]*cvals[comp]*std::cos( 2*pi*fpos[j] );
+     157        5442 :       cder[j]=-2*pi*icell*cvals[0]*cvals[comp]*std::sin( 2*pi*fpos[j] );
+     158             :     }
+     159             :     // Now accumulate derivatives
+     160     1623560 :     for(unsigned k=0; k<tvals.getNumberActive(); ++k) {
+     161     1621746 :       unsigned icomp=tvals.getActiveIndex(k);
+     162     1621746 :       myvals.addDerivative( 0, icomp, cvals[0]*tvals.getDerivative( comp, icomp ) + cvals[comp]*tvals.getDerivative( 0, icomp ) );
+     163     6486984 :       for(unsigned k=0; k<3; ++k) {
+     164     4865238 :         myvals.addDerivative( 1+k, icomp, stmp[k]*( cvals[0]*tvals.getDerivative( comp, icomp ) +
+     165     4865238 :                               cvals[comp]*tvals.getDerivative( 0, icomp ) ) );
+     166     4865238 :         myvals.addDerivative( 4+k, icomp, ctmp[k]*( cvals[0]*tvals.getDerivative( comp, icomp ) +
+     167     4865238 :                               cvals[comp]*tvals.getDerivative( 0, icomp ) ) );
+     168             :       }
+     169             :     }
+     170             :     // Get the central atom pack
+     171        1814 :     CatomPack mypack; mycolv->getCentralAtomPack( 0, mycolv->getPositionInFullTaskList(i), mypack );
+     172        3628 :     for(unsigned j=0; j<mypack.getNumberOfAtomsWithDerivatives(); ++j) {
+     173        1814 :       unsigned jder=3*mypack.getIndex(j);
+     174             :       // Derivatives of sine
+     175        1814 :       myvals.addDerivative( 1, jder+0, mypack.getDerivative(j, 0, sder) );
+     176        1814 :       myvals.addDerivative( 2, jder+1, mypack.getDerivative(j, 1, sder) );
+     177        1814 :       myvals.addDerivative( 3, jder+2, mypack.getDerivative(j, 2, sder) );
+     178             :       // Derivatives of cosine
+     179        1814 :       myvals.addDerivative( 4, jder+0, mypack.getDerivative(j, 0, cder) );
+     180        1814 :       myvals.addDerivative( 5, jder+1, mypack.getDerivative(j, 1, cder) );
+     181        1814 :       myvals.addDerivative( 6, jder+2, mypack.getDerivative(j, 2, cder) );
+     182             :     }
+     183        1814 :     norm += cvals[0]*cvals[comp]; tvals.clearAll();
+     184             :   }
+     185             : 
+     186             :   // And now finish Berry phase average
+     187           4 :   scom /= norm; ccom /=norm; Vector cpos;
+     188          16 :   for(unsigned j=0; j<3; ++j) cpos[j] = std::atan2( scom[j], ccom[j] ) / (2*pi);
+     189           4 :   Vector cart_pos = pbc.scaledToReal( cpos );
+     190             :   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.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html b/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html new file mode 100644 index 0000000000..c5e5b0ffab --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe956createERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95D2Ev4168
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.func.html b/coverage/multicolvar/CoordinationNumbers.cpp.func.html new file mode 100644 index 0000000000..1df3875a5a --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe956createERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131CoordinationNumbersRegisterMe95D2Ev4168
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html b/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html new file mode 100644 index 0000000000..442e0a84d4 --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + 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-05-27 13:05: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       12608 : PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATIONNUMBER")
+      96             : 
+      97          54 : void CoordinationNumbers::registerKeywords( Keywords& keys ) {
+      98          54 :   MultiColvarBase::registerKeywords( keys );
+      99         162 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     100         108 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     101         108 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     102         108 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     103         108 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     104         108 :   keys.add("optional","R_POWER","Multiply the coordination number function by a power of r, "
+     105             :            "as done in White and Voth (see note above, default: no)");
+     106         108 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     107             :            "The following provides information on the \\ref switchingfunction that are available. "
+     108             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     109             :   // Use actionWithDistributionKeywords
+     110         216 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     111         216 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     112         162 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     113          54 : }
+     114             : 
+     115          52 : CoordinationNumbers::CoordinationNumbers(const ActionOptions&ao):
+     116             :   Action(ao),
+     117             :   MultiColvarBase(ao),
+     118          52 :   r_power(0)
+     119             : {
+     120             : 
+     121             :   // Read in the switching function
+     122         104 :   std::string sw, errors; parse("SWITCH",sw);
+     123          52 :   if(sw.length()>0) {
+     124          50 :     switchingFunction.set(sw,errors);
+     125          50 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     126             :   } else {
+     127           2 :     double r_0=-1.0, d_0; int nn, mm;
+     128           4 :     parse("NN",nn); parse("MM",mm);
+     129           4 :     parse("R_0",r_0); parse("D_0",d_0);
+     130           2 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     131           2 :     switchingFunction.set(nn,mm,r_0,d_0);
+     132             : 
+     133             :   }
+     134          52 :   log.printf("  coordination of central atom and those within %s\n",( switchingFunction.description() ).c_str() );
+     135             : 
+     136             :   //get cutoff of switching function
+     137          52 :   double rcut = switchingFunction.get_dmax();
+     138             : 
+     139             :   //parse power
+     140          52 :   parse("R_POWER", r_power);
+     141          52 :   if(r_power > 0) {
+     142           4 :     log.printf("  Multiplying switching function by r^%d\n", r_power);
+     143           4 :     double offset = switchingFunction.calculate(rcut*0.9999, rcut2) * std::pow(rcut*0.9999, r_power);
+     144           4 :     log.printf("  You will have a discontinuous jump of %f to 0 near the cutoff of your switching function. "
+     145             :                "Consider setting D_MAX or reducing R_POWER if this is large\n", offset);
+     146             :   }
+     147             : 
+     148             :   // Set the link cell cutoff
+     149          52 :   setLinkCellCutoff( rcut );
+     150          52 :   rcut2 = rcut * rcut;
+     151             : 
+     152             :   // And setup the ActionWithVessel
+     153          52 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms ); checkRead();
+     154          52 : }
+     155             : 
+     156       37088 : double CoordinationNumbers::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     157             :   // Calculate the coordination number
+     158             :   double dfunc, sw, d, raised;
+     159     3822803 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     160             :     Vector& distance=myatoms.getPosition(i);
+     161             :     double d2;
+     162     7107372 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     163     3321657 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     164     6676366 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     165             :          d2>epsilon ) {
+     166             : 
+     167     2633753 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+     168     2633753 :       if(r_power > 0) {
+     169       19350 :         d = std::sqrt(d2); raised = std::pow( d, r_power - 1 );
+     170       19350 :         accumulateSymmetryFunction( 1, i, sw * raised * d,
+     171       19350 :                                     (dfunc * d * raised + sw * r_power * raised / d) * distance,
+     172       38700 :                                     (-dfunc * d * raised - sw * r_power * raised / d) * Tensor(distance, distance),
+     173             :                                     myatoms );
+     174             :       } else {
+     175     2614403 :         accumulateSymmetryFunction( 1, i, sw, (dfunc)*distance, (-dfunc)*Tensor(distance,distance), myatoms );
+     176             :       }
+     177             :     }
+     178             :   }
+     179             : 
+     180       37088 :   return myatoms.getValue(1);
+     181             : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.func-sort-c.html b/coverage/multicolvar/Density.cpp.func-sort-c.html new file mode 100644 index 0000000000..a2dc194d2c --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE13
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68D2Ev4168
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.func.html b/coverage/multicolvar/Density.cpp.func.html new file mode 100644 index 0000000000..18c319fbba --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe686createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119DensityRegisterMe68D2Ev4168
_ZN4PLMD11multicolvar7Density10isPeriodicEv4
_ZN4PLMD11multicolvar7Density12getIndexListERKjS3_S3_RSt6vectorIjSaIjEE0
_ZN4PLMD11multicolvar7Density15getValueForTaskERKjRSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar7Density16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD11multicolvar7DensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7DensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7Density28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.gcov.html b/coverage/multicolvar/Density.cpp.gcov.html new file mode 100644 index 0000000000..ac8cbf8230 --- /dev/null +++ b/coverage/multicolvar/Density.cpp.gcov.html @@ -0,0 +1,181 @@ + + + + + + + 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-05-27 13:05: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       12526 : PLUMED_REGISTER_ACTION(Density,"DENSITY")
+      69             : 
+      70          13 : void Density::registerKeywords( Keywords& keys ) {
+      71          13 :   MultiColvarBase::registerKeywords( keys );
+      72          13 :   keys.use("SPECIES");
+      73          13 : }
+      74             : 
+      75          11 : Density::Density(const ActionOptions&ao):
+      76             :   Action(ao),
+      77          11 :   MultiColvarBase(ao)
+      78             : {
+      79          11 :   std::vector<AtomNumber> all_atoms; parseMultiColvarAtomList("SPECIES", -1, all_atoms);
+      80          11 :   ablocks.resize(1); ablocks[0].resize( atom_lab.size() );
+      81         489 :   for(unsigned i=0; i<atom_lab.size(); ++i) { addTaskToList(i); ablocks[0][i]=i; }
+      82          11 :   setupMultiColvarBase( all_atoms );
+      83             :   // And check everything has been read in correctly
+      84          11 :   checkRead();
+      85          11 : }
+      86             : 
+      87       15955 : double Density::compute( const unsigned& tindex, AtomValuePack& myvals ) const {
+      88       15955 :   return 1.0;
+      89             : }
+      90             : 
+      91           0 : void Density::getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices ) {
+      92           0 :   indices[jstore]=0;
+      93           0 : }
+      94             : 
+      95             : // unsigned Density::getNumberOfQuantities(){
+      96             : //    return 2;
+      97             : // }
+      98             : 
+      99           0 : void Density::getValueForTask( const unsigned& iatom, std::vector<double>& vals ) {
+     100           0 :   plumed_dbg_assert( vals.size()==2 ); vals[0]=vals[1]=1.0;
+     101           0 : }
+     102             : 
+     103             : }
+     104             : }
+     105             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html b/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html new file mode 100644 index 0000000000..f78ed19d28 --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.func.html b/coverage/multicolvar/DihedralCorrelation.cpp.func.html new file mode 100644 index 0000000000..49fa64c0cb --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe926createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131DihedralCorrelationRegisterMe92D2Ev4168
_ZN4PLMD11multicolvar19DihedralCorrelation10isPeriodicEv0
_ZN4PLMD11multicolvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar19DihedralCorrelationC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html b/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html new file mode 100644 index 0000000000..62d062ede3 --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html @@ -0,0 +1,250 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(DihedralCorrelation,"DIHCOR")
+      93             : 
+      94           4 : void DihedralCorrelation::registerKeywords( Keywords& keys ) {
+      95           4 :   MultiColvarBase::registerKeywords( keys );
+      96           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the dihedral correlation values you wish to calculate. "
+      97             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dihedral correlation will be "
+      98             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      99             :            "specify the indices of 8 atoms).  The eventual number of quantities calculated by this "
+     100             :            "action will depend on what functions of the distribution you choose to calculate.");
+     101           8 :   keys.reset_style("ATOMS","atoms");
+     102           4 : }
+     103             : 
+     104           2 : DihedralCorrelation::DihedralCorrelation(const ActionOptions&ao):
+     105             :   Action(ao),
+     106           2 :   MultiColvarBase(ao)
+     107             : {
+     108             :   // Read in the atoms
+     109             :   std::vector<AtomNumber> all_atoms;
+     110           2 :   readAtomsLikeKeyword( "ATOMS", 8, all_atoms );
+     111           2 :   setupMultiColvarBase( all_atoms );
+     112             :   // Stuff for central atoms
+     113           2 :   std::vector<bool> catom_ind(8, false);
+     114           6 :   catom_ind[1]=catom_ind[2]=catom_ind[5]=catom_ind[6]=true;
+     115           2 :   setAtomsForCentralAtom( catom_ind );
+     116             : 
+     117             :   // And setup the ActionWithVessel
+     118           2 :   if( getNumberOfVessels()==0 ) {
+     119             :     std::string fake_input;
+     120           2 :     addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     121           2 :     readVesselKeywords();  // This makes sure resizing is done
+     122             :   }
+     123             : 
+     124             :   // And check everything has been read in correctly
+     125           2 :   checkRead();
+     126           2 : }
+     127             : 
+     128         590 : double DihedralCorrelation::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     129         590 :   const Vector d10=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     130         590 :   const Vector d11=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     131         590 :   const Vector d12=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     132             : 
+     133         590 :   Vector dd10,dd11,dd12;
+     134             :   PLMD::Torsion t1;
+     135         590 :   const double phi1  = t1.compute(d10,d11,d12,dd10,dd11,dd12);
+     136             : 
+     137         590 :   const Vector d20=getSeparation(myatoms.getPosition(5),myatoms.getPosition(4));
+     138         590 :   const Vector d21=getSeparation(myatoms.getPosition(6),myatoms.getPosition(5));
+     139         590 :   const Vector d22=getSeparation(myatoms.getPosition(7),myatoms.getPosition(6));
+     140             : 
+     141         590 :   Vector dd20,dd21,dd22;
+     142             :   PLMD::Torsion t2;
+     143         590 :   const double phi2 = t2.compute( d20, d21, d22, dd20, dd21, dd22 );
+     144             : 
+     145             :   // Calculate value
+     146         590 :   const double diff = phi2 - phi1;
+     147         590 :   const double value = 0.5*(1.+std::cos(diff));
+     148             :   // Derivatives wrt phi1
+     149         590 :   const double dval = 0.5*std::sin(diff);
+     150         590 :   dd10 *= dval;
+     151         590 :   dd11 *= dval;
+     152         590 :   dd12 *= dval;
+     153             :   // And add
+     154         590 :   addAtomDerivatives(1, 0, dd10, myatoms );
+     155         590 :   addAtomDerivatives(1, 1, dd11-dd10, myatoms );
+     156         590 :   addAtomDerivatives(1, 2, dd12-dd11, myatoms );
+     157         590 :   addAtomDerivatives(1, 3, -dd12, myatoms );
+     158         590 :   myatoms.addBoxDerivatives  (1, -(extProduct(d10,dd10)+extProduct(d11,dd11)+extProduct(d12,dd12)));
+     159             :   // Derivative wrt phi2
+     160         590 :   dd20 *= -dval;
+     161         590 :   dd21 *= -dval;
+     162         590 :   dd22 *= -dval;
+     163             :   // And add
+     164         590 :   addAtomDerivatives(1, 4, dd20, myatoms );
+     165         590 :   addAtomDerivatives(1, 5, dd21-dd20, myatoms );
+     166         590 :   addAtomDerivatives(1, 6, dd22-dd21, myatoms );
+     167         590 :   addAtomDerivatives(1, 7, -dd22, myatoms );
+     168         590 :   myatoms.addBoxDerivatives(1, -(extProduct(d20,dd20)+extProduct(d21,dd21)+extProduct(d22,dd22)));
+     169             : 
+     170         590 :   return value;
+     171             : }
+     172             : 
+     173             : }
+     174             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html b/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html new file mode 100644 index 0000000000..6ee9e424e2 --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-05-27 13:05: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_8KeywordsE3
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100D2Ev4168
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.func.html b/coverage/multicolvar/DistanceFromContour.cpp.func.html new file mode 100644 index 0000000000..495f5739e1 --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe1006createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_132DistanceFromContourRegisterMe100D2Ev4168
_ZN4PLMD11multicolvar19DistanceFromContour10isPeriodicEv0
_ZN4PLMD11multicolvar19DistanceFromContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.gcov.html b/coverage/multicolvar/DistanceFromContour.cpp.gcov.html new file mode 100644 index 0000000000..cb9dcca76a --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.gcov.html @@ -0,0 +1,418 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(DistanceFromContour,"DISTANCE_FROM_CONTOUR")
+     101             : 
+     102           3 : void DistanceFromContour::registerKeywords( Keywords& keys ) {
+     103           3 :   MultiColvarBase::registerKeywords( keys );
+     104           6 :   keys.addOutputComponent("dist1","default","the distance between the reference atom and the nearest contour");
+     105           6 :   keys.addOutputComponent("dist2","default","the distance between the reference atom and the other contour");
+     106           6 :   keys.addOutputComponent("qdist","default","the differentiable (squared) distance between the two contours (see above)");
+     107           6 :   keys.addOutputComponent("thickness","default","the distance between the two contours on the line from the reference atom");
+     108           6 :   keys.add("compulsory","DATA","The input base multicolvar which is being used to calculate the contour");
+     109           6 :   keys.add("atoms","ATOM","The atom whose perpendicular distance we are calculating from the contour");
+     110           6 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+     111           6 :   keys.add("compulsory","KERNEL","gaussian","the kernel function you are using.  More details on  the kernels available "
+     112             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+     113           6 :   keys.add("compulsory","DIR","the direction perpendicular to the contour that you are looking for");
+     114           6 :   keys.add("compulsory","CONTOUR","the value we would like for the contour");
+     115           6 :   keys.add("compulsory","TOLERANCE","0.1","this parameter is used to manage periodic boundary conditions.  The problem "
+     116             :            "here is that we can be between contours even when we are not within the membrane "
+     117             :            "because of periodic boundary conditions.  When we are in the contour, however, we "
+     118             :            "should have it so that the sums of the absolute values of the distances to the two "
+     119             :            "contours is approximately the distance between the two contours.  There can be numerical errors in these calculations, however, so "
+     120             :            "we specify a small tolerance here");
+     121           3 : }
+     122             : 
+     123           1 : DistanceFromContour::DistanceFromContour( const ActionOptions& ao ):
+     124             :   Action(ao),
+     125             :   MultiColvarBase(ao),
+     126           1 :   derivTime(false),
+     127           1 :   bw(3),
+     128           1 :   pos1(3,0.0),
+     129           1 :   pos2(3,0.0),
+     130           1 :   dirv(3,0.0),
+     131           1 :   dirv2(3,0.0),
+     132           1 :   perp_dirs(2),
+     133           2 :   mymin(this)
+     134             : {
+     135             :   // Read in the multicolvar/atoms
+     136           1 :   std::vector<AtomNumber> all_atoms; parse("TOLERANCE",pbc_param);
+     137           1 :   bool read2 = parseMultiColvarAtomList("DATA", -1, all_atoms);
+     138           1 :   if( !read2 ) error("missing DATA keyword");
+     139           1 :   bool read1 = parseMultiColvarAtomList("ATOM", -1, all_atoms);
+     140           1 :   if( !read1 ) error("missing ATOM keyword");
+     141           1 :   if( all_atoms.size()!=1 ) error("should only be one atom specified");
+     142             :   // Read in the center of the binding object
+     143           1 :   log.printf("  computing distance of atom %d from contour \n",all_atoms[0].serial() );
+     144           1 :   setupMultiColvarBase( all_atoms ); forces.resize( 3*getNumberOfAtoms() + 9 );
+     145           1 :   if( getNumberOfBaseMultiColvars()!=1 ) error("should only be one input multicolvar");
+     146             : 
+     147             :   // Get the direction
+     148           2 :   std::string ldir; parse("DIR",ldir );
+     149           1 :   if( ldir=="x" ) { dir=0; perp_dirs[0]=1; perp_dirs[1]=2; dirv[0]=1; dirv2[0]=-1; }
+     150           1 :   else if( ldir=="y" ) { dir=1; perp_dirs[0]=0; perp_dirs[1]=2; dirv[1]=1; dirv2[1]=-1; }
+     151           1 :   else if( ldir=="z" ) { dir=2; perp_dirs[0]=0; perp_dirs[1]=1; dirv[2]=1; dirv2[2]=-1; }
+     152           0 :   else error(ldir + " is not a valid direction use x, y or z");
+     153             : 
+     154             :   // Read in details of phase field construction
+     155           3 :   parseVector("BANDWIDTH",bw); parse("KERNEL",kerneltype); parse("CONTOUR",contour);
+     156           1 :   log.printf("  searching for contour in %s direction at %f in phase field for multicolvar %s \n",ldir.c_str(), contour, mybasemulticolvars[0]->getLabel().c_str() );
+     157           1 :   log.printf("  constructing phase field using %s kernels with bandwidth (%f, %f, %f) \n",kerneltype.c_str(), bw[0], bw[1], bw[2] );
+     158             : 
+     159             :   // Now create a task list
+     160           2 :   for(unsigned i=0; i<mybasemulticolvars[0]->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     161             :   // And a cutoff
+     162           1 :   std::vector<double> pp( bw.size(),0 );
+     163           2 :   KernelFunctions kernel( pp, bw, kerneltype, "DIAGONAL", 1.0 );
+     164           1 :   double rcut = kernel.getCutoff( bw[0] );
+     165           3 :   for(unsigned j=1; j<bw.size(); ++j) {
+     166           2 :     if( kernel.getCutoff(bw[j])>rcut ) rcut=kernel.getCutoff(bw[j]);
+     167             :   }
+     168           1 :   rcut2=rcut*rcut;
+     169             :   // Create the values
+     170           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           1 : }
+     189             : 
+     190        6230 : unsigned DistanceFromContour::getNumberOfQuantities() const {
+     191        6230 :   return 3;
+     192             : }
+     193             : 
+     194         137 : void DistanceFromContour::calculate() {
+     195             :   // Check box is orthorhombic
+     196         137 :   if( !getPbc().isOrthorombic() ) error("cell box must be orthorhombic");
+     197             : 
+     198             :   // The nanoparticle is at the origin of our coordinate system
+     199         137 :   pos1[0]=pos1[1]=pos1[2]=0.0; pos2[0]=pos2[1]=pos2[2]=0.0;
+     200             : 
+     201             :   // Set bracket as center of mass of membrane in active region
+     202         137 :   deactivateAllTasks();
+     203         137 :   Vector myvec = getSeparation( getPosition(getNumberOfAtoms()-1), getPosition(0) ); pos2[dir]=myvec[dir];
+     204         137 :   taskFlags[0]=1; double mindist = myvec.modulo2();
+     205         137 :   for(unsigned j=1; j<getNumberOfAtoms()-1; ++j) {
+     206           0 :     Vector distance=getSeparation( getPosition(getNumberOfAtoms()-1), getPosition(j) );
+     207             :     double d2;
+     208           0 :     if( (d2=distance[perp_dirs[0]]*distance[perp_dirs[0]])<rcut2 &&
+     209           0 :         (d2+=distance[perp_dirs[1]]*distance[perp_dirs[1]])<rcut2 ) {
+     210           0 :       d2+=distance[dir]*distance[dir];
+     211           0 :       if( d2<mindist && std::fabs(distance[dir])>epsilon ) { pos2[dir]=distance[dir]; mindist = d2; }
+     212           0 :       taskFlags[j]=1;
+     213             :     }
+     214             :   }
+     215         137 :   lockContributors(); derivTime=false;
+     216             :   // pos1 position of the nanoparticle, in the first time
+     217             :   // pos2 is the position of the closer atom in the membrane with respect the nanoparticle
+     218             :   // fa = distance between pos1 and the contour
+     219             :   // fb = distance between pos2 and the contour
+     220         137 :   std::vector<double> faked(3);
+     221         137 :   double fa = getDifferenceFromContour( pos1, faked );
+     222         137 :   double fb = getDifferenceFromContour( pos2, faked );
+     223         137 :   if( fa*fb>0 ) {
+     224           0 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     225           0 :     for(unsigned i=0; i<maxtries; ++i) {
+     226           0 :       double sign=(pos2[dir]>0)? -1 : +1; // If the nanoparticle is inside the membrane push it out
+     227           0 :       pos1[dir] += sign*bw[dir]; fa = getDifferenceFromContour( pos1, faked );
+     228           0 :       if( fa*fb<0 ) break;
+     229             :       // if fa*fb is less than zero the new pos 1 is outside the contour
+     230             :     }
+     231             :   }
+     232             :   // Set direction for contour search
+     233         137 :   dirv[dir] = pos2[dir] - pos1[dir];
+     234             :   // Bracket for second root starts in center of membrane
+     235         137 :   double fc = getDifferenceFromContour( pos2, faked );
+     236         137 :   if( fc*fb>0 ) {
+     237             :     // first time is true, because fc=fb
+     238             :     // push pos2 from its initial position inside the membrane towards the second contourn
+     239         137 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     240         230 :     for(unsigned i=0; i<maxtries; ++i) {
+     241         230 :       double sign=(dirv[dir]>0)? +1 : -1;
+     242         230 :       pos2[dir] += sign*bw[dir]; fc = getDifferenceFromContour( pos2, faked );
+     243         230 :       if( fc*fb<0 ) break;
+     244             :     }
+     245         137 :     dirv2[dir] = ( pos1[dir] + dirv[dir] ) - pos2[dir];
+     246             :   }
+     247             : 
+     248             :   // Now do a search for the two contours
+     249         137 :   mymin.lsearch( dirv, pos1, &DistanceFromContour::getDifferenceFromContour );
+     250             :   // Save the first value
+     251         137 :   Vector root1; root1.zero(); root1[dir] = pval[dir]->get();
+     252         137 :   mymin.lsearch( dirv2, pos2, &DistanceFromContour::getDifferenceFromContour );
+     253             :   // Calculate the separation between the two roots using PBC
+     254         137 :   Vector root2; root2.zero(); root2[dir]=pval[dir]->get();
+     255         137 :   Vector sep = getSeparation( root1, root2 ); double spacing = std::fabs( sep[dir] ); plumed_assert( spacing>epsilon );
+     256         137 :   getPntrToComponent("thickness")->set( spacing );
+     257             : 
+     258             :   // Make sure the sign is right
+     259         137 :   double predir=(root1[dir]*root2[dir]<0)? -1 : 1;
+     260             :   // This deals with periodic boundary conditions - if we are inside the membrane the sum of the absolute
+     261             :   // distances from the contours should add up to the spacing.  When this is not the case we must be outside
+     262             :   // the contour
+     263             :   // if( predir==-1 && (std::fabs(root1[dir])+std::fabs(root2[dir]))>(spacing+pbc_param) ) predir=1;
+     264             :   // Set the final value to root that is closest to the "origin" = position of atom
+     265         137 :   if( std::fabs(root1[dir])<std::fabs(root2[dir]) ) {
+     266         137 :     getPntrToComponent("dist1")->set( predir*std::fabs(root1[dir]) );
+     267         274 :     getPntrToComponent("dist2")->set( std::fabs(root2[dir]) );
+     268             :   } else {
+     269           0 :     getPntrToComponent("dist1")->set( predir*std::fabs(root2[dir]) );
+     270           0 :     getPntrToComponent("dist2")->set( std::fabs(root1[dir]) );
+     271             :   }
+     272         137 :   getPntrToComponent("qdist")->set( root2[dir]*root1[dir] );
+     273             : 
+     274             :   // Now calculate the derivatives
+     275         137 :   if( !doNotCalculateDerivatives() ) {
+     276         137 :     Value* ival=myvalue_vessel->getFinalValue(); ival->clearDerivatives();
+     277         548 :     std::vector<double> root1v(3); for(unsigned i=0; i<3; ++i) root1v[i]=root1[i];
+     278         137 :     derivTime=true; std::vector<double> der(3); getDifferenceFromContour( root1v, der ); double prefactor;
+     279         137 :     if( mybasemulticolvars[0]->isDensity() ) prefactor = root2[dir] / myderiv_vessel->getOutputValue();
+     280           0 :     else plumed_error();
+     281         137 :     Value* val=getPntrToComponent("qdist");
+     282        2192 :     for(unsigned i=0; i<val->getNumberOfDerivatives(); ++i) val->setDerivative( i, -prefactor*ival->getDerivative(i) );
+     283             :     ival->clearDerivatives();
+     284         548 :     std::vector<double> root2v(3); for(unsigned i=0; i<3; ++i) root2v[i]=root2[i];
+     285         137 :     getDifferenceFromContour( root2v, der );
+     286         137 :     if( mybasemulticolvars[0]->isDensity() ) prefactor = root1[dir] / myderiv_vessel->getOutputValue();
+     287           0 :     else plumed_error();
+     288        2192 :     for(unsigned i=0; i<val->getNumberOfDerivatives(); ++i) val->addDerivative( i, -prefactor*ival->getDerivative(i) );
+     289             :   }
+     290         137 : }
+     291             : 
+     292        3115 : double DistanceFromContour::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) {
+     293             :   std::string min, max;
+     294       12460 :   for(unsigned j=0; j<3; ++j) {
+     295        9345 :     Tools::convert( -0.5*getBox()(j,j), min );
+     296        9345 :     Tools::convert( +0.5*getBox()(j,j), max );
+     297        9345 :     pval[j]->setDomain( min, max ); pval[j]->set( x[j] );
+     298             :   }
+     299        3115 :   runAllTasks();
+     300        6230 :   return myvalue_vessel->getOutputValue() - contour;
+     301             : }
+     302             : 
+     303        3115 : double DistanceFromContour::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     304        3115 :   Vector distance = getSeparation( getPosition(getNumberOfAtoms()-1), myatoms.getPosition(0) );
+     305       12460 :   std::vector<double> pp(3), der(3,0); for(unsigned j=0; j<3; ++j) pp[j] = distance[j];
+     306             : 
+     307             :   // convert the pointer once
+     308        3115 :   auto pval_ptr=Tools::unique2raw(pval);
+     309             : 
+     310             :   // Now create the kernel and evaluate
+     311        3115 :   KernelFunctions kernel( pp, bw, kerneltype, "DIAGONAL", 1.0 );
+     312        3115 :   kernel.normalize( pval_ptr ); double newval = kernel.evaluate( pval_ptr, der, true );
+     313             : 
+     314        3115 :   if( mybasemulticolvars[0]->isDensity() ) {
+     315        3115 :     if( !doNotCalculateDerivatives() && derivTime ) {
+     316             :       MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     317         274 :       Vector vder; unsigned basen=myvals.getNumberOfDerivatives() - 12;
+     318        1096 :       for(unsigned i=0; i<3; ++i) {
+     319         822 :         vder[i]=der[i]; myvals.addDerivative( 1, basen+i, vder[i] );
+     320             :       }
+     321         274 :       myatoms.setValue( 2, der[dir] );
+     322         274 :       addAtomDerivatives( 1, 0, -vder, myatoms );
+     323         274 :       myatoms.addBoxDerivatives( 1, Tensor(vder,distance) );
+     324             :     }
+     325        3115 :     myatoms.setValue( 0, 1.0 ); return newval;
+     326             :   }
+     327             : 
+     328             :   // This does the stuff for averaging
+     329             :   myatoms.setValue( 0, newval );
+     330             : 
+     331             :   // This gets the average if we are using a phase field
+     332           0 :   std::vector<double> cvals( mybasemulticolvars[0]->getNumberOfQuantities() );
+     333           0 :   mybasedata[0]->retrieveValueWithIndex( tindex, false, cvals );
+     334           0 :   return newval*cvals[0]*cvals[1];
+     335             : }
+     336             : 
+     337         137 : void DistanceFromContour::apply() {
+     338         274 :   if( getPntrToComponent("qdist")->applyForce( forces ) ) setForcesOnAtoms( forces );
+     339         137 : }
+     340             : 
+     341             : }
+     342             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func-sort-c.html b/coverage/multicolvar/Distances.cpp.func-sort-c.html new file mode 100644 index 0000000000..ad608de7d8 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe1356createERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135D2Ev4168
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func.html b/coverage/multicolvar/Distances.cpp.func.html new file mode 100644 index 0000000000..4c37677f92 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe1356createERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122DistancesRegisterMe135D2Ev4168
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.gcov.html b/coverage/multicolvar/Distances.cpp.gcov.html new file mode 100644 index 0000000000..c5a5a59421 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.gcov.html @@ -0,0 +1,287 @@ + + + + + + + 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-05-27 13:05: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       12606 : PLUMED_REGISTER_ACTION(Distances,"DISTANCES")
+     136             : 
+     137          53 : void Distances::registerKeywords( Keywords& keys ) {
+     138          53 :   MultiColvarBase::registerKeywords( keys );
+     139         159 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     140         212 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN"); // keys.use("DHENERGY");
+     141         212 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     142         106 :   keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
+     143             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
+     144             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     145             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     146             :            "action will depend on what functions of the distribution you choose to calculate.");
+     147         106 :   keys.reset_style("ATOMS","atoms");
+     148         106 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     149         106 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     150             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     151         106 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     152             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     153          53 : }
+     154             : 
+     155          51 : Distances::Distances(const ActionOptions&ao):
+     156             :   Action(ao),
+     157          51 :   MultiColvarBase(ao)
+     158             : {
+     159             :   // Read in the atoms
+     160             :   std::vector<AtomNumber> all_atoms;
+     161         102 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     162          86 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     163          51 :   setupMultiColvarBase( all_atoms );
+     164             :   // And check everything has been read in correctly
+     165          51 :   checkRead();
+     166             : 
+     167             :   // Now check if we can use link cells
+     168          51 :   if( getNumberOfVessels()>0 ) {
+     169             :     bool use_link=false; double rcut;
+     170          49 :     vesselbase::LessThan* lt=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(0) );
+     171          49 :     if( lt ) {
+     172          16 :       use_link=true; rcut=lt->getCutoff();
+     173             :     } else {
+     174          33 :       vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(0) );
+     175          33 :       if( bt ) { use_link=true; rcut=bt->getCutoff(); }
+     176             :     }
+     177             :     if( use_link ) {
+     178          76 :       for(unsigned i=1; i<getNumberOfVessels(); ++i) {
+     179          30 :         vesselbase::LessThan* lt2=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(i) );
+     180          30 :         vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(i) );
+     181          30 :         if( lt2 ) {
+     182           0 :           double tcut=lt2->getCutoff();
+     183           0 :           if( tcut>rcut ) rcut=tcut;
+     184          30 :         } else if( bt ) {
+     185          30 :           double tcut=bt->getCutoff();
+     186          30 :           if( tcut>rcut ) rcut=tcut;
+     187             :         } else {
+     188             :           use_link=false;
+     189             :         }
+     190             :       }
+     191             :     }
+     192          49 :     if( use_link ) setLinkCellCutoff( rcut );
+     193             :   }
+     194          51 : }
+     195             : 
+     196       15275 : double Distances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     197       15275 :   Vector distance;
+     198       15275 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     199       15275 :   const double value=distance.modulo();
+     200       15275 :   const double invvalue=1.0/value;
+     201             : 
+     202             :   // And finish the calculation
+     203       15275 :   addAtomDerivatives( 1, 0,-invvalue*distance, myatoms );
+     204       15275 :   addAtomDerivatives( 1, 1, invvalue*distance, myatoms );
+     205       15275 :   myatoms.addBoxDerivatives( 1, -invvalue*Tensor(distance,distance) );
+     206       15275 :   return value;
+     207             : }
+     208             : 
+     209             : }
+     210             : }
+     211             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html new file mode 100644 index 0000000000..777808d0f5 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE24
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func.html b/coverage/multicolvar/DumpMultiColvar.cpp.func.html new file mode 100644 index 0000000000..cb3923bbdc --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_127DumpMultiColvarRegisterMe83D2Ev4168
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar15DumpMultiColvar29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarD0Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD1Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html new file mode 100644 index 0000000000..56cb52c17f --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html @@ -0,0 +1,259 @@ + + + + + + + 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-05-27 13:05: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       12548 : PLUMED_REGISTER_ACTION(DumpMultiColvar,"DUMPMULTICOLVAR")
+      84             : 
+      85          24 : void DumpMultiColvar::registerKeywords( Keywords& keys ) {
+      86          24 :   Action::registerKeywords( keys );
+      87          24 :   ActionAtomistic::registerKeywords( keys );
+      88          24 :   ActionPilot::registerKeywords( keys );
+      89          24 :   ActionWithInputVessel::registerKeywords( keys );
+      90          48 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+      91          48 :   keys.add("compulsory", "FILE", "file on which to output coordinates");
+      92          48 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      93          48 :   keys.add("optional","PRECISION","The number of digits in trajectory file");
+      94          48 :   keys.add("atoms","ORIGIN","You can use this keyword to specify the position of an atom as an origin. The positions output will then be displayed relative to that origin");
+      95          24 : }
+      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.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html b/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html new file mode 100644 index 0000000000..15274600b9 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1476createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1466createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe146C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe146D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.func.html b/coverage/multicolvar/FilterBetween.cpp.func.html new file mode 100644 index 0000000000..4777829892 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1466createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe146C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe146D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe1476createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126FilterBetweenRegisterMe147D2Ev4168
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.gcov.html b/coverage/multicolvar/FilterBetween.cpp.gcov.html new file mode 100644 index 0000000000..cc5346dbbc --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.gcov.html @@ -0,0 +1,270 @@ + + + + + + + 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-05-27 13:05: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 histogram bead
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by MultiColvar is transformed by a \ref histogrambead function that
+      31             : is equal to one if the colvar is within a certain range and which is equal to zero otherwise.  In other words, we
+      32             : compute:
+      33             : 
+      34             : \f[
+      35             : f_i = \int_a^b K\left( \frac{s-s_i}{w} \right)
+      36             : \f]
+      37             : 
+      38             : where \f$a, b\f$ and \f$w\f$ are parameters.
+      39             : 
+      40             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_BETWEEN.
+      41             : In \ref MFILTER_BETWEEN a weight, \f$w_i\f$ for the colvar is calculated using the \ref histogrambead.  If one calculates the
+      42             : MEAN for \ref MFILTER_BETWEEN one is thus calculating:
+      43             : 
+      44             : \f[
+      45             : \mu = \frac{ \sum_i f_i s_i }{ \sum_i f_i}
+      46             : \f]
+      47             : 
+      48             : In this action by contrast the colvar is being transformed by the \ref histogrambead.  If one thus calculates a MEAN for
+      49             : this action one computes:
+      50             : 
+      51             : \f[
+      52             : \mu = \frac{ \sum_{i=1}^N f_i }{ N }
+      53             : \f]
+      54             : 
+      55             : In other words, you are calculating the mean for the transformed colvar.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : The following input gives an example of how a \ref MTRANSFORM_BETWEEN action can be used to duplicate
+      60             : functionality that is elsewhere in PLUMED.
+      61             : 
+      62             : \plumedfile
+      63             : DISTANCES ...
+      64             :  GROUPA=1-10 GROUPB=11-20
+      65             :  LABEL=d1
+      66             : ... DISTANCES
+      67             : MTRANSFORM_BETWEEN DATA=d1 LOWER=1.0 UPPER=2.0 SMEAR=0.5
+      68             : \endplumedfile
+      69             : 
+      70             : In this case you can achieve the same result by using:
+      71             : 
+      72             : \plumedfile
+      73             : DISTANCES ...
+      74             :  GROUPA=1-10 GROUPB=11-20
+      75             :  BETWEEN={GAUSSIAN LOWER=1.0 UPPER=2.0}
+      76             : ... DISTANCES
+      77             : \endplumedfile
+      78             : (see \ref DISTANCES)
+      79             : 
+      80             : The advantage of \ref MTRANSFORM_BETWEEN comes, however, if you want to use transformed colvars as input
+      81             : for \ref MULTICOLVARDENS
+      82             : 
+      83             : */
+      84             : //+ENDPLUMEDOC
+      85             : 
+      86             : //+PLUMEDOC MFILTERS MFILTER_BETWEEN
+      87             : /*
+      88             : This action can be used to filter the colvar values calculated by a multicolvar so that one can compute the mean and so on for only those multicolvars within a certain range.
+      89             : 
+      90             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      91             : In this action a multicolvar is within the dynamic group if its value lies in a particular range.
+      92             : In actuality a weight, \f$w_i\f$  is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      93             : and this weight measures the degree to which a colvar is a member of the group.  This weight is
+      94             : calculated using a \ref histogrambead so it is given by:
+      95             : 
+      96             : \f[
+      97             : w_i = \int_a^b K\left( \frac{s - s_i}{w} \right)
+      98             : \f]
+      99             : 
+     100             : where \f$a, b\f$ and \f$w\f$ are parameters.  If one calculates a function of the set of multicolvars
+     101             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+     102             : multicolvar what is computed is the following:
+     103             : 
+     104             : \f[
+     105             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+     106             : \f]
+     107             : 
+     108             : One is thus calculating the mean for those colvars that are within the range of interest.
+     109             : 
+     110             : \par Examples
+     111             : 
+     112             : The example shown below calculates the mean for those distances that are between 0 and 3 nm in length
+     113             : 
+     114             : \plumedfile
+     115             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     116             : MFILTER_BETWEEN DATA=d1 LOWER=0 UPPER=3.0 SMEAR=0.0001 MEAN LABEL=d4
+     117             : \endplumedfile
+     118             : 
+     119             : More complicated things can be done by using the label of a filter as input to a new multicolvar as shown
+     120             : in the example below.  Here the coordination numbers of all atoms are computed.  The atoms with a coordination
+     121             : number between 4 and 6 are then identified using the filter.  This reduced list of atoms is then used as input
+     122             : to a second coordination number calculation.  This second coordination number thus measures the number of atoms
+     123             : 4-6 coordinated atoms each of the 4-6 coordination atoms is bound to.
+     124             : 
+     125             : \plumedfile
+     126             : c1: COORDINATIONNUMBER SPECIES=1-150 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+     127             : cf: MFILTER_BETWEEN DATA=c1 LOWER=4 UPPER=6 SMEAR=0.5 LOWMEM
+     128             : 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}
+     129             : \endplumedfile
+     130             : 
+     131             : */
+     132             : //+ENDPLUMEDOC
+     133             : 
+     134             : namespace PLMD {
+     135             : namespace multicolvar {
+     136             : 
+     137             : class FilterBetween : public MultiColvarFilter {
+     138             : private:
+     139             :   HistogramBead hb;
+     140             : public:
+     141             :   static void registerKeywords( Keywords& keys );
+     142             :   explicit FilterBetween(const ActionOptions& ao);
+     143             :   double applyFilter( const double& val, double& df ) const override;
+     144             : };
+     145             : 
+     146       12510 : PLUMED_REGISTER_ACTION(FilterBetween,"MFILTER_BETWEEN")
+     147       12504 : PLUMED_REGISTER_ACTION(FilterBetween,"MTRANSFORM_BETWEEN")
+     148             : 
+     149           7 : void FilterBetween::registerKeywords( Keywords& keys ) {
+     150           7 :   MultiColvarFilter::registerKeywords( keys );
+     151          14 :   keys.add("compulsory","LOWER","the lower boundary for the range of interest");
+     152          14 :   keys.add("compulsory","UPPER","the upper boundary for the range of interest");
+     153          14 :   keys.add("compulsory","SMEAR","0.5","the amount by which to smear the value for kernel density estimation");
+     154          14 :   keys.add("optional","BEAD","This keywords is used if you want to employ an alternative to the function defined above. "
+     155             :            "The following provides information on the \\ref histogrambead that are available. "
+     156             :            "When this keyword is present you no longer need the LOWER, UPPER and SMEAR keywords.");
+     157           7 : }
+     158             : 
+     159           3 : FilterBetween::FilterBetween(const ActionOptions& ao):
+     160             :   Action(ao),
+     161           3 :   MultiColvarFilter(ao)
+     162             : {
+     163             :   // Read in the switching function
+     164           6 :   std::string sw, errors; parse("BEAD",sw);
+     165           3 :   if( getPntrToMultiColvar()->isPeriodic() ) {
+     166           0 :     std::string min, max; getPntrToMultiColvar()->retrieveDomain( min, max );
+     167           0 :     double mlow, mhigh; Tools::convert( min,mlow ); Tools::convert( max, mhigh);
+     168           0 :     hb.isPeriodic( mlow, mhigh );
+     169             :   } else {
+     170             :     hb.isNotPeriodic();
+     171             :   }
+     172             : 
+     173           3 :   if(sw.length()>0) {
+     174           0 :     hb.set(sw,errors);
+     175           0 :     if( errors.length()!=0 ) error("problem reading BEAD keyword : " + errors );
+     176             :   } else {
+     177             :     double l, u, s; std::string ll, uu, ss;
+     178           9 :     parse("LOWER",l); parse("UPPER",u); parse("SMEAR",s);
+     179           3 :     Tools::convert(l,ll); Tools::convert(u,uu); Tools::convert(s,ss);
+     180           6 :     sw="GAUSSIAN LOWER=" + ll + " UPPER=" + uu + " SMEAR=" + ss;
+     181           3 :     hb.set(sw,errors); plumed_massert(errors.length()==0,"problems with bead" + errors);
+     182             :   }
+     183           3 :   log.printf("  filtering colvar values and focussing only on those values in range %s\n",( hb.description() ).c_str() );
+     184             : 
+     185           3 :   checkRead();
+     186           3 : }
+     187             : 
+     188         735 : double FilterBetween::applyFilter( const double& val, double& df ) const {
+     189         735 :   double f = hb.calculate( val, df );
+     190         735 :   return f;
+     191             : }
+     192             : 
+     193             : }
+     194             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html b/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html new file mode 100644 index 0000000000..89ac9eaa9a --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1226createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1216createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe121C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe121D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.func.html b/coverage/multicolvar/FilterLessThan.cpp.func.html new file mode 100644 index 0000000000..76cd1f2e17 --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1216createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe121C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe121D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe1226createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterLessRegisterMe122D2Ev4168
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.gcov.html b/coverage/multicolvar/FilterLessThan.cpp.gcov.html new file mode 100644 index 0000000000..7b68d64562 --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + 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-05-27 13:05: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 multicovar using a switching function
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by \ref mcolv is transformed by a \ref switchingfunction function that
+      31             : is equal to one if the colvar is less than a certain target value and which is equal to zero otherwise.
+      32             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_LESS.
+      33             : In \ref MFILTER_LESS a weight, \f$w_i\f$ for the colvar is calculated using the \ref switchingfunction.  If one calculates the
+      34             : MEAN for \ref MFILTER_LESS one is thus calculating:
+      35             : 
+      36             : \f[
+      37             : \mu = \frac{ \sum_i \sigma(s_i) s_i }{\sum_i \simga(s_i) }
+      38             : \f]
+      39             : 
+      40             : where \f$\sigma\f$ is the \ref switchingfunction.  In this action by contrast the colvar is being transformed by
+      41             : the \ref switchingfunction.  If one thus calculates a MEAN for this action one computes:
+      42             : 
+      43             : \f[
+      44             : \mu = \frac{ \sum_{i=1}^N \simga(s_i) }{ N }
+      45             : \f]
+      46             : 
+      47             : In other words, you are calculating the mean for the transformed colvar.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input gives an example of how a MTRANSFORM_LESS action can be used to duplicate
+      52             : functionality that is elsewhere in PLUMED.
+      53             : 
+      54             : \plumedfile
+      55             : DISTANCES ...
+      56             :  GROUPA=1-10 GROUPB=11-20
+      57             :  LABEL=d1
+      58             : ... DISTANCES
+      59             : MTRANSFORM_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
+      60             : \endplumedfile
+      61             : 
+      62             : In this case you can achieve the same result by using:
+      63             : 
+      64             : \plumedfile
+      65             : DISTANCES ...
+      66             :  GROUPA=1-10 GROUPB=11-20
+      67             :  LESS_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
+      68             : ... DISTANCES
+      69             : \endplumedfile
+      70             : (see \ref DISTANCES)
+      71             : 
+      72             : The advantage of MTRANSFORM_LESS comes, however, if you want to use transformed colvars as input
+      73             : for \ref MULTICOLVARDENS
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : //+PLUMEDOC MFILTERS MFILTER_LESS
+      79             : /*
+      80             : This action can be used to filter the distribution of colvar values in a multicolvar so that one can compute the mean and so on for only those multicolvars less than a tolerance.
+      81             : 
+      82             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      83             : In this action a multicolvar is within the dynamic group if its value is less than a target.
+      84             : In actuality a weight, \f$w_i\f$ is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      85             : and this weight measures the degree to which a colvar is a member of the group.  This weight is a number
+      86             : between 0 and 1 that is calculated using a \ref switchingfunction , \f$\sigma\f$.
+      87             : If one calculates a function of the set of multicolvars
+      88             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+      89             : multicolvar what is computed is the following:
+      90             : 
+      91             : \f[
+      92             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+      93             : \f]
+      94             : 
+      95             : One is thus calculating the mean for those colvars that are less than the target.
+      96             : 
+      97             : \par Examples
+      98             : 
+      99             : The example shown below calculates the mean for those distances that less than 1.5 nm in length
+     100             : 
+     101             : \plumedfile
+     102             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     103             : MFILTER_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
+     104             : \endplumedfile
+     105             : 
+     106             : */
+     107             : //+ENDPLUMEDOC
+     108             : 
+     109             : namespace PLMD {
+     110             : namespace multicolvar {
+     111             : 
+     112             : class FilterLess : public MultiColvarFilter {
+     113             : private:
+     114             :   SwitchingFunction sf;
+     115             : public:
+     116             :   static void registerKeywords( Keywords& keys );
+     117             :   explicit FilterLess(const ActionOptions& ao);
+     118             :   double applyFilter( const double& val, double& df ) const override;
+     119             : };
+     120             : 
+     121       12512 : PLUMED_REGISTER_ACTION(FilterLess,"MFILTER_LESS")
+     122       12504 : PLUMED_REGISTER_ACTION(FilterLess,"MTRANSFORM_LESS")
+     123             : 
+     124           8 : void FilterLess::registerKeywords( Keywords& keys ) {
+     125           8 :   MultiColvarFilter::registerKeywords( keys );
+     126          16 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     127          16 :   keys.add("compulsory","MM","0","The m parameter of the switching function ");
+     128          16 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     129          16 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     130          16 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     131             :            "The following provides information on the \\ref switchingfunction that are available. "
+     132             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     133           8 : }
+     134             : 
+     135           4 : FilterLess::FilterLess(const ActionOptions& ao):
+     136             :   Action(ao),
+     137           4 :   MultiColvarFilter(ao)
+     138             : {
+     139             :   // Read in the switching function
+     140           8 :   std::string sw, errors; parse("SWITCH",sw);
+     141           4 :   if(sw.length()>0) {
+     142           4 :     sf.set(sw,errors);
+     143           4 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     144             :   } else {
+     145           0 :     double r_0=-1.0, d_0; int nn, mm;
+     146           0 :     parse("NN",nn); parse("MM",mm);
+     147           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     148           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     149           0 :     sf.set(nn,mm,r_0,d_0);
+     150             :   }
+     151           4 :   log.printf("  filtering colvar values and focussing only on those less than %s\n",( sf.description() ).c_str() );
+     152             : 
+     153           4 :   checkRead();
+     154           4 : }
+     155             : 
+     156        2486 : double FilterLess::applyFilter( const double& val, double& df ) const {
+     157        2486 :   double f = sf.calculate( val, df ); df*=val;
+     158        2486 :   return f;
+     159             : }
+     160             : 
+     161             : }
+     162             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html b/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html new file mode 100644 index 0000000000..5b58d7e080 --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1396createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1386createERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe138C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe138D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139D2Ev4168
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.func.html b/coverage/multicolvar/FilterMoreThan.cpp.func.html new file mode 100644 index 0000000000..e47766c21d --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1386createERKNS_13ActionOptionsE6
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe138C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe138D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe1396createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123FilterMoreRegisterMe139D2Ev4168
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.gcov.html b/coverage/multicolvar/FilterMoreThan.cpp.gcov.html new file mode 100644 index 0000000000..57e46cb8b1 --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.gcov.html @@ -0,0 +1,255 @@ + + + + + + + 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-05-27 13:05: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 multicolvar using one minus a switching function
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by \ref mcolv is transformed by a \ref switchingfunction function that
+      31             : is equal to one if the colvar is greater than a certain target value and which is equal to zero otherwise.
+      32             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_MORE.
+      33             : In \ref MFILTER_MORE a weight, \f$w_i\f$ for the colvar is calculated using the \ref histogrambead.  If one calculates the
+      34             : MEAN for \ref MFILTER_MORE one is thus calculating:
+      35             : 
+      36             : \f[
+      37             : \mu = \frac{ \sum_i [1 - \sigma(s_i) ] s_i }{\sum_i [1 - \sigma(s_i)] }
+      38             : \f]
+      39             : 
+      40             : where \f$\sigma\f$ is the \ref switchingfunction.  In this action by contrast the colvar is being transformed by the \ref switchingfunction.
+      41             : If one thus calculates a MEAN for this action one computes:
+      42             : 
+      43             : \f[
+      44             : \mu = \frac{ \sum_{i=1}^N 1 - \sigma(s_i) }{ N }
+      45             : \f]
+      46             : 
+      47             : In other words, you are calculating the mean for the transformed colvar.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input gives an example of how a MTRANSFORM_MORE action can be used to duplicate
+      52             : functionality that is elsewhere in PLUMED.
+      53             : 
+      54             : \plumedfile
+      55             : DISTANCES ...
+      56             :  GROUPA=1-10 GROUPB=11-20
+      57             :  LABEL=d1
+      58             : ... DISTANCES
+      59             : MTRANSFORM_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
+      60             : \endplumedfile
+      61             : 
+      62             : In this case you can achieve the same result by using:
+      63             : 
+      64             : \plumedfile
+      65             : DISTANCES ...
+      66             :  GROUPA=1-10 GROUPB=11-20
+      67             :  MORE_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
+      68             : ... DISTANCES
+      69             : \endplumedfile
+      70             : (see \ref DISTANCES)
+      71             : 
+      72             : The advantage of MTRANSFORM_MORE comes, however, if you want to use transformed colvars as input
+      73             : for \ref MULTICOLVARDENS
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : //+PLUMEDOC MFILTERS MFILTER_MORE
+      79             : /*
+      80             : This action can be used to filter the distribution of colvar values in a multicolvar so that one can compute the mean and so on for only those multicolvars more than a tolerance.
+      81             : 
+      82             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      83             : In this action a multicolvar is within the dynamic group if its value is greater than a target.
+      84             : In actuality a weight, \f$w_i\f$  is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      85             : and this weight measures the degree to which a colvar is a member of the group.  This weight is
+      86             : calculated using a \ref switchingfunction , \f$\sigma\f$ so it is given by:
+      87             : 
+      88             : \f[
+      89             : w_i = 1 - \sigma(s_i)
+      90             : \f]
+      91             : 
+      92             : If one calculates a function of the set of multicolvars
+      93             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+      94             : multicolvar what is computed is the following:
+      95             : 
+      96             : \f[
+      97             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+      98             : \f]
+      99             : 
+     100             : One is thus calculating the mean for those colvars that are greater than the target.
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : The example shown below calculates the mean for those distances that greater than 1.5 nm in length
+     105             : 
+     106             : \plumedfile
+     107             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     108             : MFILTER_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
+     109             : \endplumedfile
+     110             : 
+     111             : More complicated things can be done by using the label of a filter as input to a new multicolvar as shown
+     112             : in the example below.  Here the coordination numbers of all atoms are computed.  The atoms with a coordination
+     113             : number greater than 2 are then identified using the filter.  This reduced list of atoms is then used as input
+     114             : to a second coordination number calculation.  This second coordination number thus measures the number of
+     115             : two-coordinated atoms that each of the two-coordinated atoms is bound to.
+     116             : 
+     117             : \plumedfile
+     118             : c1: COORDINATIONNUMBER SPECIES=1-150 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+     119             : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+     120             : 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}
+     121             : \endplumedfile
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : namespace PLMD {
+     127             : namespace multicolvar {
+     128             : 
+     129             : class FilterMore : public MultiColvarFilter {
+     130             : private:
+     131             :   SwitchingFunction sf;
+     132             : public:
+     133             :   static void registerKeywords( Keywords& keys );
+     134             :   explicit FilterMore(const ActionOptions& ao);
+     135             :   double applyFilter( const double& val, double& df ) const override;
+     136             : };
+     137             : 
+     138       12516 : PLUMED_REGISTER_ACTION(FilterMore,"MFILTER_MORE")
+     139       12506 : PLUMED_REGISTER_ACTION(FilterMore,"MTRANSFORM_MORE")
+     140             : 
+     141          11 : void FilterMore::registerKeywords( Keywords& keys ) {
+     142          11 :   MultiColvarFilter::registerKeywords( keys );
+     143          22 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     144          22 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     145          22 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     146          22 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     147          22 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     148             :            "The following provides information on the \\ref switchingfunction that are available. "
+     149             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     150          11 : }
+     151             : 
+     152           7 : FilterMore::FilterMore(const ActionOptions& ao):
+     153             :   Action(ao),
+     154           7 :   MultiColvarFilter(ao)
+     155             : {
+     156             :   // Read in the switching function
+     157          14 :   std::string sw, errors; parse("SWITCH",sw);
+     158           7 :   if(sw.length()>0) {
+     159           7 :     sf.set(sw,errors);
+     160           7 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     161             :   } else {
+     162           0 :     double r_0=-1.0, d_0; int nn, mm;
+     163           0 :     parse("NN",nn); parse("MM",mm);
+     164           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     165           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     166           0 :     sf.set(nn,mm,r_0,d_0);
+     167             :   }
+     168           7 :   log.printf("  filtering colvar values and focussing only on those more than %s\n",( sf.description() ).c_str() );
+     169             : 
+     170           7 :   checkRead();
+     171           7 : }
+     172             : 
+     173       16806 : double FilterMore::applyFilter( const double& val, double& df ) const {
+     174       16806 :   double f = 1.0 - sf.calculate( val, df ); df*=-val;
+     175       16806 :   return f;
+     176             : }
+     177             : 
+     178             : }
+     179             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html new file mode 100644 index 0000000000..b334ce65ae --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func.html b/coverage/multicolvar/InPlaneDistances.cpp.func.html new file mode 100644 index 0000000000..f0d85a242b --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe726createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128InPlaneDistancesRegisterMe72D2Ev4168
_ZN4PLMD11multicolvar16InPlaneDistances10isPeriodicEv0
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16InPlaneDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.gcov.html b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html new file mode 100644 index 0000000000..5a3c535309 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(InPlaneDistances,"INPLANEDISTANCES")
+      73             : 
+      74           2 : void InPlaneDistances::registerKeywords( Keywords& keys ) {
+      75           2 :   MultiColvarBase::registerKeywords( keys );
+      76           6 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      77           8 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      78           8 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      79           4 :   keys.add("atoms","VECTORSTART","The first atom position that is used to define the normal to the plane of interest");
+      80           4 :   keys.add("atoms","VECTOREND","The second atom position that is used to define the normal to the plane of interest");
+      81           4 :   keys.add("atoms-2","GROUP","The set of atoms for which you wish to calculate the in plane distance ");
+      82           2 : }
+      83             : 
+      84           0 : InPlaneDistances::InPlaneDistances(const ActionOptions&ao):
+      85             :   Action(ao),
+      86           0 :   MultiColvarBase(ao)
+      87             : {
+      88             :   // Read in the atoms
+      89             :   std::vector<AtomNumber> all_atoms;
+      90           0 :   readThreeGroups("GROUP","VECTORSTART","VECTOREND",false,false,all_atoms);
+      91           0 :   setupMultiColvarBase( all_atoms );
+      92             : 
+      93             :   // Setup the multicolvar base
+      94           0 :   setupMultiColvarBase( all_atoms ); readVesselKeywords();
+      95             :   // Check atoms are OK
+      96           0 :   if( getFullNumberOfTasks()!=getNumberOfAtoms()-2 ) error("you should specify one atom for VECTORSTART and one atom for VECTOREND only");
+      97             :   // And check everything has been read in correctly
+      98           0 :   checkRead();
+      99             : 
+     100             : // Now check if we can use link cells
+     101           0 :   if( getNumberOfVessels()>0 ) {
+     102             :     bool use_link=false; double rcut;
+     103           0 :     vesselbase::LessThan* lt=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(0) );
+     104           0 :     if( lt ) {
+     105           0 :       use_link=true; rcut=lt->getCutoff();
+     106             :     } else {
+     107           0 :       vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(0) );
+     108           0 :       if( bt ) {
+     109           0 :         use_link=true; rcut=bt->getCutoff();
+     110             :       }
+     111             :     }
+     112             :     if( use_link ) {
+     113           0 :       for(unsigned i=1; i<getNumberOfVessels(); ++i) {
+     114           0 :         vesselbase::LessThan* lt2=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(i) );
+     115           0 :         vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(i) );
+     116           0 :         if( lt2 ) {
+     117           0 :           double tcut=lt2->getCutoff();
+     118           0 :           if( tcut>rcut ) rcut=tcut;
+     119           0 :         } else if( bt ) {
+     120           0 :           double tcut=bt->getCutoff();
+     121           0 :           if( tcut>rcut ) rcut=tcut;
+     122             :         } else {
+     123             :           use_link=false;
+     124             :         }
+     125             :       }
+     126             :     }
+     127           0 :     if( use_link ) setLinkCellCutoff( rcut );
+     128             :   }
+     129           0 : }
+     130             : 
+     131           0 : double InPlaneDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     132           0 :   Vector normal=getSeparation( myatoms.getPosition(1), myatoms.getPosition(2) );
+     133           0 :   Vector dir=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+     134           0 :   PLMD::Angle a; Vector ddij, ddik; double angle=a.compute(normal,dir,ddij,ddik);
+     135           0 :   double sangle=std::sin(angle), cangle=std::cos(angle);
+     136           0 :   double dd=dir.modulo(), invdd=1.0/dd, val=dd*sangle;
+     137             : 
+     138           0 :   addAtomDerivatives( 1, 0, dd*cangle*ddik + sangle*invdd*dir, myatoms );
+     139           0 :   addAtomDerivatives( 1, 1, -dd*cangle*(ddik+ddij) - sangle*invdd*dir, myatoms );
+     140           0 :   addAtomDerivatives( 1, 2, dd*cangle*ddij, myatoms );
+     141           0 :   myatoms.addBoxDerivatives( 1, -dd*cangle*(Tensor(normal,ddij)+Tensor(dir,ddik)) - sangle*invdd*Tensor(dir,dir) );
+     142             : 
+     143           0 :   return val;
+     144             : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html b/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html new file mode 100644 index 0000000000..b569b28903 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.func.html b/coverage/multicolvar/LocalAverage.cpp.func.html new file mode 100644 index 0000000000..9ecf2e0329 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12LocalAverage10isPeriodicEv3
_ZN4PLMD11multicolvar12LocalAverage16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar12LocalAverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12LocalAverageC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe1036createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125LocalAverageRegisterMe103D2Ev4168
_ZNK4PLMD11multicolvar12LocalAverage15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.gcov.html b/coverage/multicolvar/LocalAverage.cpp.gcov.html new file mode 100644 index 0000000000..1d63793311 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.gcov.html @@ -0,0 +1,406 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(LocalAverage,"LOCAL_AVERAGE")
+     104             : 
+     105           6 : void LocalAverage::registerKeywords( Keywords& keys ) {
+     106           6 :   MultiColvarBase::registerKeywords( keys );
+     107          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     108          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     109          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     110          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     111          12 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     112             :            "The following provides information on the \\ref switchingfunction that are available. "
+     113             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     114             :   // Use actionWithDistributionKeywords
+     115          18 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     116          24 :   keys.remove("LOWMEM"); keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+     117          18 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     118          12 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     119          18 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+     120          18 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+     121           6 : }
+     122             : 
+     123           4 : LocalAverage::LocalAverage(const ActionOptions& ao):
+     124             :   Action(ao),
+     125           4 :   MultiColvarBase(ao)
+     126             : {
+     127           4 :   if( getNumberOfBaseMultiColvars()>1 ) error("local average with more than one base colvar makes no sense");
+     128             :   // Read in the switching function
+     129           8 :   std::string sw, errors; parse("SWITCH",sw);
+     130           4 :   if(sw.length()>0) {
+     131           4 :     switchingFunction.set(sw,errors);
+     132             :   } else {
+     133           0 :     double r_0=-1.0, d_0; int nn, mm;
+     134           0 :     parse("NN",nn); parse("MM",mm);
+     135           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     136           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     137           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     138             :   }
+     139           4 :   log.printf("  averaging over central molecule and those within %s\n",( switchingFunction.description() ).c_str() );
+     140           4 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+     141           4 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+     142           4 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+     143           4 : }
+     144             : 
+     145          71 : unsigned LocalAverage::getNumberOfQuantities() const {
+     146          71 :   return getBaseMultiColvar(0)->getNumberOfQuantities();
+     147             : }
+     148             : 
+     149        1004 : double LocalAverage::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     150             :   double sw, dfunc; MultiValue& myvals = myatoms.getUnderlyingMultiValue();
+     151        1004 :   std::vector<double> values( getBaseMultiColvar(0)->getNumberOfQuantities() );
+     152             : 
+     153        1004 :   getInputData( 0, false, myatoms, values );
+     154             :   myvals.addTemporyValue( values[0] );
+     155        1004 :   if( values.size()>2 ) {
+     156       27108 :     for(unsigned j=2; j<values.size(); ++j) myatoms.addValue( j, values[0]*values[j] );
+     157             :   } else {
+     158           0 :     myatoms.addValue( 1, values[0]*values[1] );
+     159             :   }
+     160             : 
+     161        1004 :   if( !doNotCalculateDerivatives() ) {
+     162        1004 :     MultiValue& myder=getInputDerivatives( 0, false, myatoms );
+     163             : 
+     164             :     // Convert input atom to local index
+     165             :     unsigned katom = myatoms.getIndex( 0 ); plumed_dbg_assert( katom<atom_lab.size() ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     166             :     // Find base colvar
+     167        1004 :     unsigned mmc=atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     168             :     // Get start of indices for this atom
+     169        1004 :     unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=mybasemulticolvars[i]->getNumberOfDerivatives() - 9;
+     170             :     plumed_dbg_assert( basen%3==0 ); // Check the number of atoms is consistent with input derivatives
+     171             : 
+     172        1004 :     unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     173        1004 :     if( values.size()>2 ) {
+     174       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.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..5168e59069 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html @@ -0,0 +1,236 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd192
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE309
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE351
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv429
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE471
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE501
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1939
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1995
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2960
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4628
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6550
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9025
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9074
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE53063
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj220663
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE242860
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE447974
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE451503
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE605410
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE658236
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE905762
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1122658
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1428471
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2753935
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512702
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE64365841
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150993
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.func.html b/coverage/multicolvar/MultiColvarBase.cpp.func.html new file mode 100644 index 0000000000..eb1e3c733f --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.func.html @@ -0,0 +1,236 @@ + + + + + + + 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-05-27 13:05:14Functions:404197.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512702
_ZN4PLMD11multicolvar15MultiColvarBase13readTwoGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RSt6vectorINS_10AtomNumberESaISB_EE76
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6550
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1939
_ZN4PLMD11multicolvar15MultiColvarBase15readThreeGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE10
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE501
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2753935
_ZN4PLMD11multicolvar15MultiColvarBase17readGroupKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE12
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd192
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv429
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE605410
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9074
_ZN4PLMD11multicolvar15MultiColvarBase20readAtomsLikeKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE48
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE309
_ZN4PLMD11multicolvar15MultiColvarBase21resizeBookeepingArrayERKjS3_96
_ZN4PLMD11multicolvar15MultiColvarBase22setAtomsForCentralAtomERKSt6vectorIbSaIbEE19
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE471
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4628
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1995
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2960
_ZN4PLMD11multicolvar15MultiColvarBase9buildSetsEv4
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9025
_ZN4PLMD11multicolvar15MultiColvarBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE351
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE447974
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1122658
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150993
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE242860
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE905762
_ZNK4PLMD11multicolvar15MultiColvarBase17getLinkCellCutoffEv8
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE658236
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1428471
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE53063
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE451503
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase21splitInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE106
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE64365841
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj220663
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.gcov.html b/coverage/multicolvar/MultiColvarBase.cpp.gcov.html new file mode 100644 index 0000000000..b2cc40a40a --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.gcov.html @@ -0,0 +1,1164 @@ + + + + + + + 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-05-27 13:05: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         501 : void MultiColvarBase::registerKeywords( Keywords& keys ) {
+      39         501 :   Action::registerKeywords( keys );
+      40         501 :   ActionWithValue::registerKeywords( keys );
+      41         501 :   ActionAtomistic::registerKeywords( keys );
+      42        1002 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      43         501 :   ActionWithVessel::registerKeywords( keys );
+      44        1002 :   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         501 :   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        1002 :   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        1002 :   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        1002 :   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        1002 :   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         501 : }
+      73             : 
+      74         351 : MultiColvarBase::MultiColvarBase(const ActionOptions&ao):
+      75             :   Action(ao),
+      76             :   ActionAtomistic(ao),
+      77             :   ActionWithValue(ao),
+      78             :   ActionWithVessel(ao),
+      79         351 :   usepbc(false),
+      80         351 :   allthirdblockintasks(false),
+      81         351 :   uselinkforthree(false),
+      82         351 :   linkcells(comm),
+      83         351 :   threecells(comm),
+      84         351 :   setup_completed(false),
+      85         351 :   atomsWereRetrieved(false),
+      86         351 :   matsums(false),
+      87         351 :   usespecies(false),
+      88         702 :   nblock(0)
+      89             : {
+      90         702 :   if( keywords.exists("NOPBC") ) {
+      91         351 :     bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
+      92         351 :     usepbc=!nopbc;
+      93             :   }
+      94         702 :   if( keywords.exists("SPECIESA") ) { matsums=usespecies=true; }
+      95         351 : }
+      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         471 : bool MultiColvarBase::parseMultiColvarAtomList(const std::string& key, const int& num, std::vector<AtomNumber>& t) {
+     129             :   std::vector<std::string> mlabs;
+     130         471 :   if( num<0 ) parseVector(key,mlabs);
+     131           0 :   else parseNumberedVector(key,num,mlabs);
+     132             : 
+     133         471 :   if( mlabs.size()==0 ) return false;
+     134             : 
+     135         323 :   std::string mname; unsigned found_mcolv=mlabs.size();
+     136         450 :   for(unsigned i=0; i<mlabs.size(); ++i) {
+     137         328 :     MultiColvarBase* mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlabs[i]);
+     138         328 :     if(!mycolv) { found_mcolv=i; break; }
+     139             :     // Check all base multicolvars are of same type
+     140         127 :     if( i==0 ) {
+     141         122 :       mname = mycolv->getName();
+     142         244 :       if( keywords.exists("ALL_INPUT_SAME_TYPE") && mycolv->isPeriodic() ) error("multicolvar functions don't work with this multicolvar");
+     143             :     } else {
+     144          10 :       if( keywords.exists("ALL_INPUT_SAME_TYPE") && mname!=mycolv->getName() ) error("All input multicolvars must be of same type");
+     145             :     }
+     146             :     // And track which variable stores each colvar
+     147     4458438 :     for(unsigned j=0; j<mycolv->getFullNumberOfTasks(); ++j) atom_lab.push_back( std::pair<unsigned,unsigned>( mybasemulticolvars.size()+1, j ) );
+     148             :     // And store the multicolvar base
+     149         127 :     mybasemulticolvars.push_back( mycolv );
+     150             :     // And create a basedata stash
+     151         127 :     mybasedata.push_back( mybasemulticolvars[mybasemulticolvars.size()-1]->buildDataStashes( this ) );
+     152             :     // Check if weight has derivatives
+     153         127 :     if( mybasemulticolvars[ mybasemulticolvars.size()-1 ]->weightHasDerivatives ) weightHasDerivatives=true;
+     154         127 :     plumed_assert( mybasemulticolvars.size()==mybasedata.size() );
+     155             :   }
+     156             :   // Have we conventional atoms to read in
+     157         323 :   if( found_mcolv==0 ) {
+     158         201 :     std::vector<AtomNumber> tt; ActionAtomistic::interpretAtomList( mlabs, tt );
+     159       89846 :     for(unsigned i=0; i<tt.size(); ++i) { atom_lab.push_back( std::pair<unsigned,unsigned>( 0, t.size() + i ) ); }
+     160         201 :     log.printf("  keyword %s takes atoms : ", key.c_str() );
+     161       89846 :     for(unsigned i=0; i<tt.size(); ++i) { t.push_back( tt[i] ); log.printf("%d ",tt[i].serial() ); }
+     162         201 :     log.printf("\n");
+     163         122 :   } else if( found_mcolv==mlabs.size() ) {
+     164         122 :     if( checkNumericalDerivatives() ) error("cannot use NUMERICAL_DERIVATIVES keyword with dynamic groups as input");
+     165         122 :     log.printf("  keyword %s takes dynamic groups of atoms constructed from multicolvars labelled : ", key.c_str() );
+     166         249 :     for(unsigned i=0; i<mlabs.size(); ++i) log.printf("%s ",mlabs[i].c_str() );
+     167         122 :     log.printf("\n");
+     168           0 :   } else if( found_mcolv<mlabs.size() ) {
+     169           0 :     error("cannot mix multicolvar input and atom input in one line");
+     170             :   }
+     171             :   return true;
+     172         471 : }
+     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    12512702 : void MultiColvarBase::addTaskToList( const unsigned& taskCode ) {
+     371    12512702 :   plumed_assert( getNumberOfVessels()==0 );
+     372    12512702 :   ActionWithVessel::addTaskToList( taskCode );
+     373    12512702 : }
+     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         309 : void MultiColvarBase::setupMultiColvarBase( const std::vector<AtomNumber>& atoms ) {
+     383         309 :   if( !matsums && atom_lab.size()==0 ) error("No atoms have been read in");
+     384             :   std::vector<AtomNumber> all_atoms;
+     385             :   // Setup decoder array
+     386         309 :   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         246 :   } 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         318 :   } else if( keywords.exists("SPECIESA") ) {
+     422         101 :     plumed_assert( atom_lab.size()==0 && all_atoms.size()==0 );
+     423         101 :     ablocks.resize( 1 ); bool readspecies=parseMultiColvarAtomList("SPECIES", -1, all_atoms);
+     424         101 :     if( readspecies ) {
+     425       41493 :       ablocks[0].resize( atom_lab.size() ); for(unsigned i=0; i<atom_lab.size(); ++i) { addTaskToList(i); ablocks[0][i]=i; }
+     426             :     } else {
+     427          40 :       if( !parseMultiColvarAtomList("SPECIESA", -1, all_atoms) ) error("missing SPECIES/SPECIESA keyword");
+     428          20 :       unsigned nat1=atom_lab.size();
+     429          40 :       if( !parseMultiColvarAtomList("SPECIESB", -1, all_atoms) ) error("missing SPECIESB keyword");
+     430          20 :       unsigned nat2=atom_lab.size() - nat1;
+     431             : 
+     432         759 :       for(unsigned i=0; i<nat1; ++i) addTaskToList(i);
+     433          20 :       ablocks[0].resize( nat2 );
+     434        3726 :       for(unsigned i=0; i<nat2; ++i) {
+     435             :         bool found=false; unsigned inum=0;
+     436      288729 :         for(unsigned j=0; j<nat1; ++j) {
+     437      285201 :           if( atom_lab[nat1+i].first>0 && atom_lab[j].first>0 ) {
+     438      252720 :             if( atom_lab[nat1+i].first==atom_lab[j].first &&
+     439           0 :                 mybasemulticolvars[atom_lab[nat1+i].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[nat1+i].second)==
+     440      252720 :                 mybasemulticolvars[atom_lab[j].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[j].second) ) { found=true; inum=j; break; }
+     441       32481 :           } else if( atom_lab[nat1+i].first>0 ) {
+     442           0 :             if( mybasemulticolvars[atom_lab[nat1+i].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[nat1+i].second)==
+     443           0 :                 all_atoms[atom_lab[j].second] ) { found=true; inum=nat1 + i; break; }
+     444       32481 :           } else if( atom_lab[j].first>0 ) {
+     445           0 :             if( all_atoms[atom_lab[nat1+i].second]==
+     446           0 :                 mybasemulticolvars[atom_lab[j].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[j].second) ) { found=true; inum=nat1+i; break; }
+     447       32481 :           } else if( all_atoms[atom_lab[nat1+i].second]==all_atoms[atom_lab[j].second] ) { found=true; inum=j; break; }
+     448             :         }
+     449             :         // This prevents mistakes being made in colvar setup
+     450         178 :         if( found ) { ablocks[0][i]=inum; }
+     451        3528 :         else { ablocks[0][i]=nat1 + i; }
+     452             :       }
+     453             :     }
+     454             :   }
+     455         309 :   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         436 :   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       59576 :   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         309 :   ActionAtomistic::requestAtoms( all_atoms );
+     472             :   // And setup dependencies
+     473         436 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) addDependency( mybasemulticolvars[i] );
+     474             : 
+     475             :   // Setup underlying ActionWithVessel
+     476         309 :   readVesselKeywords();
+     477         309 : }
+     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         192 : void MultiColvarBase::setLinkCellCutoff( const double& lcut, double tcut ) {
+     496         192 :   plumed_assert( usespecies || ablocks.size()<4 );
+     497         192 :   if( tcut<0 ) tcut=lcut;
+     498             : 
+     499         192 :   if( !linkcells.enabled() ) {
+     500         192 :     linkcells.setCutoff( lcut );
+     501         192 :     threecells.setCutoff( tcut );
+     502             :   } else {
+     503           0 :     if( lcut>linkcells.getCutoff() ) linkcells.setCutoff( lcut );
+     504           0 :     if( tcut>threecells.getCutoff() ) threecells.setCutoff( tcut );
+     505             :   }
+     506         192 : }
+     507             : 
+     508           8 : double MultiColvarBase::getLinkCellCutoff()  const {
+     509           8 :   return linkcells.getCutoff();
+     510             : }
+     511             : 
+     512        1939 : void MultiColvarBase::setupLinkCells() {
+     513        1939 :   if( (!usespecies && nblock==0) || !linkcells.enabled() ) return ;
+     514             :   // Retrieve any atoms that haven't already been retrieved
+     515        1319 :   for(std::vector<MultiColvarBase*>::iterator p=mybasemulticolvars.begin(); p!=mybasemulticolvars.end(); ++p) {
+     516         203 :     (*p)->retrieveAtoms();
+     517             :   }
+     518        1116 :   retrieveAtoms();
+     519             : 
+     520             :   unsigned iblock;
+     521        1116 :   if( usespecies ) {
+     522             :     iblock=0;
+     523         217 :   } else if( ablocks.size()<4 ) {
+     524             :     iblock=1;
+     525             :   } else {
+     526           0 :     plumed_error();
+     527             :   }
+     528             : 
+     529             :   // Count number of currently active atoms
+     530        1116 :   nactive_atoms=0;
+     531      387954 :   for(unsigned i=0; i<ablocks[iblock].size(); ++i) {
+     532      386838 :     if( isCurrentlyActive( ablocks[iblock][i] ) ) nactive_atoms++;
+     533             :   }
+     534             : 
+     535        1116 :   if( nactive_atoms>0 ) {
+     536        1116 :     std::vector<Vector> ltmp_pos( nactive_atoms );
+     537        1116 :     std::vector<unsigned> ltmp_ind( nactive_atoms );
+     538             : 
+     539        1116 :     nactive_atoms=0;
+     540        1116 :     if( usespecies ) {
+     541      366639 :       for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     542      365740 :         if( !isCurrentlyActive( ablocks[0][i] ) ) continue;
+     543      365644 :         ltmp_ind[nactive_atoms]=ablocks[0][i];
+     544      365644 :         ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] );
+     545      365644 :         nactive_atoms++;
+     546             :       }
+     547             :     } else {
+     548       21315 :       for(unsigned i=0; i<ablocks[1].size(); ++i) {
+     549       21098 :         if( !isCurrentlyActive( ablocks[1][i] ) ) continue;
+     550       16178 :         ltmp_ind[nactive_atoms]=i;
+     551       16178 :         ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ablocks[1][i] );
+     552       16178 :         nactive_atoms++;
+     553             :       }
+     554             :     }
+     555             : 
+     556             :     // Build the lists for the link cells
+     557        1116 :     linkcells.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     558             :   }
+     559             : }
+     560             : 
+     561        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      451503 : bool MultiColvarBase::setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const {
+     653      451503 :   if( isDensity() ) {
+     654       19070 :     myatoms.setNumberOfAtoms( 1 ); myatoms.setAtom( 0, taskCode ); return true;
+     655      432433 :   } else if( usespecies ) {
+     656      180847 :     std::vector<unsigned> task_atoms(1); task_atoms[0]=taskCode;
+     657      180847 :     unsigned natomsper=myatoms.setupAtomsFromLinkCells( task_atoms, getPositionOfAtomForLinkCells( taskCode ), linkcells );
+     658      180847 :     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        9074 : void MultiColvarBase::setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label ) {
+     677        9074 :   if( !setup_completed ) {
+     678             :     bool justVolumes=false;
+     679        1931 :     if( usespecies ) {
+     680             :       justVolumes=true;
+     681        1438 :       for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     682        1318 :         vesselbase::StoreDataVessel* mys=dynamic_cast<vesselbase::StoreDataVessel*>( getPntrToVessel(i) );
+     683        1318 :         if( mys ) continue;
+     684         810 :         vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) );
+     685         810 :         if( !myb ) { justVolumes=false; break; }
+     686          38 :         ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
+     687          38 :         if( !myv ) { justVolumes=false; break; }
+     688             :       }
+     689             :     }
+     690        1931 :     deactivateAllTasks();
+     691        1931 :     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        1931 :     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     4886702 :       for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     717             :     }
+     718             : 
+     719             :     // Now activate all this class
+     720        1931 :     lockContributors();
+     721             :     // Setup the link cells
+     722        1931 :     setupLinkCells();
+     723             :     // Ensures that setup is not performed multiple times during one cycle
+     724        1931 :     setup_completed=true;
+     725             :   }
+     726             : 
+     727             :   // And activate the tasks in input action
+     728        9074 :   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        9074 : }
+     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        9025 : void MultiColvarBase::calculate() {
+     757             :   // Recursive function that sets up tasks
+     758        9025 :   setupActiveTaskSet( taskFlags, getLabel() );
+     759             : 
+     760             :   // Check for filters and rerun setup of link cells if there are any
+     761        9025 :   if( mybasemulticolvars.size()>0 && filtersUsedAsInput() ) setupLinkCells();
+     762             : 
+     763             :   //  Setup the link cells if we are not using species
+     764        9025 :   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        9025 :   runAllTasks();
+     778        9025 : }
+     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        2960 : void MultiColvarBase::prepare() {
+     786        2960 :   setup_completed=false; atomsWereRetrieved=false;
+     787        2960 : }
+     788             : 
+     789        6550 : void MultiColvarBase::retrieveAtoms() {
+     790        6550 :   if( !atomsWereRetrieved ) { ActionAtomistic::retrieveAtoms(); atomsWereRetrieved=true; }
+     791        6550 : }
+     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    64365841 : 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    64365841 :   double weight0=1.0; if( atom_lab[katom].first>0 ) weight0=mybasedata[atom_lab[katom].first-1]->retrieveWeightWithIndex( atom_lab[katom].second );
+     902    64365841 :   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    64365841 :   if( ival<0 ) myatoms.getUnderlyingMultiValue().addTemporyValue( weight0*weighti*val );
+     905    61628941 :   else myatoms.addValue( ival, weight0*weighti*val );
+     906             : 
+     907             :   // Return if we don't need derivatives
+     908    64365841 :   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      242860 : double MultiColvarBase::calculateWeight( const unsigned& current, const double& weight, AtomValuePack& myvals ) const {
+     946      242860 :   return 1.0;
+     947             : }
+     948             : 
+     949      447974 : void MultiColvarBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     950      447974 :   AtomValuePack myatoms( myvals, this );
+     951             :   // Retrieve the atom list
+     952      447974 :   if( !setupCurrentAtomList( current, myatoms ) ) return;
+     953             :   // Get weight due to dynamic groups
+     954      447854 :   double weight = 1.0;
+     955      447854 :   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      177610 :   } else if( usespecies ) {
+     964      177169 :     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      447854 :   double multweight = calculateWeight( current, weight, myatoms );
+     970      447854 :   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      326318 :   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      326318 :   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      326318 :   double vv=compute( task_index, myatoms ); updateActiveAtoms( myatoms );
+    1012             :   myatoms.setValue( 1, vv );
+    1013      326318 :   return;
+    1014             : }
+    1015             : 
+    1016      658236 : void MultiColvarBase::updateActiveAtoms( AtomValuePack& myatoms ) const {
+    1017      658236 :   if( mybasemulticolvars.size()==0 ) myatoms.updateUsingIndices();
+    1018      141871 :   else myatoms.updateDynamicList();
+    1019      658236 : }
+    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      220663 : void MultiColvarBase::applyPbc(std::vector<Vector>& dlist, unsigned int max_index) const {
+    1080      220663 :   if (usepbc) pbcApply(dlist, max_index);
+    1081      220663 : }
+    1082             : 
+    1083        1995 : void MultiColvarBase::apply() {
+    1084        1995 :   if( getForcesFromVessels( forcesToApply ) ) setForcesOnAtoms( forcesToApply );
+    1085        1995 : }
+    1086             : 
+    1087             : }
+    1088             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html b/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html new file mode 100644 index 0000000000..de02a32f38 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev351
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4462
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917709
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1814681
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv8911890
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69061330
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj408156345
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.func.html b/coverage/multicolvar/MultiColvarBase.h.func.html new file mode 100644 index 0000000000..846cead740 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917709
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv8911890
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev351
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4462
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69061330
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj408156345
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1814681
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.gcov.html b/coverage/multicolvar/MultiColvarBase.h.gcov.html new file mode 100644 index 0000000000..b0cdcc5b72 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.gcov.html @@ -0,0 +1,350 @@ + + + + + + + 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-05-27 13:05: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        1404 :   ~MultiColvarBase() {}
+     151             :   static void registerKeywords( Keywords& keys );
+     152             : /// Turn on the derivatives
+     153             :   void turnOnDerivatives() override;
+     154             : /// Get the separation between a pair of vectors
+     155             :   Vector getSeparation( const Vector& vec1, const Vector& vec2 ) const ;
+     156             : /// Do we use pbc to calculate this quantity
+     157             :   bool usesPbc() const ;
+     158             : /// Apply PBCs over a set of distance vectors
+     159             :   void applyPbc(std::vector<Vector>& dlist, unsigned max_index=0) const;
+     160             : /// Is it safe to use multithreading
+     161        4462 :   bool threadSafe() const override { return !(mybasemulticolvars.size()>0); }
+     162             : /// Do some setup before the calculation
+     163             :   void prepare() override;
+     164             : /// This is overwritten here in order to make sure that we do not retrieve atoms multiple times
+     165             :   void retrieveAtoms() override;
+     166             : /// Do the calculation
+     167             :   void calculate() override;
+     168             : /// Calculate numerical derivatives
+     169             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     170             : /// Perform one of the tasks
+     171             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+     172             : /// Update the active atoms
+     173             :   virtual void updateActiveAtoms( AtomValuePack& myatoms ) const ;
+     174             : /// This gets the position of an atom for the link cell setup
+     175             :   virtual Vector getPositionOfAtomForLinkCells( const unsigned& iatom ) const ;
+     176             : /// Get the absolute index of the central atom
+     177             :   virtual AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const ;
+     178             : /// This is replaced once we have a function to calculate the cv
+     179             :   virtual double compute( const unsigned& tindex, AtomValuePack& myatoms ) const=0;
+     180             : /// Apply the forces from this action
+     181             :   void apply() override;
+     182             : /// Get the number of derivatives for this action
+     183             :   unsigned getNumberOfDerivatives() override;  // N.B. This is replacing the virtual function in ActionWithValue
+     184             : /// Checks if an task is being performed at the present time
+     185             :   virtual bool isCurrentlyActive( const unsigned& code );
+     186             : /// Add some derivatives to a particular component of a particular atom
+     187             :   void addAtomDerivatives( const int&, const unsigned&, const Vector&, multicolvar::AtomValuePack& ) const ;
+     188             : ///
+     189             :   virtual void getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack);
+     190             : /// Get the index where the central atom is stored
+     191             :   virtual Vector getCentralAtomPos( const unsigned& curr );
+     192             : /// You can use this to screen contributions that are very small so we can avoid expensive (and pointless) calculations
+     193             :   virtual double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const ;
+     194             : /// Is this a density?
+     195     1814681 :   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      917709 : bool MultiColvarBase::isCurrentlyActive( const unsigned& code ) {
+     216      917709 :   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   408156345 : Vector MultiColvarBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     236             :   plumed_dbg_assert( iatom<atom_lab.size() );
+     237   408156345 :   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   405668363 :   return ActionAtomistic::getPosition( atom_lab[iatom].second );
+     242             : }
+     243             : 
+     244             : inline
+     245     8911890 : unsigned MultiColvarBase::getNumberOfDerivatives() {
+     246     8911890 :   return 3*getNumberOfAtoms()+9;
+     247             : }
+     248             : 
+     249             : inline
+     250             : bool MultiColvarBase::usesPbc() const {
+     251      220663 :   return usepbc;
+     252             : }
+     253             : 
+     254             : inline
+     255    69061330 : bool MultiColvarBase::doNotCalculateDerivatives() const {
+     256    69061330 :   if( !dertime ) return true;
+     257    68373610 :   return ActionWithValue::doNotCalculateDerivatives();
+     258             : }
+     259             : 
+     260             : inline
+     261             : unsigned MultiColvarBase::getNumberOfBaseMultiColvars() const {
+     262         178 :   return mybasemulticolvars.size();
+     263             : }
+     264             : 
+     265             : inline
+     266             : MultiColvarBase* MultiColvarBase::getBaseMultiColvar( const unsigned& icolv ) const {
+     267             :   plumed_dbg_assert( icolv<mybasemulticolvars.size() );
+     268       25010 :   return mybasemulticolvars[icolv];
+     269             : }
+     270             : 
+     271             : }
+     272             : }
+     273             : 
+     274             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html new file mode 100644 index 0000000000..c0d0eccb9a --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.func.html b/coverage/multicolvar/MultiColvarCombine.cpp.func.html new file mode 100644 index 0000000000..8e2394b2e5 --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe536createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarCombineRegisterMe53D2Ev4168
_ZN4PLMD11multicolvar18MultiColvarCombine10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarCombine16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar18MultiColvarCombineC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html b/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html new file mode 100644 index 0000000000..36c0d3025d --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(MultiColvarCombine,"MCOLV_COMBINE")
+      54             : 
+      55           3 : void MultiColvarCombine::registerKeywords( Keywords& keys ) {
+      56           3 :   MultiColvarBase::registerKeywords( keys );
+      57           6 :   keys.add("compulsory","DATA","the multicolvars you are calculating linear combinations for");
+      58           6 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients to use for the various multicolvars");
+      59          15 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      60          21 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      61           3 : }
+      62             : 
+      63           1 : MultiColvarCombine::MultiColvarCombine(const ActionOptions& ao):
+      64             :   Action(ao),
+      65           1 :   MultiColvarBase(ao)
+      66             : {
+      67           1 :   buildSets();
+      68           3 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      69           2 :     if( mybasemulticolvars[i]->weightWithDerivatives() ) error("cannot combine multicolvars with weights");
+      70             :   }
+      71           1 :   coeff.resize( getNumberOfBaseMultiColvars() );
+      72           1 :   parseVector("COEFFICIENTS",coeff);
+      73           1 :   log.printf("  coefficients of multicolvars %f", coeff[0] );
+      74           2 :   for(unsigned i=1; i<coeff.size(); ++i) log.printf(", %f", coeff[i] );
+      75           1 :   log.printf("\n");
+      76           1 : }
+      77             : 
+      78          15 : double MultiColvarCombine::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+      79          15 :   double dot=0; std::vector<double> tval(2);
+      80          45 :   for(unsigned i=0; i<coeff.size(); ++i) {
+      81          30 :     getInputData( i, false, myatoms, tval );
+      82          30 :     dot += coeff[i]*tval[1];
+      83             :   }
+      84          15 :   if( !doNotCalculateDerivatives() ) {
+      85          15 :     std::vector<double> cc(2);
+      86          45 :     for(unsigned i=0; i<coeff.size(); ++i) {
+      87          30 :       cc[1]=coeff[i]; MultiValue& myder=getInputDerivatives( i, false, myatoms );
+      88          30 :       splitInputDerivatives( 1, 1, 2, i, cc, myder, myatoms );
+      89             :     }
+      90             :   }
+      91          15 :   return dot;
+      92             : }
+      93             : 
+      94             : }
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html new file mode 100644 index 0000000000..0cf63fbadf --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE13
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107D2Ev4168
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.func.html b/coverage/multicolvar/MultiColvarDensity.cpp.func.html new file mode 100644 index 0000000000..106f6fd9fc --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe1076createERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_131MultiColvarDensityRegisterMe107D2Ev4168
_ZN4PLMD11multicolvar18MultiColvarDensity10isPeriodicEv0
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZN4PLMD11multicolvar18MultiColvarDensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html b/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html new file mode 100644 index 0000000000..e0253f1193 --- /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-05-27 13:05: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       12526 : PLUMED_REGISTER_ACTION(MultiColvarDensity,"MULTICOLVARDENS")
+     108             : 
+     109          13 : void MultiColvarDensity::registerKeywords( Keywords& keys ) {
+     110          13 :   gridtools::ActionWithGrid::registerKeywords( keys );
+     111          26 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin");
+     112          26 :   keys.add("compulsory","DATA","the multicolvar which you would like to calculate the density profile for");
+     113          26 :   keys.add("compulsory","DIR","the direction in which to calculate the density profile");
+     114          26 :   keys.add("optional","NBINS","the number of bins to use to represent the density profile");
+     115          26 :   keys.add("optional","SPACING","the approximate grid spacing (to be used as an alternative or together with NBINS)");
+     116          26 :   keys.addFlag("FRACTIONAL",false,"use fractional coordinates for the various axes");
+     117          26 :   keys.addFlag("XREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     118          26 :   keys.add("optional","XLOWER","this is required if you are using XREDUCED. It specifies the lower bound for the region of the x-axis that for "
+     119             :            "which you are calculating the density/average");
+     120          26 :   keys.add("optional","XUPPER","this is required if you are using XREDUCED. It specifies the upper bound for the region of the x-axis that for "
+     121             :            "which you are calculating the density/average");
+     122          26 :   keys.addFlag("YREDUCED",false,"limit the calculation of the density/average to a portion of the y-axis only");
+     123          26 :   keys.add("optional","YLOWER","this is required if you are using YREDUCED. It specifies the lower bound for the region of the y-axis that for "
+     124             :            "which you are calculating the density/average");
+     125          26 :   keys.add("optional","YUPPER","this is required if you are using YREDUCED. It specifies the upper bound for the region of the y-axis that for "
+     126             :            "which you are calculating the density/average");
+     127          26 :   keys.addFlag("ZREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     128          26 :   keys.add("optional","ZLOWER","this is required if you are using ZREDUCED. It specifies the lower bound for the region of the z-axis that for "
+     129             :            "which you are calculating the density/average");
+     130          26 :   keys.add("optional","ZUPPER","this is required if you are using ZREDUCED. It specifies the upper bound for the region of the z-axis that for "
+     131             :            "which you are calculating the density/average");
+     132          13 : }
+     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             :   // cppcheck-suppress danglingLifetime
+     232          11 :   mygrid=grid.get();
+     233             :   // And finish the grid setup
+     234          11 :   setAveragingAction( std::move(grid), true );
+     235             : 
+     236             :   // Enusre units for cube files are set correctly
+     237          11 :   if( !fractional ) {
+     238          11 :     if( plumed.getAtoms().usingNaturalUnits() ) mygrid->setCubeUnits( 1.0/0.5292 );
+     239           1 :     else mygrid->setCubeUnits( plumed.getAtoms().getUnits().getLength()/.05929 );
+     240             :   }
+     241             : 
+     242          11 :   checkRead(); requestAtoms(atom);
+     243             :   // Stupid dependencies cleared by requestAtoms - why GBussi why? That's got me so many times
+     244          11 :   addDependency( mycolv );
+     245          22 : }
+     246             : 
+     247          62 : unsigned MultiColvarDensity::getNumberOfQuantities() const {
+     248          62 :   return directions.size() + 2;
+     249             : }
+     250             : 
+     251          18 : void MultiColvarDensity::clearAverage() {
+     252          18 :   std::vector<double> min(directions.size()), max(directions.size());
+     253          18 :   std::vector<std::string> gmin(directions.size()), gmax(directions.size());;
+     254          46 :   for(unsigned i=0; i<directions.size(); ++i) { min[i]=-0.5; max[i]=0.5; }
+     255          18 :   if( !fractional ) {
+     256          18 :     if( !mycolv->getPbc().isOrthorombic() ) {
+     257           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");
+     258             :     }
+     259             : 
+     260          46 :     for(unsigned i=0; i<directions.size(); ++i) {
+     261          28 :       if( !confined[i] ) {
+     262          25 :         min[i]*=mycolv->getBox()(directions[i],directions[i]);
+     263          25 :         max[i]*=mycolv->getBox()(directions[i],directions[i]);
+     264             :       } else {
+     265           3 :         min[i]=cmin[i]; max[i]=cmax[i];
+     266             :       }
+     267             :     }
+     268             :   }
+     269          46 :   for(unsigned i=0; i<directions.size(); ++i) { Tools::convert(min[i],gmin[i]); Tools::convert(max[i],gmax[i]); }
+     270          18 :   ActionWithAveraging::clearAverage();
+     271          18 :   mygrid->setBounds( gmin, gmax, nbins, gspacing ); resizeFunctions();
+     272          36 : }
+     273             : 
+     274          26 : void MultiColvarDensity::prepareForAveraging() {
+     275          62 :   for(unsigned i=0; i<directions.size(); ++i) {
+     276          36 :     if( confined[i] ) continue;
+     277          33 :     std::string max; Tools::convert( 0.5*mycolv->getBox()(directions[i],directions[i]), max );
+     278          33 :     if( max!=mygrid->getMax()[i] ) error("box size should be fixed.  Use FRACTIONAL");
+     279             :   }
+     280             :   // Ensure we only work with active multicolvars
+     281          26 :   deactivateAllTasks();
+     282       21178 :   for(unsigned i=0; i<stash->getNumberOfStoredValues(); ++i) taskFlags[i]=1;
+     283          26 :   lockContributors();
+     284             :   // Retrieve the origin
+     285          26 :   origin = getPosition(0);
+     286          26 : }
+     287             : 
+     288       21152 : void MultiColvarDensity::compute( const unsigned& current, MultiValue& myvals ) const {
+     289       21152 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() ); stash->retrieveSequentialValue( current, false, cvals );
+     290       21152 :   Vector fpos, apos = pbcDistance( origin, mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(current) ) );
+     291       21152 :   if( fractional ) { fpos = getPbc().realToScaled( apos ); } else { fpos=apos; }
+     292             : 
+     293       84566 :   myvals.setValue( 0, cweight*cvals[0] ); for(unsigned j=0; j<directions.size(); ++j) myvals.setValue( 1+j, fpos[ directions[j] ] );
+     294       21152 :   myvals.setValue( 1+directions.size(), cvals[1] );
+     295       21152 : }
+     296             : 
+     297             : }
+     298             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html new file mode 100644 index 0000000000..f7da142d00 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.func.html b/coverage/multicolvar/MultiColvarFilter.cpp.func.html new file mode 100644 index 0000000000..287e4c5d3d --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html b/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html new file mode 100644 index 0000000000..6200873aca --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + 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-05-27 13:05: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          26 : void MultiColvarFilter::registerKeywords( Keywords& keys ) {
+      28          26 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      29          78 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30         104 :   keys.use("MEAN"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("MAX");
+      31          78 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      32          26 : }
+      33             : 
+      34          14 : MultiColvarFilter::MultiColvarFilter(const ActionOptions&ao):
+      35             :   Action(ao),
+      36          14 :   BridgedMultiColvarFunction(ao)
+      37             : {
+      38          14 :   if( getPntrToMultiColvar()->isDensity() ) error("filtering/transforming density makes no sense");
+      39             : 
+      40          14 :   if( getName().find("MFILTER")!=std::string::npos ) filter=true;
+      41             :   else {
+      42           1 :     plumed_assert( getName().find("MTRANSFORM")!=std::string::npos );
+      43           1 :     filter=false;
+      44             :   }
+      45             : 
+      46          14 :   readVesselKeywords();
+      47          14 : }
+      48             : 
+      49          46 : void MultiColvarFilter::doJobsRequiredBeforeTaskList() {
+      50          46 :   ActionWithValue::clearDerivatives();
+      51          46 :   ActionWithVessel::doJobsRequiredBeforeTaskList();
+      52          46 : }
+      53             : 
+      54       20027 : void MultiColvarFilter::completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const {
+      55       20027 :   invals.copyValues( outvals );
+      56       20027 :   if( derivativesAreRequired() ) invals.copyDerivatives( outvals );
+      57             : 
+      58             :   // Retrieve the value of the multicolvar and apply filter
+      59       20027 :   double val=invals.get(1), df, weight=applyFilter( val, df );
+      60             : 
+      61             :   // Now propegate derivatives
+      62       20027 :   if( filter && !getPntrToMultiColvar()->weightHasDerivatives ) {
+      63             :     outvals.setValue( 0, weight );
+      64       18447 :     if( derivativesAreRequired() ) {
+      65     2268072 :       for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      66     2253501 :         unsigned jder=invals.getActiveIndex(i);
+      67     2253501 :         outvals.addDerivative( 0, jder, df*invals.getDerivative(1, jder ) );
+      68             :       }
+      69             :     }
+      70        1580 :   } else if( filter ) {
+      71           0 :     double ww=outvals.get(0); outvals.setValue( 0, ww*weight );
+      72           0 :     if( derivativesAreRequired() ) {
+      73           0 :       for(unsigned i=0; i<outvals.getNumberActive(); ++i) {
+      74           0 :         unsigned ider=outvals.getActiveIndex(i);
+      75           0 :         outvals.setDerivative( 0, ider, weight*outvals.getDerivative(1,ider) + ww*df*outvals.getDerivative(0,ider) );
+      76             :       }
+      77             :     }
+      78             :   } else {
+      79             :     outvals.setValue( 1, weight );
+      80        1580 :     if( derivativesAreRequired() ) {
+      81       80912 :       for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      82       79332 :         unsigned jder=invals.getActiveIndex(i);
+      83       79332 :         outvals.setDerivative( 1, jder, df*invals.getDerivative(1, jder ) );
+      84             :       }
+      85             :     }
+      86             :   }
+      87       20027 : }
+      88             : 
+      89           0 : void MultiColvarFilter::addBridgeForces( const std::vector<double>& bb ) {
+      90             :   plumed_dbg_assert( bb.size()==0 );
+      91           0 : }
+      92             : 
+      93             : }
+      94             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html b/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html new file mode 100644 index 0000000000..c6866e98ef --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28192
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.func.html b/coverage/multicolvar/MultiColvarFilter.h.func.html new file mode 100644 index 0000000000..5c214ced76 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28192
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.gcov.html b/coverage/multicolvar/MultiColvarFilter.h.gcov.html new file mode 100644 index 0000000000..972a868eda --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.gcov.html @@ -0,0 +1,139 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html new file mode 100644 index 0000000000..8bdf8698ac --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.func.html b/coverage/multicolvar/MultiColvarProduct.cpp.func.html new file mode 100644 index 0000000000..278d7cc84d --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe526createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_130MultiColvarProductRegisterMe52D2Ev4168
_ZN4PLMD11multicolvar18MultiColvarProduct10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarProduct16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar18MultiColvarProductC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProductC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html b/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html new file mode 100644 index 0000000000..342d24a5d0 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html @@ -0,0 +1,165 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(MultiColvarProduct,"MCOLV_PRODUCT")
+      53             : 
+      54           3 : void MultiColvarProduct::registerKeywords( Keywords& keys ) {
+      55           3 :   MultiColvarBase::registerKeywords( keys );
+      56           6 :   keys.add("compulsory","DATA","the multicolvars you are calculating the product of");
+      57          15 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      58          21 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      59           3 : }
+      60             : 
+      61           1 : MultiColvarProduct::MultiColvarProduct(const ActionOptions& ao):
+      62             :   Action(ao),
+      63           1 :   MultiColvarBase(ao)
+      64             : {
+      65           1 :   buildSets();
+      66           3 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      67           2 :     if( mybasemulticolvars[i]->weightWithDerivatives() ) error("cannot take product of multicolvars with weights");
+      68             :   }
+      69           1 : }
+      70             : 
+      71          15 : double MultiColvarProduct::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+      72          15 :   double dot=1; std::vector<double> tval(2);
+      73          45 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      74          30 :     getInputData( i, false, myatoms, tval );
+      75          30 :     dot *= tval[1];
+      76             :   }
+      77          15 :   if( !doNotCalculateDerivatives() ) {
+      78          15 :     std::vector<double> cc(2);
+      79          45 :     for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      80          30 :       getInputData( i, false, myatoms, cc ); cc[1] = dot / cc[1];
+      81          30 :       MultiValue& myder=getInputDerivatives( i, false, myatoms );
+      82          30 :       splitInputDerivatives( 1, 1, 2, i, cc, myder, myatoms );
+      83             :     }
+      84             :   }
+      85          15 :   return dot;
+      86             : }
+      87             : 
+      88             : }
+      89             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html b/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html new file mode 100644 index 0000000000..f0dca1aa7d --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86D2Ev4168
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.func.html b/coverage/multicolvar/NumberOfLinks.cpp.func.html new file mode 100644 index 0000000000..3c7ac8a144 --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe866createERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125NumberOfLinksRegisterMe86D2Ev4168
_ZN4PLMD11multicolvar13NumberOfLinks10isPeriodicEv0
_ZN4PLMD11multicolvar13NumberOfLinks16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar13NumberOfLinksC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinksC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.gcov.html b/coverage/multicolvar/NumberOfLinks.cpp.gcov.html new file mode 100644 index 0000000000..30c3da66b4 --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(NumberOfLinks,"NLINKS")
+      87             : 
+      88           6 : void NumberOfLinks::registerKeywords( Keywords& keys ) {
+      89           6 :   MultiColvarBase::registerKeywords( keys );
+      90          12 :   keys.add("atoms","GROUP","");
+      91          12 :   keys.add("atoms-1","GROUPA","");
+      92          12 :   keys.add("atoms-1","GROUPB","");
+      93          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      94          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      95          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      96          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      97          12 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      98             :            "The following provides information on the \\ref switchingfunction that are available. "
+      99             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     100             :   // Use actionWithDistributionKeywords
+     101           6 :   keys.remove("LOWMEM");
+     102          12 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     103           6 : }
+     104             : 
+     105           4 : NumberOfLinks::NumberOfLinks(const ActionOptions& ao):
+     106             :   Action(ao),
+     107           4 :   MultiColvarBase(ao)
+     108             : {
+     109             :   // The weight of this does have derivatives
+     110           4 :   weightHasDerivatives=true;
+     111             : 
+     112             :   // Read in the switching function
+     113           8 :   std::string sw, errors; parse("SWITCH",sw);
+     114           4 :   if(sw.length()>0) {
+     115           4 :     switchingFunction.set(sw,errors);
+     116             :   } else {
+     117           0 :     double r_0=-1.0, d_0; int nn, mm;
+     118           0 :     parse("NN",nn); parse("MM",mm);
+     119           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     120           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     121           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     122             :   }
+     123           8 :   log.printf("  calculating number of links with atoms separation of %s\n",( switchingFunction.description() ).c_str() );
+     124           8 :   std::vector<AtomNumber> all_atoms; readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     125           4 :   setupMultiColvarBase( all_atoms ); setLinkCellCutoff( switchingFunction.get_dmax() );
+     126             : 
+     127           8 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     128           4 :     if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     129             :   }
+     130             : 
+     131             :   // Create holders for the collective variable
+     132           4 :   readVesselKeywords();
+     133           4 :   plumed_assert( getNumberOfVessels()==0 );
+     134           4 :   std::string input; addVessel( "SUM", input, -1 );
+     135           4 :   readVesselKeywords();
+     136           4 : }
+     137             : 
+     138        8064 : double NumberOfLinks::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     139        8064 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     140        8064 :   double dfunc, sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
+     141             : 
+     142        8064 :   if( !doNotCalculateDerivatives() ) {
+     143        8064 :     addAtomDerivatives( 0, 0, (-dfunc)*weight*distance, myatoms );
+     144        8064 :     addAtomDerivatives( 0, 1, (dfunc)*weight*distance, myatoms );
+     145        8064 :     myatoms.addBoxDerivatives( 0, (-dfunc)*weight*Tensor(distance,distance) );
+     146             :   }
+     147        8064 :   return sw;
+     148             : }
+     149             : 
+     150        8064 : double NumberOfLinks::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     151        8064 :   if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0;
+     152             : 
+     153        8064 :   unsigned ncomp=getBaseMultiColvar(0)->getNumberOfQuantities();
+     154             : 
+     155        8064 :   std::vector<double> orient0( ncomp ), orient1( ncomp );
+     156        8064 :   getInputData( 0, true, myatoms, orient0 );
+     157        8064 :   getInputData( 1, true, myatoms, orient1 );
+     158             : 
+     159             :   double dot=0;
+     160      185472 :   for(unsigned k=2; k<orient0.size(); ++k) {
+     161      177408 :     dot+=orient0[k]*orient1[k];
+     162             :   }
+     163             : 
+     164        8064 :   if( !doNotCalculateDerivatives() ) {
+     165        8064 :     MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+     166        8064 :     mergeInputDerivatives( 1, 2, orient1.size(), 0, orient1, myder0, myatoms );
+     167        8064 :     MultiValue& myder1=getInputDerivatives( 1, true, myatoms );
+     168        8064 :     mergeInputDerivatives( 1, 2, orient0.size(), 1, orient0, myder1, myatoms );
+     169             :   }
+     170             : 
+     171             :   return dot;
+     172             : }
+     173             : 
+     174             : }
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func-sort-c.html b/coverage/multicolvar/Torsions.cpp.func-sort-c.html new file mode 100644 index 0000000000..12595d38c7 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func.html b/coverage/multicolvar/Torsions.cpp.func.html new file mode 100644 index 0000000000..57b75d7b60 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120TorsionsRegisterMe85D2Ev4168
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZN4PLMD11multicolvar8Torsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.gcov.html b/coverage/multicolvar/Torsions.cpp.gcov.html new file mode 100644 index 0000000000..dd8ca835c4 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.gcov.html @@ -0,0 +1,211 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(Torsions,"TORSIONS")
+      86             : 
+      87           4 : void Torsions::registerKeywords( Keywords& keys ) {
+      88           4 :   MultiColvarBase::registerKeywords( keys );
+      89           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the torsion angles you wish to calculate. "
+      90             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be "
+      91             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      92             :            "provide the indices of four atoms).  The eventual number of quantities calculated by this "
+      93             :            "action will depend on what functions of the distribution you choose to calculate.");
+      94           8 :   keys.reset_style("ATOMS","atoms");
+      95           8 :   keys.use("BETWEEN"); keys.use("HISTOGRAM");
+      96           4 : }
+      97             : 
+      98           2 : Torsions::Torsions(const ActionOptions&ao):
+      99             :   Action(ao),
+     100           2 :   MultiColvarBase(ao)
+     101             : {
+     102             :   // Read in the atoms
+     103           2 :   int natoms=4; std::vector<AtomNumber> all_atoms;
+     104           2 :   readAtomsLikeKeyword( "ATOMS", natoms, all_atoms );
+     105           2 :   setupMultiColvarBase( all_atoms );
+     106           2 :   std::vector<bool> catom_ind(4, false);
+     107           2 :   catom_ind[1]=catom_ind[2]=true;
+     108           2 :   setAtomsForCentralAtom( catom_ind );
+     109             :   // Read in the vessels
+     110           2 :   readVesselKeywords();
+     111             :   // And check everything has been read in correctly
+     112           2 :   checkRead();
+     113           2 : }
+     114             : 
+     115          36 : double Torsions::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     116          36 :   Vector d0,d1,d2;
+     117          36 :   d0=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     118          36 :   d1=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     119          36 :   d2=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     120             : 
+     121          36 :   Vector dd0,dd1,dd2; PLMD::Torsion t;
+     122          36 :   double value  = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     123             : 
+     124          36 :   addAtomDerivatives(1,0,dd0,myatoms);
+     125          36 :   addAtomDerivatives(1,1,dd1-dd0,myatoms);
+     126          36 :   addAtomDerivatives(1,2,dd2-dd1,myatoms);
+     127          36 :   addAtomDerivatives(1,3,-dd2,myatoms);
+     128             : 
+     129          36 :   myatoms.addBoxDerivatives  (1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
+     130             : 
+     131          36 :   return value;
+     132             : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html b/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html new file mode 100644 index 0000000000..6f3a9f3bf4 --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83D2Ev4168
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.func.html b/coverage/multicolvar/VolumeAround.cpp.func.html new file mode 100644 index 0000000000..6bdee96aff --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe836createERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124VolumeAroundRegisterMe83D2Ev4168
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.gcov.html b/coverage/multicolvar/VolumeAround.cpp.gcov.html new file mode 100644 index 0000000000..76d612206d --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + 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-05-27 13:05: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       12548 : PLUMED_REGISTER_ACTION(VolumeAround,"AROUND")
+      84             : 
+      85          24 : void VolumeAround::registerKeywords( Keywords& keys ) {
+      86          24 :   ActionVolume::registerKeywords( keys );
+      87          48 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88          48 :   keys.add("compulsory","XLOWER","0.0","the lower boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
+      89          48 :   keys.add("compulsory","XUPPER","0.0","the upper boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
+      90          48 :   keys.add("compulsory","YLOWER","0.0","the lower boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
+      91          48 :   keys.add("compulsory","YUPPER","0.0","the upper boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
+      92          48 :   keys.add("compulsory","ZLOWER","0.0","the lower boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
+      93          48 :   keys.add("compulsory","ZUPPER","0.0","the upper boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
+      94          24 : }
+      95             : 
+      96          22 : VolumeAround::VolumeAround(const ActionOptions& ao):
+      97             :   Action(ao),
+      98          22 :   ActionVolume(ao)
+      99             : {
+     100             :   std::vector<AtomNumber> atom;
+     101          44 :   parseAtomList("ATOM",atom);
+     102          22 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     103          22 :   log.printf("  boundaries for region are calculated based on positions of atom : %d\n",atom[0].serial() );
+     104             : 
+     105          44 :   dox=true; parse("XLOWER",xlow); parse("XUPPER",xhigh);
+     106          44 :   doy=true; parse("YLOWER",ylow); parse("YUPPER",yhigh);
+     107          44 :   doz=true; parse("ZLOWER",zlow); parse("ZUPPER",zhigh);
+     108          22 :   if( xlow==0.0 && xhigh==0.0 ) dox=false;
+     109          22 :   if( ylow==0.0 && yhigh==0.0 ) doy=false;
+     110          22 :   if( zlow==0.0 && zhigh==0.0 ) doz=false;
+     111          22 :   if( !dox && !doy && !doz ) error("no subregion defined use XLOWER, XUPPER, YLOWER, YUPPER, ZLOWER, ZUPPER");
+     112          22 :   log.printf("  boundaries for region (region of interest about atom) : x %f %f, y %f %f, z %f %f \n",xlow,xhigh,ylow,yhigh,zlow,zhigh);
+     113          22 :   checkRead(); requestAtoms(atom);
+     114          22 : }
+     115             : 
+     116         317 : void VolumeAround::setupRegions() { }
+     117             : 
+     118       56393 : double VolumeAround::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     119             :   // Setup the histogram bead
+     120      112786 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     121             : 
+     122             :   // Calculate position of atom wrt to origin
+     123       56393 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     124             :   double xcontr, ycontr, zcontr, xder, yder, zder;
+     125       56393 :   if( dox ) {
+     126       32393 :     bead.set( xlow, xhigh, getSigma() );
+     127       32393 :     xcontr=bead.calculate( fpos[0], xder );
+     128             :   } else {
+     129       24000 :     xcontr=1.; xder=0.;
+     130             :   }
+     131       56393 :   if( doy ) {
+     132       32000 :     bead.set( ylow, yhigh, getSigma() );
+     133       32000 :     ycontr=bead.calculate( fpos[1], yder );
+     134             :   } else {
+     135       24393 :     ycontr=1.; yder=0.;
+     136             :   }
+     137       56393 :   if( doz ) {
+     138       32000 :     bead.set( zlow, zhigh, getSigma() );
+     139       32000 :     zcontr=bead.calculate( fpos[2], zder );
+     140             :   } else {
+     141       24393 :     zcontr=1.; zder=0.;
+     142             :   }
+     143       56393 :   derivatives[0]=xder*ycontr*zcontr;
+     144       56393 :   derivatives[1]=xcontr*yder*zcontr;
+     145       56393 :   derivatives[2]=xcontr*ycontr*zder;
+     146             :   // Add derivatives wrt to position of origin atom
+     147       56393 :   refders[0] = -derivatives;
+     148             :   // Add virial contribution
+     149       56393 :   vir -= Tensor(fpos,derivatives);
+     150       56393 :   return xcontr*ycontr*zcontr;
+     151             : }
+     152             : 
+     153             : }
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html b/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html new file mode 100644 index 0000000000..27e406fc38 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.func.html b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html new file mode 100644 index 0000000000..97af3ddbc6 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe786createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInEnvelopeRegisterMe78D2Ev4168
_ZN4PLMD11multicolvar16VolumeInEnvelope12setupRegionsEv0
_ZN4PLMD11multicolvar16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16VolumeInEnvelopeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html b/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html new file mode 100644 index 0000000000..75e918d160 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(VolumeInEnvelope,"INENVELOPE")
+      79             : 
+      80           2 : void VolumeInEnvelope::registerKeywords( Keywords& keys ) {
+      81           2 :   ActionVolume::registerKeywords( keys ); keys.remove("SIGMA");
+      82           4 :   keys.add("atoms","ATOMS","the atom whose positions we are constructing a field from");
+      83           4 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      84           4 :   keys.add("compulsory","CONTOUR","a switching function that tells PLUMED how large the density should be");
+      85           2 : }
+      86             : 
+      87           0 : VolumeInEnvelope::VolumeInEnvelope(const ActionOptions& ao):
+      88             :   Action(ao),
+      89             :   ActionVolume(ao),
+      90           0 :   mylinks(comm)
+      91             : {
+      92           0 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+      93           0 :   log.printf("  creating density field from atoms : ");
+      94           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+      95           0 :   log.printf("\n"); ltmp_ind.resize( atoms.size() ); ltmp_pos.resize( atoms.size() );
+      96           0 :   for(unsigned i=0; i<atoms.size(); ++i) ltmp_ind[i]=i;
+      97             : 
+      98           0 :   std::string sw, errors; parse("CONTOUR",sw);
+      99           0 :   if(sw.length()==0) error("missing CONTOURkeyword");
+     100           0 :   sfunc.set(sw,errors);
+     101           0 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     102           0 :   log.printf("  density at atom must be larger than %s \n", ( sfunc.description() ).c_str() );
+     103             : 
+     104           0 :   std::vector<double> pp(3,0.0), bandwidth(3); parseVector("BANDWIDTH",bandwidth);
+     105           0 :   log.printf("  using %s kernel with bandwidths %f %f %f \n",getKernelType().c_str(),bandwidth[0],bandwidth[1],bandwidth[2] );
+     106           0 :   kernel=Tools::make_unique<KernelFunctions>( pp, bandwidth, getKernelType(), "DIAGONAL", 1.0 );
+     107           0 :   for(unsigned i=0; i<3; ++i) { pos.emplace_back(Tools::make_unique<Value>()); pos[i]->setNotPeriodic(); }
+     108           0 :   std::vector<double> csupport( kernel->getContinuousSupport() );
+     109           0 :   double maxs = csupport[0];
+     110           0 :   for(unsigned i=1; i<csupport.size(); ++i) {
+     111           0 :     if( csupport[i]>maxs ) maxs = csupport[i];
+     112             :   }
+     113           0 :   checkRead(); requestAtoms(atoms); mylinks.setCutoff( maxs );
+     114           0 : }
+     115             : 
+     116           0 : void VolumeInEnvelope::setupRegions() {
+     117           0 :   for(unsigned i=0; i<ltmp_ind.size(); ++i) { ltmp_pos[i]=getPosition(i); }
+     118           0 :   mylinks.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     119           0 : }
+     120             : 
+     121           0 : double VolumeInEnvelope::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     122           0 :   unsigned ncells_required=0, natoms=1; std::vector<unsigned> cells_required( mylinks.getNumberOfCells() ), indices( 1 + getNumberOfAtoms() );
+     123           0 :   mylinks.addRequiredCells( mylinks.findMyCell( cpos ), ncells_required, cells_required );
+     124           0 :   indices[0]=getNumberOfAtoms(); mylinks.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+     125           0 :   double value=0; std::vector<double> der(3); Vector tder;
+     126             : 
+     127             :   // convert pointer once
+     128           0 :   auto pos_ptr=Tools::unique2raw(pos);
+     129             : 
+     130           0 :   for(unsigned i=1; i<natoms; ++i) {
+     131           0 :     Vector dist = getSeparation( cpos, getPosition( indices[i] ) );
+     132           0 :     for(unsigned j=0; j<3; ++j) pos[j]->set( dist[j] );
+     133           0 :     value += kernel->evaluate( pos_ptr, der, true );
+     134           0 :     for(unsigned j=0; j<3; ++j) {
+     135           0 :       derivatives[j] -= der[j]; refders[ indices[i] ][j] += der[j]; tder[j]=der[j];
+     136             :     }
+     137           0 :     vir -= Tensor( tder, dist );
+     138             :   }
+     139           0 :   double deriv, fval = sfunc.calculate( value, deriv );
+     140           0 :   derivatives *= -deriv*value; vir *= -deriv*value;
+     141           0 :   for(unsigned i=1; i<natoms; ++i) refders[ indices[i] ] *= -deriv*value;
+     142           0 :   return 1.0 - fval;
+     143             : }
+     144             : 
+     145             : }
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html b/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html new file mode 100644 index 0000000000..bd3226861a --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.func.html b/coverage/multicolvar/VolumeCavity.cpp.func.html new file mode 100644 index 0000000000..fc525ae9b0 --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZN4PLMD11multicolvar12VolumeCavity16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavityC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeCavityD0Ev2
_ZN4PLMD11multicolvar12VolumeCavityD1Ev2
_ZN4PLMD11multicolvar12VolumeCavityD2Ev0
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe1276createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_125VolumeCavityRegisterMe127D2Ev4168
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.gcov.html b/coverage/multicolvar/VolumeCavity.cpp.gcov.html new file mode 100644 index 0000000000..1f92b39566 --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.gcov.html @@ -0,0 +1,488 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(VolumeCavity,"CAVITY")
+     128             : 
+     129           4 : void VolumeCavity::registerKeywords( Keywords& keys ) {
+     130           4 :   ActionVolume::registerKeywords( keys );
+     131           8 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     132           8 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     133           8 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     134           8 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     135           4 : }
+     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_perp<=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.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html b/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..e99539face --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.func.html b/coverage/multicolvar/VolumeGradientBase.cpp.func.html new file mode 100644 index 0000000000..ba146d50a5 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html new file mode 100644 index 0000000000..d4cc7d8c03 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-05-27 13:05: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          44 : void VolumeGradientBase::registerKeywords( Keywords& keys ) {
+      31          44 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      32          44 : }
+      33             : 
+      34          30 : VolumeGradientBase::VolumeGradientBase(const ActionOptions&ao):
+      35             :   Action(ao),
+      36          30 :   BridgedMultiColvarFunction(ao)
+      37             : {
+      38          30 : }
+      39             : 
+      40          30 : void VolumeGradientBase::requestAtoms( const std::vector<AtomNumber>& atoms ) {
+      41          30 :   ActionAtomistic::requestAtoms(atoms); bridgeVariable=3*atoms.size();
+      42             :   std::map<std::string,bool> checklabs;
+      43          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             :     }
+      96           0 :   } else if(ivol==0) {
+      97           0 :     double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
+      98           0 :     if( derivativesAreRequired() ) {
+      99           0 :       plumed_merror("This needs testing");
+     100             : #if 0
+     101             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     102             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     103             :         unsigned jatom=3*catom.getIndex(i);
+     104             :         outvals.addDerivative( ivol, jatom+0, weight*outvals.getDerivative(ivol,jatom+0) + ww*catom.getDerivative(i,0,wdf) );
+     105             :         outvals.addDerivative( ivol, jatom+1, weight*outvals.getDerivative(ivol,jatom+1) + ww*catom.getDerivative(i,1,wdf) );
+     106             :         outvals.addDerivative( ivol, jatom+2, weight*outvals.getDerivative(ivol,jatom+2) + ww*catom.getDerivative(i,2,wdf) );
+     107             :       }
+     108             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     109             :       for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
+     110             :       for(unsigned i=0; i<refders.size(); ++i) {
+     111             :         unsigned iatom=nmder+3*i;
+     112             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     113             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     114             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     115             :       }
+     116             : #endif
+     117             :     }
+     118             :   } else {
+     119           0 :     double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
+     120           0 :     if( derivativesAreRequired() ) {
+     121           0 :       plumed_merror("This needs testing");
+     122             : #if 0
+     123             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     124             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     125             :         unsigned jatom=3*catom.getIndex(i);
+     126             :         outvals.addDerivative( ivol, jatom+0, ww*catom.getDerivative(i,0,wdf) );
+     127             :         outvals.addDerivative( ivol, jatom+1, ww*catom.getDerivative(i,1,wdf) );
+     128             :         outvals.addDerivative( ivol, jatom+2, ww*catom.getDerivative(i,2,wdf) );
+     129             :       }
+     130             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     131             :       for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
+     132             :       for(unsigned i=0; i<refders.size(); ++i) {
+     133             :         unsigned iatom=nmder+3*i;
+     134             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     135             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     136             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     137             :       }
+     138             : #endif
+     139             :     }
+     140             :   }
+     141      115758 : }
+     142             : 
+     143           0 : void VolumeGradientBase::addBridgeForces( const std::vector<double>& bb ) {
+     144             :   plumed_dbg_assert( bb.size()==tmpforces.size()-9 );
+     145             :   // Forces on local atoms
+     146           0 :   for(unsigned i=0; i<bb.size(); ++i) tmpforces[i]=bb[i];
+     147             :   // Virial contribution is zero
+     148           0 :   for(unsigned i=bb.size(); i<bb.size()+9; ++i) tmpforces[i]=0.0;
+     149           0 :   setForcesOnAtoms( tmpforces, 0 );
+     150           0 : }
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html b/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html new file mode 100644 index 0000000000..6e83c33473 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.func.html b/coverage/multicolvar/VolumeGradientBase.h.func.html new file mode 100644 index 0000000000..c9485d6ead --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.gcov.html b/coverage/multicolvar/VolumeGradientBase.h.gcov.html new file mode 100644 index 0000000000..f56aec7c08 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html b/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html new file mode 100644 index 0000000000..bd90daef57 --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.func.html b/coverage/multicolvar/VolumeInCylinder.cpp.func.html new file mode 100644 index 0000000000..626bf8f009 --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe876createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeInCylinderRegisterMe87D2Ev4168
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html b/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html new file mode 100644 index 0000000000..aed644fbe0 --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(VolumeInCylinder,"INCYLINDER")
+      88             : 
+      89           3 : void VolumeInCylinder::registerKeywords( Keywords& keys ) {
+      90           3 :   ActionVolume::registerKeywords( keys );
+      91           6 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      92           6 :   keys.add("compulsory","DIRECTION","the direction of the long axis of the cylinder. Must be x, y or z");
+      93           6 :   keys.add("compulsory","RADIUS","a switching function that gives the extent of the cylinder in the plane perpendicular to the direction");
+      94           6 :   keys.add("compulsory","LOWER","0.0","the lower boundary on the direction parallel to the long axis of the cylinder");
+      95           6 :   keys.add("compulsory","UPPER","0.0","the upper boundary on the direction parallel to the long axis of the cylinder");
+      96           6 :   keys.reset_style("SIGMA","optional");
+      97           3 : }
+      98             : 
+      99           1 : VolumeInCylinder::VolumeInCylinder(const ActionOptions& ao):
+     100             :   Action(ao),
+     101             :   ActionVolume(ao),
+     102           1 :   docylinder(false)
+     103             : {
+     104             :   std::vector<AtomNumber> atom;
+     105           2 :   parseAtomList("ATOM",atom);
+     106           1 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     107           1 :   log.printf("  center of cylinder is at position of atom : %d\n",atom[0].serial() );
+     108             : 
+     109           2 :   std::string sdir; parse("DIRECTION",sdir);
+     110           1 :   if( sdir=="X") {dir.push_back(1); dir.push_back(2); dir.push_back(0); }
+     111           1 :   else if( sdir=="Y") {dir.push_back(0); dir.push_back(2); dir.push_back(1); }
+     112           1 :   else if( sdir=="Z") {dir.push_back(0); dir.push_back(1); dir.push_back(2); }
+     113           0 :   else { error(sdir + "is not a valid direction.  Should be X, Y or Z"); }
+     114           1 :   log.printf("  cylinder's long axis is along %s axis\n",sdir.c_str() );
+     115             : 
+     116           2 :   std::string sw, errors; parse("RADIUS",sw);
+     117           1 :   if(sw.length()==0) error("missing RADIUS keyword");
+     118           1 :   switchingFunction.set(sw,errors);
+     119           1 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     120           1 :   log.printf("  radius of cylinder is given by %s \n", ( switchingFunction.description() ).c_str() );
+     121             : 
+     122           2 :   double min, max; parse("LOWER",min); parse("UPPER",max);
+     123           1 :   if( min!=0.0 ||  max!=0.0 ) {
+     124           1 :     if( min>max ) error("minimum of cylinder should be less than maximum");
+     125           1 :     docylinder=true;
+     126           1 :     log.printf("  cylinder extends from %f to %f along the %s axis\n",min,max,sdir.c_str() );
+     127           2 :     bead.isNotPeriodic(); bead.setKernelType( getKernelType() ); bead.set( min, max, getSigma() );
+     128             :   }
+     129             : 
+     130           1 :   checkRead(); requestAtoms(atom);
+     131           1 : }
+     132             : 
+     133          20 : void VolumeInCylinder::setupRegions() { }
+     134             : 
+     135        4000 : double VolumeInCylinder::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     136             :   // Calculate position of atom wrt to origin
+     137        4000 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     138             : 
+     139             :   double vcylinder, dcylinder;
+     140        4000 :   if( docylinder ) {
+     141        4000 :     vcylinder=bead.calculate( fpos[dir[2]], dcylinder );
+     142             :   } else {
+     143           0 :     vcylinder=1.0; dcylinder=0.0;
+     144             :   }
+     145             : 
+     146        4000 :   const double dd = fpos[dir[0]]*fpos[dir[0]] + fpos[dir[1]]*fpos[dir[1]];
+     147        4000 :   double dfunc, vswitch = switchingFunction.calculateSqr( dd, dfunc );
+     148        4000 :   derivatives.zero(); double value=vswitch*vcylinder;
+     149        4000 :   derivatives[dir[0]]=vcylinder*dfunc*fpos[dir[0]];
+     150        4000 :   derivatives[dir[1]]=vcylinder*dfunc*fpos[dir[1]];
+     151        4000 :   derivatives[dir[2]]=vswitch*dcylinder;
+     152             :   // Add derivatives wrt to position of origin atom
+     153        4000 :   refders[0] = -derivatives;
+     154             :   // Add virial contribution
+     155        4000 :   vir -= Tensor(fpos,derivatives);
+     156        4000 :   return value;
+     157             : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html b/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html new file mode 100644 index 0000000000..017b1efd01 --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe836createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83D2Ev4168
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.func.html b/coverage/multicolvar/VolumeInSphere.cpp.func.html new file mode 100644 index 0000000000..d58104443b --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe836createERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_126VolumeInSphereRegisterMe83D2Ev4168
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.gcov.html b/coverage/multicolvar/VolumeInSphere.cpp.gcov.html new file mode 100644 index 0000000000..6a71de4be4 --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(VolumeInSphere,"INSPHERE")
+      84             : 
+      85           5 : void VolumeInSphere::registerKeywords( Keywords& keys ) {
+      86           5 :   ActionVolume::registerKeywords( keys );
+      87          10 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88          10 :   keys.add("compulsory","RADIUS","the switching function that tells us the extent of the spherical region of interest");
+      89           5 :   keys.remove("SIGMA");
+      90           5 : }
+      91             : 
+      92           3 : VolumeInSphere::VolumeInSphere(const ActionOptions& ao):
+      93             :   Action(ao),
+      94           3 :   ActionVolume(ao)
+      95             : {
+      96             :   std::vector<AtomNumber> atom;
+      97           6 :   parseAtomList("ATOM",atom);
+      98           3 :   if( atom.size()!=1 ) error("should only be one atom specified");
+      99           3 :   log.printf("  center of sphere is at position of atom : %d\n",atom[0].serial() );
+     100             : 
+     101           6 :   std::string sw, errors; parse("RADIUS",sw);
+     102           3 :   if(sw.length()==0) error("missing RADIUS keyword");
+     103           3 :   switchingFunction.set(sw,errors);
+     104           3 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     105           3 :   log.printf("  radius of sphere is given by %s \n", ( switchingFunction.description() ).c_str() );
+     106             : 
+     107           3 :   checkRead(); requestAtoms(atom);
+     108           3 : }
+     109             : 
+     110          82 : void VolumeInSphere::setupRegions() { }
+     111             : 
+     112      155474 : double VolumeInSphere::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     113             :   // Calculate position of atom wrt to origin
+     114      155474 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     115      155474 :   double dfunc, value = switchingFunction.calculateSqr( fpos.modulo2(), dfunc );
+     116      155474 :   derivatives.zero(); derivatives = dfunc*fpos; refders[0] = -derivatives;
+     117             :   // Add a virial contribution
+     118      155474 :   vir -= Tensor(fpos,derivatives);
+     119      155474 :   return value;
+     120             : }
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html b/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html new file mode 100644 index 0000000000..fb55600946 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.func.html b/coverage/multicolvar/VolumeTetrapore.cpp.func.html new file mode 100644 index 0000000000..8ff3793a3d --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:31225.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe1356createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_128VolumeTetraporeRegisterMe135D2Ev4168
_ZN4PLMD11multicolvar15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD11multicolvar15VolumeTetrapore16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar15VolumeTetrapore6updateEv0
_ZN4PLMD11multicolvar15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeD0Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD1Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD2Ev0
_ZNK4PLMD11multicolvar15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html new file mode 100644 index 0000000000..02ccad5b5b --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html @@ -0,0 +1,523 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(VolumeTetrapore,"TETRAHEDRALPORE")
+     136             : 
+     137           2 : void VolumeTetrapore::registerKeywords( Keywords& keys ) {
+     138           2 :   ActionVolume::registerKeywords( keys );
+     139           4 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     140           4 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     141           4 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     142           4 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     143           2 : }
+     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_perp<=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.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func-sort-c.html b/coverage/multicolvar/XAngle.cpp.func-sort-c.html new file mode 100644 index 0000000000..ac99506810 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE9
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func.html b/coverage/multicolvar/XAngle.cpp.func.html new file mode 100644 index 0000000000..8142e45fb0 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe996createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_119XAnglesRegisterMe99D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1006createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe100D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe1016createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_120XAnglesRegisterMe101D2Ev4168
_ZN4PLMD11multicolvar7XAngles10isPeriodicEv3
_ZN4PLMD11multicolvar7XAngles16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar7XAnglesC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar7XAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.gcov.html b/coverage/multicolvar/XAngle.cpp.gcov.html new file mode 100644 index 0000000000..81a156c4e2 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(XAngles,"XANGLES")
+     100       12504 : PLUMED_REGISTER_ACTION(XAngles,"YANGLES")
+     101       12508 : PLUMED_REGISTER_ACTION(XAngles,"ZANGLES")
+     102             : 
+     103           9 : void XAngles::registerKeywords( Keywords& keys ) {
+     104           9 :   MultiColvarBase::registerKeywords( keys );
+     105          18 :   keys.use("MAX"); keys.use("ALT_MIN");
+     106          27 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     107          18 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     108          36 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     109          18 :   keys.add("numbered","ATOMS","the atoms involved in each of the angles you wish to calculate. "
+     110             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one angle will be "
+     111             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     112             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     113             :            "action will depend on what functions of the distribution you choose to calculate.");
+     114          18 :   keys.reset_style("ATOMS","atoms");
+     115          18 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     116          18 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     117             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     118          18 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     119             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     120          18 :   keys.add("optional","SWITCH","A switching function that ensures that only angles are only computed when atoms are within "
+     121             :            "are within a certain fixed cutoff. The following provides information on the \\ref switchingfunction that are available.");
+     122           9 : }
+     123             : 
+     124           3 : XAngles::XAngles(const ActionOptions&ao):
+     125             :   Action(ao),
+     126             :   MultiColvarBase(ao),
+     127           3 :   use_sf(false)
+     128             : {
+     129           3 :   if( getName().find("X")!=std::string::npos) myc=0;
+     130           2 :   else if( getName().find("Y")!=std::string::npos) myc=1;
+     131           2 :   else if( getName().find("Z")!=std::string::npos) myc=2;
+     132           0 :   else plumed_error();
+     133             : 
+     134             :   // Read in switching function
+     135           6 :   std::string sfinput, errors; parse("SWITCH",sfinput);
+     136           3 :   if( sfinput.length()>0 ) {
+     137           2 :     use_sf=true; weightHasDerivatives=true;
+     138           2 :     sf1.set(sfinput,errors);
+     139           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     140           2 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     141           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     142             :   }
+     143             : 
+     144             :   // Read in the atoms
+     145             :   std::vector<AtomNumber> all_atoms;
+     146           6 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     147           4 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     148           3 :   setupMultiColvarBase( all_atoms );
+     149             :   // And check everything has been read in correctly
+     150           3 :   checkRead();
+     151           3 : }
+     152             : 
+     153         110 : double XAngles::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     154         110 :   if(!use_sf) return 1.0;
+     155             : 
+     156         100 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     157         100 :   double dw, w = sf1.calculateSqr( distance.modulo2(), dw );
+     158         100 :   addAtomDerivatives( 0, 0, (-dw)*distance, myatoms );
+     159         100 :   addAtomDerivatives( 0, 1, (+dw)*distance, myatoms );
+     160         100 :   myatoms.addBoxDerivatives( 0, (-dw)*Tensor(distance,distance) );
+     161         100 :   return w;
+     162             : }
+     163             : 
+     164          50 : double XAngles::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     165          50 :   Vector ddij, ddik, axis, distance; axis.zero(); axis[myc]=1;
+     166          50 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     167          50 :   PLMD::Angle a; double angle=a.compute( distance, axis, ddij, ddik );
+     168             : 
+     169          50 :   addAtomDerivatives( 1, 0, -ddij, myatoms );
+     170          50 :   addAtomDerivatives( 1, 1, ddij, myatoms );
+     171          50 :   myatoms.addBoxDerivatives( 1, -Tensor( distance,ddij ) );
+     172          50 :   return angle;
+     173             : }
+     174             : 
+     175             : }
+     176             : }
+     177             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.func-sort-c.html b/coverage/multicolvar/XDistances.cpp.func-sort-c.html new file mode 100644 index 0000000000..09b192b7ee --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.func.html b/coverage/multicolvar/XDistances.cpp.func.html new file mode 100644 index 0000000000..da461ee088 --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XDistances10isPeriodicEv0
_ZN4PLMD11multicolvar10XDistances16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar10XDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10XDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1856createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe185D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1866createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe186D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe1876createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_123XDistancesRegisterMe187D2Ev4168
_ZNK4PLMD11multicolvar10XDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.gcov.html b/coverage/multicolvar/XDistances.cpp.gcov.html new file mode 100644 index 0000000000..7a4ab7c783 --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.gcov.html @@ -0,0 +1,317 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(XDistances,"XDISTANCES")
+     186       12504 : PLUMED_REGISTER_ACTION(XDistances,"YDISTANCES")
+     187       12504 : PLUMED_REGISTER_ACTION(XDistances,"ZDISTANCES")
+     188             : 
+     189           6 : void XDistances::registerKeywords( Keywords& keys ) {
+     190           6 :   MultiColvarBase::registerKeywords( keys );
+     191          12 :   keys.use("MAX"); keys.use("ALT_MIN");
+     192          18 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     193          12 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     194          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     195          12 :   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          12 :   keys.reset_style("ATOMS","atoms");
+     201          12 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     202          12 :   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          12 :   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           6 : }
+     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.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.func-sort-c.html b/coverage/multicolvar/XYDistances.cpp.func-sort-c.html new file mode 100644 index 0000000000..1e5bbed8a4 --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.func.html b/coverage/multicolvar/XYDistances.cpp.func.html new file mode 100644 index 0000000000..5f1a34b99d --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:71450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11XYDistances10isPeriodicEv0
_ZN4PLMD11multicolvar11XYDistances16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar11XYDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11XYDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1106createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe110D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1116createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe111D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe1126createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_124XYDistancesRegisterMe112D2Ev4168
_ZNK4PLMD11multicolvar11XYDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.gcov.html b/coverage/multicolvar/XYDistances.cpp.gcov.html new file mode 100644 index 0000000000..561ee65ed2 --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(XYDistances,"XYDISTANCES")
+     111       12504 : PLUMED_REGISTER_ACTION(XYDistances,"XZDISTANCES")
+     112       12504 : PLUMED_REGISTER_ACTION(XYDistances,"YZDISTANCES")
+     113             : 
+     114           6 : void XYDistances::registerKeywords( Keywords& keys ) {
+     115           6 :   MultiColvarBase::registerKeywords( keys );
+     116          12 :   keys.use("MAX"); keys.use("ALT_MIN");
+     117          30 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     118          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     119          12 :   keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
+     120             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
+     121             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     122             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     123             :            "action will depend on what functions of the distribution you choose to calculate.");
+     124          12 :   keys.reset_style("ATOMS","atoms");
+     125          12 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     126          12 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     127             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     128          12 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     129             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     130           6 : }
+     131             : 
+     132           0 : XYDistances::XYDistances(const ActionOptions&ao):
+     133             :   Action(ao),
+     134           0 :   MultiColvarBase(ao)
+     135             : {
+     136           0 :   if( getName().find("XY")!=std::string::npos) {
+     137           0 :     myc1=0; myc2=1;
+     138           0 :   } else if( getName().find("XZ")!=std::string::npos) {
+     139           0 :     myc1=0; myc2=2;
+     140           0 :   } else if( getName().find("YZ")!=std::string::npos) {
+     141           0 :     myc1=1; myc2=2;
+     142           0 :   } else plumed_error();
+     143             : 
+     144             :   // Read in the atoms
+     145             :   std::vector<AtomNumber> all_atoms;
+     146           0 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     147           0 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     148           0 :   setupMultiColvarBase( all_atoms );
+     149             :   // And check everything has been read in correctly
+     150           0 :   checkRead();
+     151           0 : }
+     152             : 
+     153           0 : double XYDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     154           0 :   Vector distance;
+     155           0 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     156           0 :   const double value=std::sqrt(distance[myc1]*distance[myc1] + distance[myc2]*distance[myc2] );
+     157           0 :   const double invvalue=1.0/value;
+     158             : 
+     159           0 :   Vector myvec; myvec.zero();
+     160             :   // And finish the calculation
+     161           0 :   myvec[myc1]=+invvalue*distance[myc1]; myvec[myc2]=+invvalue*distance[myc2]; addAtomDerivatives( 1, 1, myvec, myatoms  );
+     162           0 :   myvec[myc1]=-invvalue*distance[myc1]; myvec[myc2]=-invvalue*distance[myc2]; addAtomDerivatives( 1, 0, myvec, myatoms );
+     163           0 :   myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
+     164           0 :   return value;
+     165             : }
+     166             : 
+     167             : }
+     168             : }
+     169             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html b/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html new file mode 100644 index 0000000000..1b237ed476 --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE15
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.func.html b/coverage/multicolvar/XYTorsion.cpp.func.html new file mode 100644 index 0000000000..69d026a90d --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05:14Functions:202580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1496createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe149D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1506createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe150D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1516createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe151D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1526createERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe152D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1536createERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe153D2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe1546createERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154C2Ev4168
_ZN4PLMD11multicolvar12_GLOBAL__N_122XYTorsionRegisterMe154D2Ev4168
_ZN4PLMD11multicolvar9XYTorsion10isPeriodicEv3
_ZN4PLMD11multicolvar9XYTorsion14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1
_ZN4PLMD11multicolvar9XYTorsion16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD11multicolvar9XYTorsionC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar9XYTorsionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.gcov.html b/coverage/multicolvar/XYTorsion.cpp.gcov.html new file mode 100644 index 0000000000..69a8ba2926 --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.gcov.html @@ -0,0 +1,310 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_ACTION(XYTorsion,"XYTORSIONS")
+     150       12504 : PLUMED_REGISTER_ACTION(XYTorsion,"XZTORSIONS")
+     151       12504 : PLUMED_REGISTER_ACTION(XYTorsion,"YXTORSIONS")
+     152       12504 : PLUMED_REGISTER_ACTION(XYTorsion,"YZTORSIONS")
+     153       12508 : PLUMED_REGISTER_ACTION(XYTorsion,"ZXTORSIONS")
+     154       12506 : PLUMED_REGISTER_ACTION(XYTorsion,"ZYTORSIONS")
+     155             : 
+     156          15 : void XYTorsion::registerKeywords( Keywords& keys ) {
+     157          15 :   MultiColvarBase::registerKeywords( keys );
+     158          30 :   keys.use("MAX"); keys.use("ALT_MIN");
+     159          30 :   keys.use("MEAN"); keys.use("MIN");
+     160          30 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     161          45 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     162          30 :   keys.add("numbered","ATOMS","the atoms involved in each of the torsion angles you wish to calculate. "
+     163             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be "
+     164             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     165             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     166             :            "action will depend on what functions of the distribution you choose to calculate.");
+     167          30 :   keys.reset_style("ATOMS","atoms");
+     168          30 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     169          30 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     170             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     171          30 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     172             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     173          30 :   keys.add("optional","SWITCH","A switching function that ensures that only angles are only computed when atoms are within "
+     174             :            "are within a certain fixed cutoff. The following provides information on the \\ref switchingfunction that are available.");
+     175          15 : }
+     176             : 
+     177           3 : XYTorsion::XYTorsion(const ActionOptions&ao):
+     178             :   Action(ao),
+     179             :   MultiColvarBase(ao),
+     180           3 :   use_sf(false)
+     181             : {
+     182           3 :   if( getName().find("XY")!=std::string::npos) { myc1=0; myc2=1; }
+     183           3 :   else if( getName().find("XZ")!=std::string::npos) { myc1=0; myc2=2; }
+     184           3 :   else if( getName().find("YX")!=std::string::npos) { myc1=1; myc2=0; }
+     185           3 :   else if( getName().find("YZ")!=std::string::npos) { myc1=1; myc2=2; }
+     186           3 :   else if( getName().find("ZX")!=std::string::npos) { myc1=2; myc2=0; }
+     187           1 :   else if( getName().find("ZY")!=std::string::npos) { myc1=2; myc2=1; }
+     188           0 :   else plumed_error();
+     189             : 
+     190             :   // Read in switching function
+     191           6 :   std::string sfinput, errors; parse("SWITCH",sfinput);
+     192           3 :   if( sfinput.length()>0 ) {
+     193           2 :     use_sf=true; weightHasDerivatives=true;
+     194           2 :     sf1.set(sfinput,errors);
+     195           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     196           2 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     197           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     198             :   }
+     199             : 
+     200             :   // Read in the atoms
+     201             :   std::vector<AtomNumber> all_atoms;
+     202           6 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     203           4 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     204           3 :   setupMultiColvarBase( all_atoms );
+     205             :   // And check everything has been read in correctly
+     206           3 :   checkRead();
+     207           3 : }
+     208             : 
+     209         110 : double XYTorsion::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     210         110 :   if(!use_sf) return 1.0;
+     211             : 
+     212         100 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     213         100 :   double dw, w = sf1.calculateSqr( distance.modulo2(), dw );
+     214         100 :   addAtomDerivatives( 0, 0, (-dw)*distance, myatoms );
+     215         100 :   addAtomDerivatives( 0, 1, (+dw)*distance, myatoms );
+     216         100 :   myatoms.addBoxDerivatives( 0, (-dw)*Tensor(distance,distance) );
+     217         100 :   return w;
+     218             : }
+     219             : 
+     220          50 : double XYTorsion::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     221          50 :   Vector dd0, dd1, dd2, axis, rot, distance;
+     222          50 :   axis.zero(); rot.zero(); rot[myc1]=1; axis[myc2]=1;
+     223          50 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     224          50 :   PLMD::Torsion t; double torsion=t.compute( distance, rot, axis, dd0, dd1, dd2 );
+     225             : 
+     226          50 :   addAtomDerivatives( 1, 0, -dd0, myatoms );
+     227          50 :   addAtomDerivatives( 1, 1, dd0, myatoms );
+     228          50 :   myatoms.addBoxDerivatives( 1, -extProduct(distance,dd0) );
+     229          50 :   return torsion;
+     230             : }
+     231             : 
+     232             : }
+     233             : }
+     234             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-f.html b/coverage/multicolvar/index-sort-f.html new file mode 100644 index 0000000000..68b7fad817 --- /dev/null +++ b/coverage/multicolvar/index-sort-f.html @@ -0,0 +1,523 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2377302578.6 %
Date:2024-05-27 13:05: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
InPlaneDistances.cpp +
21.3%21.3%
+
21.3 %10 / 4737.5 %3 / 8
VolumeBetweenContours.cpp +
14.0%14.0%
+
14.0 %7 / 5037.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
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %49 / 5075.0 %6 / 8
VolumeGradientBase.cpp +
78.9%78.9%
+
78.9 %45 / 5775.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
FilterBetween.cpp +
82.8%82.8%
+
82.8 %24 / 2980.0 %8 / 10
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
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.2%86.2%
+
86.2 %131 / 15284.6 %11 / 13
CenterOfMultiColvar.cpp +
96.2%96.2%
+
96.2 %77 / 8085.7 %6 / 7
XAngle.cpp +
98.0%98.0%
+
98.0 %50 / 5186.7 %13 / 15
VolumeAround.cpp +
100.0%
+
100.0 %48 / 4887.5 %7 / 8
MultiColvarProduct.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
VolumeInCylinder.cpp +
95.9%95.9%
+
95.9 %47 / 4987.5 %7 / 8
MultiColvarCombine.cpp +
100.0%
+
100.0 %31 / 3187.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
VolumeInSphere.cpp +
100.0%
+
100.0 %26 / 2687.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
CatomPack.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
MultiColvarFilter.h +
100.0%
+
100.0 %2 / 2100.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
CatomPack.h +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
AtomValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %4 / 4
AtomValuePack.h +
95.1%95.1%
+
95.1 %39 / 41100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-l.html b/coverage/multicolvar/index-sort-l.html new file mode 100644 index 0000000000..eca67794aa --- /dev/null +++ b/coverage/multicolvar/index-sort-l.html @@ -0,0 +1,523 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2377302578.6 %
Date:2024-05-27 13:05: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
VolumeGradientBase.cpp +
78.9%78.9%
+
78.9 %45 / 5775.0 %6 / 8
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
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.2%86.2%
+
86.2 %131 / 15284.6 %11 / 13
AlphaBeta.cpp +
87.9%87.9%
+
87.9 %51 / 5875.0 %6 / 8
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.2%96.2%
+
96.2 %77 / 8085.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
CatomPack.h +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
VolumeGradientBase.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
MultiColvarProduct.cpp +
100.0%
+
100.0 %26 / 2687.5 %7 / 8
VolumeInSphere.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.16
+
+ + + diff --git a/coverage/multicolvar/index.html b/coverage/multicolvar/index.html new file mode 100644 index 0000000000..6f8c9f4c92 --- /dev/null +++ b/coverage/multicolvar/index.html @@ -0,0 +1,523 @@ + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2377302578.6 %
Date:2024-05-27 13:05: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 +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
CenterOfMultiColvar.cpp +
96.2%96.2%
+
96.2 %77 / 8085.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.2%86.2%
+
86.2 %131 / 15284.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 +
78.9%78.9%
+
78.9 %45 / 5775.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.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func-sort-c.html b/coverage/opes/ECVcustom.cpp.func-sort-c.html new file mode 100644 index 0000000000..611482189f --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func.html b/coverage/opes/ECVcustom.cpp.func.html new file mode 100644 index 0000000000..738a7c00be --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe856createERKNS_13ActionOptionsE2
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_121ECVcustomRegisterMe85D2Ev4168
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.gcov.html b/coverage/opes/ECVcustom.cpp.gcov.html new file mode 100644 index 0000000000..9b70c5a3bf --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(ECVcustom,"ECV_CUSTOM")
+      86             : 
+      87           4 : void ECVcustom::registerKeywords(Keywords& keys)
+      88             : {
+      89           4 :   ExpansionCVs::registerKeywords(keys);
+      90           4 :   keys.remove("ARG");
+      91           8 :   keys.add("compulsory","ARG","the labels of the single ECVs. \\f$\\Delta U_i\\f$, in energy units");
+      92           8 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+      93           8 :   keys.addFlag("DIMENSIONLESS",false,"consider ARG as dimensionless rather than an energy, thus do not multiply it by \\f$\\beta\\f$");
+      94           8 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+      95           4 : }
+      96             : 
+      97           2 : ECVcustom::ECVcustom(const ActionOptions&ao)
+      98             :   : Action(ao)
+      99             :   , ExpansionCVs(ao)
+     100           2 :   , beta0_(1./kbt_)
+     101             : {
+     102             : //set beta0_
+     103             :   bool dimensionless;
+     104           2 :   parseFlag("DIMENSIONLESS",dimensionless);
+     105           2 :   if(dimensionless)
+     106           0 :     beta0_=1;
+     107             : 
+     108             : //set P0_contribution_
+     109           2 :   bool add_P0=false;
+     110           2 :   parseFlag("ADD_P0",add_P0);
+     111           2 :   if(add_P0)
+     112           2 :     P0_contribution_=1;
+     113             :   else
+     114           0 :     P0_contribution_=0;
+     115             : 
+     116             : //set barrier_
+     117           2 :   barrier_=std::numeric_limits<double>::infinity();
+     118           2 :   parse("BARRIER",barrier_);
+     119             : 
+     120           2 :   checkRead();
+     121             : 
+     122             : //set ECVs stuff
+     123           2 :   totNumECVs_=getNumberOfArguments()+P0_contribution_;
+     124           2 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     125           2 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     126           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     127           4 :     derECVs_[j][j+P0_contribution_]=beta0_; //always constant
+     128             : 
+     129             : //print some info
+     130           2 :   if(dimensionless)
+     131           0 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     132           2 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     133             :   {
+     134           0 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     135           0 :     if(dimensionless)
+     136           0 :       log.printf("    also the BARRIER is considered to be DIMENSIONLESS\n");
+     137             :   }
+     138           2 :   if(P0_contribution_==1)
+     139           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     140           2 : }
+     141             : 
+     142          91 : void ECVcustom::calculateECVs(const double * cv)
+     143             : {
+     144         273 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     145         182 :     ECVs_[j][j+P0_contribution_]=beta0_*cv[j];
+     146             :   //derivative is constant
+     147          91 : }
+     148             : 
+     149           4 : const double * ECVcustom::getPntrToECVs(unsigned j)
+     150             : {
+     151           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     152           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     153           4 :   return &ECVs_[j][0];
+     154             : }
+     155             : 
+     156           4 : const double * ECVcustom::getPntrToDerECVs(unsigned j)
+     157             : {
+     158           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     159           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     160           4 :   return &derECVs_[j][0];
+     161             : }
+     162             : 
+     163           2 : std::vector< std::vector<unsigned> > ECVcustom::getIndex_k() const
+     164             : {
+     165           2 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     166           2 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+     167           8 :   for(unsigned k=0; k<totNumECVs_; k++)
+     168          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     169          12 :       if(k==j+P0_contribution_)
+     170           4 :         index_k[k][j]=k;
+     171           2 :   return index_k;
+     172           0 : }
+     173             : 
+     174           2 : std::vector<std::string> ECVcustom::getLambdas() const
+     175             : {
+     176           2 :   std::vector<std::string> lambdas(totNumECVs_);
+     177           2 :   if(P0_contribution_==1)
+     178             :   {
+     179           2 :     std::ostringstream subs;
+     180           2 :     subs<<"P0";
+     181           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     182           2 :       subs<<"_P0";
+     183           2 :     lambdas[0]=subs.str();
+     184           2 :   }
+     185           6 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     186             :   {
+     187           4 :     const unsigned kk=k-P0_contribution_;
+     188           4 :     std::ostringstream subs;
+     189             : //the getLambdas method is const, so it complains if one tries to access a non-const pointer, hence the const_cast
+     190           4 :     if(kk==0)
+     191             :       subs<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     192             :     else
+     193           2 :       subs<<"NaN";
+     194           8 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     195             :     {
+     196           4 :       if(kk==j)
+     197           2 :         subs<<"_"<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     198             :       else
+     199           2 :         subs<<"_NaN";
+     200             :     }
+     201           4 :     lambdas[k]=subs.str();
+     202           4 :   }
+     203           2 :   return lambdas;
+     204           0 : }
+     205             : 
+     206           2 : void ECVcustom::initECVs()
+     207             : {
+     208           2 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     209           2 :   isReady_=true;
+     210           2 :   log.printf("  *%4u ECVs for %s\n",totNumECVs_,getName().c_str());
+     211           2 : }
+     212             : 
+     213           1 : void ECVcustom::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     214             : {
+     215           1 :   initECVs();
+     216           1 :   calculateECVs(&all_obs_cvs[index_j]);
+     217           3 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218           4 :     ECVs_[j][j+P0_contribution_]=std::min(barrier_*beta0_,ECVs_[j][j+P0_contribution_]);
+     219           1 : }
+     220             : 
+     221           1 : void ECVcustom::initECVs_restart(const std::vector<std::string>& lambdas)
+     222             : {
+     223             :   std::size_t pos=0;
+     224           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     225           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     226           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     227           1 :   pos=lambdas[0].find("_",pos+1);
+     228           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     229             : 
+     230           1 :   std::vector<std::string> myLambdas=getLambdas();
+     231           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     232           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     233             : 
+     234           1 :   initECVs();
+     235           1 : }
+     236             : 
+     237             : }
+     238             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func-sort-c.html b/coverage/opes/ECVlinear.cpp.func-sort-c.html new file mode 100644 index 0000000000..44fbd89764 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func.html b/coverage/opes/ECVlinear.cpp.func.html new file mode 100644 index 0000000000..d4907d6f1b --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe956createERKNS_13ActionOptionsE4
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_121ECVlinearRegisterMe95D2Ev4168
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.gcov.html b/coverage/opes/ECVlinear.cpp.gcov.html new file mode 100644 index 0000000000..4a0d81276c --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.gcov.html @@ -0,0 +1,344 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(ECVlinear,"ECV_LINEAR")
+      96             : 
+      97           6 : void ECVlinear::registerKeywords(Keywords& keys)
+      98             : {
+      99           6 :   ExpansionCVs::registerKeywords(keys);
+     100           6 :   keys.remove("ARG");
+     101          12 :   keys.add("compulsory","ARG","the label of the Hamiltonian difference. \\f$\\Delta U\\f$");
+     102          12 :   keys.add("compulsory","LAMBDA","0","the lambda at which the underlying simulation runs");
+     103          12 :   keys.add("optional","LAMBDA_MIN","( default=0 ) the minimum of the lambda range");
+     104          12 :   keys.add("optional","LAMBDA_MAX","( default=1 ) the maximum of the lambda range");
+     105          12 :   keys.add("optional","LAMBDA_STEPS","uniformly place the lambda values, for a total of LAMBDA_STEPS");
+     106          12 :   keys.add("optional","LAMBDA_SET_ALL","manually set all the lamdbas");
+     107          12 :   keys.addFlag("DIMENSIONLESS",false,"ARG is considered dimensionless rather than an energy, thus is not multiplied by \\f$\\beta\\f$");
+     108          12 :   keys.addFlag("GEOM_SPACING",false,"use geometrical spacing in lambda instead of linear spacing");
+     109           6 : }
+     110             : 
+     111           4 : ECVlinear::ECVlinear(const ActionOptions&ao)
+     112             :   : Action(ao)
+     113             :   , ExpansionCVs(ao)
+     114           4 :   , todoAutomatic_(false)
+     115           4 :   , beta0_(1./kbt_)
+     116             : {
+     117           4 :   plumed_massert(getNumberOfArguments()==1,"only DeltaU should be given as ARG");
+     118             : 
+     119             : //set beta0_
+     120             :   bool dimensionless;
+     121           4 :   parseFlag("DIMENSIONLESS",dimensionless);
+     122           4 :   if(dimensionless)
+     123           1 :     beta0_=1;
+     124             : 
+     125             : //parse lambda info
+     126           4 :   parse("LAMBDA",lambda0_);
+     127             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     128           4 :   double lambda_min=myNone;
+     129           4 :   double lambda_max=myNone;
+     130           4 :   parse("LAMBDA_MIN",lambda_min);
+     131           4 :   parse("LAMBDA_MAX",lambda_max);
+     132           4 :   unsigned lambda_steps=0;
+     133           8 :   parse("LAMBDA_STEPS",lambda_steps);
+     134             :   std::vector<double> lambdas;
+     135           4 :   parseVector("LAMBDA_SET_ALL",lambdas);
+     136           4 :   parseFlag("GEOM_SPACING",geom_spacing_);
+     137             : 
+     138           4 :   checkRead();
+     139             : 
+     140             : //set the diff vector using lambdas
+     141           4 :   if(lambdas.size()>0)
+     142             :   {
+     143           1 :     plumed_massert(lambda_steps==0,"cannot set both LAMBDA_STEPS and LAMBDA_SET_ALL");
+     144           1 :     plumed_massert(lambda_min==myNone && lambda_max==myNone,"cannot set both LAMBDA_SET_ALL and LAMBDA_MIN/MAX");
+     145           1 :     plumed_massert(lambdas.size()>=2,"set at least 2 lambdas with LAMBDA_SET_ALL");
+     146           4 :     for(unsigned k=0; k<lambdas.size()-1; k++)
+     147           3 :       plumed_massert(lambdas[k]<=lambdas[k+1],"LAMBDA_SET_ALL must be properly ordered");
+     148           1 :     lambda_min=lambdas[0];
+     149           1 :     lambda_max=lambdas[lambdas.size()-1];
+     150           1 :     derECVs_.resize(lambdas.size());
+     151           5 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     152           4 :       derECVs_[k]=beta0_*(lambdas[k]-lambda0_);
+     153             :   }
+     154             :   else
+     155             :   { //get LAMBDA_MIN and LAMBDA_MAX
+     156           3 :     if(lambda_min==myNone)
+     157             :     {
+     158           0 :       lambda_min=0;
+     159           0 :       log.printf("  no LAMBDA_MIN provided, using LAMBDA_MIN = %g\n",lambda_min);
+     160             :     }
+     161           3 :     if(lambda_max==myNone)
+     162             :     {
+     163           1 :       lambda_max=1;
+     164           1 :       log.printf("  no LAMBDA_MAX provided, using LAMBDA_MAX = %g\n",lambda_max);
+     165             :     }
+     166           3 :     plumed_massert(lambda_max>=lambda_min,"LAMBDA_MAX should be bigger than LAMBDA_MIN");
+     167           3 :     derECVs_.resize(2);
+     168           3 :     derECVs_[0]=beta0_*(lambda_min-lambda0_);
+     169           3 :     derECVs_[1]=beta0_*(lambda_max-lambda0_);
+     170           3 :     if(lambda_min==lambda_max && lambda_steps==0)
+     171           0 :       lambda_steps=1;
+     172           3 :     if(lambda_steps>0)
+     173           2 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     174             :     else
+     175           2 :       todoAutomatic_=true;
+     176             :   }
+     177           4 :   if(lambda0_<lambda_min || lambda0_>lambda_max)
+     178           1 :     log.printf(" +++ WARNING +++ running at LAMBDA=%g which is outside the chosen lambda range\n",lambda0_);
+     179             : 
+     180             : //print some info
+     181           4 :   log.printf("  running at LAMBDA=%g\n",lambda0_);
+     182           4 :   log.printf("  targeting a lambda range from LAMBDA_MIN=%g to LAMBDA_MAX=%g\n",lambda_min,lambda_max);
+     183           4 :   if(dimensionless)
+     184           1 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     185           4 :   if(geom_spacing_)
+     186           1 :     log.printf(" -- GEOM_SPACING: lambdas will be geometrically spaced\n");
+     187           4 : }
+     188             : 
+     189         182 : void ECVlinear::calculateECVs(const double * DeltaU)
+     190             : {
+     191        1587 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     192        1405 :     ECVs_[k]=derECVs_[k]*DeltaU[0];
+     193             : // derivatives never change: derECVs_k=beta0*(lambda_k-lambda0)
+     194         182 : }
+     195             : 
+     196           4 : const double * ECVlinear::getPntrToECVs(unsigned j)
+     197             : {
+     198           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     199           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     200           4 :   return &ECVs_[0];
+     201             : }
+     202             : 
+     203           4 : const double * ECVlinear::getPntrToDerECVs(unsigned j)
+     204             : {
+     205           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     206           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     207           4 :   return &derECVs_[0];
+     208             : }
+     209             : 
+     210           4 : std::vector<std::string> ECVlinear::getLambdas() const
+     211             : {
+     212           4 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     213           4 :   std::vector<std::string> lambdas(derECVs_.size());
+     214          35 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     215             :   {
+     216          31 :     std::ostringstream subs;
+     217          31 :     subs<<derECVs_[k]/beta0_+lambda0_; //lambda_k
+     218          31 :     lambdas[k]=subs.str();
+     219          31 :   }
+     220           4 :   return lambdas;
+     221           0 : }
+     222             : 
+     223           4 : void ECVlinear::initECVs()
+     224             : {
+     225           4 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     226           4 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     227           4 :   totNumECVs_=derECVs_.size();
+     228           4 :   ECVs_.resize(derECVs_.size());
+     229           4 :   isReady_=true;
+     230           4 :   log.printf("  *%4lu lambdas for %s\n",derECVs_.size(),getName().c_str());
+     231           4 : }
+     232             : 
+     233           3 : void ECVlinear::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     234             : {
+     235           3 :   if(todoAutomatic_) //estimate the steps in lambda from observations
+     236             :   {
+     237           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     238           1 :     std::vector<double> obs_cv(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     239          11 :     for(unsigned t=0; t<obs_cv.size(); t++)
+     240          10 :       obs_cv[t]=all_obs_cvs[t*ncv+index_j];
+     241           1 :     const unsigned lambda_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_cv,"LAMBDA");
+     242           1 :     if(beta0_!=1)
+     243           0 :       log.printf("    (spacing is in beta0 units)\n");
+     244           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     245           1 :     todoAutomatic_=false;
+     246             :   }
+     247           3 :   initECVs();
+     248           3 :   calculateECVs(&all_obs_cvs[index_j]);
+     249           3 : }
+     250             : 
+     251           1 : void ECVlinear::initECVs_restart(const std::vector<std::string>& lambdas)
+     252             : {
+     253           1 :   std::size_t pos=lambdas[0].find("_");
+     254           1 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     255           1 :   if(todoAutomatic_)
+     256             :   {
+     257           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     258           1 :     todoAutomatic_=false;
+     259             :   }
+     260           1 :   std::vector<std::string> myLambdas=getLambdas();
+     261           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     262           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     263             : 
+     264           1 :   initECVs();
+     265           1 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html new file mode 100644 index 0000000000..6f6a24d513 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func.html b/coverage/opes/ECVmultiThermal.cpp.func.html new file mode 100644 index 0000000000..1748e6207a --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe1036createERKNS_13ActionOptionsE11
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVmultiThermalRegisterMe103D2Ev4168
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.gcov.html b/coverage/opes/ECVmultiThermal.cpp.gcov.html new file mode 100644 index 0000000000..306adb7381 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.gcov.html @@ -0,0 +1,346 @@ + + + + + + + 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-05-27 13:05: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       12526 : PLUMED_REGISTER_ACTION(ECVmultiThermal,"ECV_MULTITHERMAL")
+     104             : 
+     105          13 : void ECVmultiThermal::registerKeywords(Keywords& keys)
+     106             : {
+     107          13 :   ExpansionCVs::registerKeywords(keys);
+     108          13 :   keys.remove("ARG");
+     109          26 :   keys.add("compulsory","ARG","the label of the internal energy of the system. If volume is fixed it is calculated by the \\ref ENERGY colvar");
+     110          26 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     111          26 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     112          26 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     113          26 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     114          26 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     115          13 : }
+     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.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html new file mode 100644 index 0000000000..a6d21a1144 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func.html b/coverage/opes/ECVmultiThermalBaric.cpp.func.html new file mode 100644 index 0000000000..96312d125f --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe1106createERKNS_13ActionOptionsE9
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_133ECVmultiThermalBaricRegisterMe110D2Ev4168
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html new file mode 100644 index 0000000000..b163e1ff8c --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html @@ -0,0 +1,608 @@ + + + + + + + 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-05-27 13:05: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       12522 : PLUMED_REGISTER_ACTION(ECVmultiThermalBaric,"ECV_MULTITHERMAL_MULTIBARIC")
+     111             : 
+     112          11 : void ECVmultiThermalBaric::registerKeywords(Keywords& keys)
+     113             : {
+     114          11 :   ExpansionCVs::registerKeywords(keys);
+     115          11 :   keys.remove("ARG");
+     116          22 :   keys.add("compulsory","ARG","the labels of the potential energy and of the volume of the system. You can calculate them with \\ref ENERGY and \\ref VOLUME respectively");
+     117             : //temperature
+     118          22 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     119          22 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     120          22 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     121          22 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     122          22 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     123             : //pressure
+     124          22 :   keys.add("compulsory","PRESSURE","pressure. Use the proper units");
+     125          22 :   keys.add("optional","PRESSURE_MIN","the minimum of the pressure range");
+     126          22 :   keys.add("optional","PRESSURE_MAX","the maximum of the pressure range");
+     127          22 :   keys.add("optional","PRESSURE_STEPS","the number of steps in pressure");
+     128          22 :   keys.add("optional","PRESSURE_SET_ALL","manually set all the pressures");
+     129             : //other
+     130          22 :   keys.add("optional","SET_ALL_TEMP_PRESSURE","manually set all the target temperature_pressure pairs. An underscore separates temperature and pressure, while different points are comma-separated, e.g.: temp1_pres1,temp1_pres2,...");
+     131          22 :   keys.add("optional","CUT_CORNER","avoid region of high temperature and low pressure. Exclude all points below a line in the temperature-pressure plane, defined by two points: \\f$T_{\\text{low}},P_{\\text{low}},T_{\\text{high}},P_{\\text{high}}\\f$");
+     132          11 : }
+     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           1 :     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.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html new file mode 100644 index 0000000000..eb13c1edba --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func.html b/coverage/opes/ECVumbrellasFile.cpp.func.html new file mode 100644 index 0000000000..a7940ac899 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe966createERKNS_13ActionOptionsE3
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasFileRegisterMe96D2Ev4168
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.gcov.html b/coverage/opes/ECVumbrellasFile.cpp.gcov.html new file mode 100644 index 0000000000..a618d4fa71 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(ECVumbrellasFile,"ECV_UMBRELLAS_FILE")
+      97             : 
+      98           5 : void ECVumbrellasFile::registerKeywords(Keywords& keys)
+      99             : {
+     100           5 :   ExpansionCVs::registerKeywords(keys);
+     101           5 :   keys.use("ARG");
+     102          10 :   keys.add("compulsory","FILE","the name of the file containing the umbrellas");
+     103          10 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     104          10 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     105          10 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     106           5 : }
+     107             : 
+     108           3 : ECVumbrellasFile::ECVumbrellasFile(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           3 :   ExpansionCVs(ao)
+     111             : {
+     112             : //get number of CVs
+     113             :   const unsigned ncv=getNumberOfArguments();
+     114           3 :   centers_.resize(ncv);
+     115           3 :   sigmas_.resize(ncv);
+     116             : 
+     117             : //set P0_contribution_
+     118           3 :   bool add_P0=false;
+     119           3 :   parseFlag("ADD_P0",add_P0);
+     120           3 :   if(add_P0)
+     121           2 :     P0_contribution_=1;
+     122             :   else
+     123           1 :     P0_contribution_=0;
+     124             : 
+     125             : //set barrier_
+     126           3 :   barrier_=std::numeric_limits<double>::infinity();
+     127           3 :   parse("BARRIER",barrier_);
+     128           6 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     129             : 
+     130             : //set umbrellas
+     131             :   std::string umbrellasFileName;
+     132           3 :   parse("FILE",umbrellasFileName);
+     133           3 :   IFile ifile;
+     134           3 :   ifile.link(*this);
+     135           3 :   if(ifile.FileExist(umbrellasFileName))
+     136             :   {
+     137           3 :     log.printf("  reading from FILE '%s'\n",umbrellasFileName.c_str());
+     138           3 :     ifile.open(umbrellasFileName);
+     139           3 :     ifile.allowIgnoredFields();
+     140             :     double time; //first field is ignored
+     141        1332 :     while(ifile.scanField("time",time))
+     142             :     {
+     143        1989 :       for(unsigned j=0; j<ncv; j++)
+     144             :       {
+     145             :         double centers_j;
+     146        1326 :         ifile.scanField(getPntrToArgument(j)->getName(),centers_j);
+     147        1326 :         centers_[j].push_back(centers_j); //this might be slow
+     148             :       }
+     149        1989 :       for(unsigned j=0; j<ncv; j++)
+     150             :       {
+     151             :         double sigmas_j;
+     152        2652 :         ifile.scanField("sigma_"+getPntrToArgument(j)->getName(),sigmas_j);
+     153        1326 :         sigmas_[j].push_back(sigmas_j);
+     154             :       }
+     155         663 :       ifile.scanField();
+     156             :     }
+     157             :   }
+     158             :   else
+     159           0 :     plumed_merror("Umbrellas FILE '"+umbrellasFileName+"' not found");
+     160             : 
+     161           3 :   checkRead();
+     162             : 
+     163             : //extra consistency checks
+     164           3 :   const unsigned sizeUmbrellas=centers_[0].size();
+     165           9 :   for(unsigned j=0; j<ncv; j++)
+     166             :   {
+     167           6 :     plumed_massert(centers_[j].size()==sizeUmbrellas,"mismatch in the number of centers read from file");
+     168           6 :     plumed_massert(sigmas_[j].size()==sizeUmbrellas,"mismatch in the number of sigmas read from file");
+     169             :   }
+     170             : 
+     171             : //set ECVs stuff
+     172           3 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     173           3 :   ECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     174           3 :   derECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     175             : 
+     176             : //printing some info
+     177           3 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     178           3 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     179           1 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     180           3 :   if(P0_contribution_==1)
+     181           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     182           3 :   if(lower_only_)
+     183           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     184           6 : }
+     185             : 
+     186         131 : void ECVumbrellasFile::calculateECVs(const double * cv)
+     187             : {
+     188         131 :   if(lower_only_)
+     189             :   {
+     190         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     191             :     {
+     192       22644 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     193             :       {
+     194       22542 :         const unsigned kk=k-P0_contribution_;
+     195       22542 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     196       22542 :         if(dist_jk>=0)
+     197             :         {
+     198       11483 :           ECVs_[j][k]=0;
+     199       11483 :           derECVs_[j][k]=0;
+     200             :         }
+     201             :         else
+     202             :         {
+     203       11059 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     204       11059 :           derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     205             :         }
+     206             :       }
+     207             :     }
+     208             :   }
+     209             :   else
+     210             :   {
+     211         240 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     212             :     {
+     213       35520 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     214             :       {
+     215       35360 :         const unsigned kk=k-P0_contribution_;
+     216       35360 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     217       35360 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     218       35360 :         derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     219             :       }
+     220             :     }
+     221             :   }
+     222         131 : }
+     223             : 
+     224           6 : const double * ECVumbrellasFile::getPntrToECVs(unsigned j)
+     225             : {
+     226           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     227           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     228           6 :   return &ECVs_[j][0];
+     229             : }
+     230             : 
+     231           6 : const double * ECVumbrellasFile::getPntrToDerECVs(unsigned j)
+     232             : {
+     233           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     234           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     235           6 :   return &derECVs_[j][0];
+     236             : }
+     237             : 
+     238           3 : std::vector<std::string> ECVumbrellasFile::getLambdas() const
+     239             : { //notice that sigmas are not considered!
+     240           3 :   std::vector<std::string> lambdas(totNumECVs_);
+     241           3 :   if(P0_contribution_==1)
+     242             :   {
+     243           2 :     std::ostringstream subs;
+     244           2 :     subs<<"P0";
+     245           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     246           2 :       subs<<"_P0";
+     247           2 :     lambdas[0]=subs.str();
+     248           2 :   }
+     249         666 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     250             :   {
+     251         663 :     const unsigned kk=k-P0_contribution_;
+     252         663 :     std::ostringstream subs;
+     253         663 :     subs<<centers_[0][kk];
+     254        1326 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     255         663 :       subs<<"_"<<centers_[j][kk];
+     256         663 :     lambdas[k]=subs.str();
+     257         663 :   }
+     258           3 :   return lambdas;
+     259           0 : }
+     260             : 
+     261           3 : void ECVumbrellasFile::initECVs()
+     262             : {
+     263           3 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     264           3 :   isReady_=true;
+     265           3 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     266           3 : }
+     267             : 
+     268           2 : void ECVumbrellasFile::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     269             : {
+     270             :   //this non-linear exansion never uses automatic initialization
+     271           2 :   initECVs();
+     272           2 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     273           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     274         888 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     275        1680 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     276           2 : }
+     277             : 
+     278           1 : void ECVumbrellasFile::initECVs_restart(const std::vector<std::string>& lambdas)
+     279             : {
+     280             :   std::size_t pos=0;
+     281           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     282           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     283           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     284           1 :   pos=lambdas[0].find("_",pos+1);
+     285           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     286             : 
+     287           1 :   std::vector<std::string> myLambdas=getLambdas();
+     288           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     289           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     290             : 
+     291           1 :   initECVs();
+     292           1 : }
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html new file mode 100644 index 0000000000..b2e39e098d --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_128ECVumbrellasLineRegisterMe976createERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe97C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func.html b/coverage/opes/ECVumbrellasLine.cpp.func.html new file mode 100644 index 0000000000..f39b2f22b8 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe976createERKNS_13ActionOptionsE8
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe97C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_128ECVumbrellasLineRegisterMe97D2Ev4168
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.gcov.html b/coverage/opes/ECVumbrellasLine.cpp.gcov.html new file mode 100644 index 0000000000..b1efe3f4d9 --- /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-05-27 13:05: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             : Typically, a SPACING greater than 1 can lead to faster convergence, by reducing the total number of umbrellas.
+      37             : The umbrellas can be multidimensional, but the CVs dimensions should be rescaled since a single SIGMA must be used.
+      38             : 
+      39             : The keyword BARRIER can be helpful to avoid breaking your system due to a too strong initial bias.
+      40             : If you think the placed umbrellas will not cover the whole unbiased probability distribution you should add it explicitly to the target, with the flag ADD_P0, for more robust convergence.
+      41             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      42             : 
+      43             : The flag LOWER_HALF_ONLY modifies the ECVs so that they are set to zero when \f$\mathbf{s}>\mathbf{s}_i\f$, as in \ref LOWER_WALLS.
+      44             : This can be useful e.g. when the CV used is the \ref ENERGY and one wants to sample a broad range of high energy values, similar to \ref ECV_MULTITHERMAL but with a flat energy distribution as target.
+      45             : By pushing only from below one can avoid too extreme forces that could crash the simulation.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : \plumedfile
+      50             : cv: DISTANCE ATOMS=1,2
+      51             : ecv: ECV_UMBRELLAS_LINE ARG=cv CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5 SPACING=1.5
+      52             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      53             : \endplumedfile
+      54             : 
+      55             : It is also possible to combine different ECV_UMBRELLAS_LINE to build a grid of CV values that will be sampled.
+      56             : For example the following code will sample a whole 2D region of cv1 and cv2.
+      57             : 
+      58             : \plumedfile
+      59             : cv1: DISTANCE ATOMS=1,2
+      60             : ecv2: ECV_UMBRELLAS_LINE ARG=cv1 CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      61             : 
+      62             : cv2: DISTANCE ATOMS=3,4
+      63             : ecv1: ECV_UMBRELLAS_LINE ARG=cv2 CV_MIN=13.8 CV_MAX=21.4 SIGMA=4.3
+      64             : 
+      65             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500
+      66             : \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : class ECVumbrellasLine :
+      72             :   public ExpansionCVs
+      73             : {
+      74             : private:
+      75             :   double barrier_;
+      76             :   unsigned P0_contribution_;
+      77             :   bool lower_only_;
+      78             : 
+      79             :   std::vector< std::vector<double> > centers_;
+      80             :   double sigma_;
+      81             : 
+      82             :   std::vector< std::vector<double> > ECVs_;
+      83             :   std::vector< std::vector<double> > derECVs_;
+      84             :   void initECVs();
+      85             : 
+      86             : public:
+      87             :   explicit ECVumbrellasLine(const ActionOptions&);
+      88             :   static void registerKeywords(Keywords& keys);
+      89             :   void calculateECVs(const double *) override;
+      90             :   const double * getPntrToECVs(unsigned) override;
+      91             :   const double * getPntrToDerECVs(unsigned) override;
+      92             :   std::vector<std::string> getLambdas() const override;
+      93             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      94             :   void initECVs_restart(const std::vector<std::string>&) override;
+      95             : };
+      96             : 
+      97       12520 : PLUMED_REGISTER_ACTION(ECVumbrellasLine,"ECV_UMBRELLAS_LINE")
+      98             : 
+      99          10 : void ECVumbrellasLine::registerKeywords(Keywords& keys)
+     100             : {
+     101          10 :   ExpansionCVs::registerKeywords(keys);
+     102          10 :   keys.use("ARG");
+     103          20 :   keys.add("compulsory","CV_MIN","the minimum of the CV range to be explored");
+     104          20 :   keys.add("compulsory","CV_MAX","the maximum of the CV range to be explored");
+     105          20 :   keys.add("compulsory","SIGMA","sigma of the umbrella Gaussians");
+     106          20 :   keys.add("compulsory","SPACING","1","the distance between umbrellas, in units of SIGMA");
+     107          20 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     108          20 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     109          20 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     110          10 : }
+     111             : 
+     112           8 : ECVumbrellasLine::ECVumbrellasLine(const ActionOptions&ao):
+     113             :   Action(ao),
+     114           8 :   ExpansionCVs(ao)
+     115             : {
+     116             : //set P0_contribution_
+     117           8 :   bool add_P0=false;
+     118           8 :   parseFlag("ADD_P0",add_P0);
+     119           8 :   if(add_P0)
+     120           2 :     P0_contribution_=1;
+     121             :   else
+     122           6 :     P0_contribution_=0;
+     123             : 
+     124             : //set barrier_
+     125           8 :   barrier_=std::numeric_limits<double>::infinity();
+     126           8 :   parse("BARRIER",barrier_);
+     127           8 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     128             : 
+     129             : //set umbrellas
+     130          16 :   parse("SIGMA",sigma_);
+     131             :   std::vector<double> cv_min;
+     132             :   std::vector<double> cv_max;
+     133           8 :   parseVector("CV_MIN",cv_min);
+     134          16 :   parseVector("CV_MAX",cv_max);
+     135           8 :   plumed_massert(cv_min.size()==getNumberOfArguments(),"wrong number of CV_MINs");
+     136           8 :   plumed_massert(cv_max.size()==getNumberOfArguments(),"wrong number of CV_MAXs");
+     137             :   double spacing;
+     138           8 :   parse("SPACING",spacing);
+     139             :   double length=0;
+     140          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     141          10 :     length+=std::pow(cv_max[j]-cv_min[j],2);
+     142           8 :   length=std::sqrt(length);
+     143           8 :   unsigned sizeUmbrellas=1+std::round(length/(sigma_*spacing));
+     144           8 :   centers_.resize(getNumberOfArguments()); //centers_[cv][umbrellas]
+     145             :   unsigned full_period=0;
+     146          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     147             :   {
+     148          10 :     centers_[j].resize(sizeUmbrellas);
+     149          10 :     if(sizeUmbrellas>1)
+     150         140 :       for(unsigned k=0; k<sizeUmbrellas; k++)
+     151         130 :         centers_[j][k]=cv_min[j]+k*(cv_max[j]-cv_min[j])/(sizeUmbrellas-1);
+     152             :     else
+     153           0 :       centers_[j][0]=(cv_min[j]+cv_max[j])/2.;
+     154          10 :     if(getPntrToArgument(j)->isPeriodic())
+     155             :     {
+     156             :       double min,max;
+     157             :       std::string min_str,max_str;
+     158          10 :       getPntrToArgument(j)->getDomain(min,max);
+     159          10 :       getPntrToArgument(j)->getDomain(min_str,max_str);
+     160          10 :       plumed_massert(cv_min[j]>=min,"ARG "+std::to_string(j)+": CV_MIN cannot be smaller than the periodic bound "+min_str);
+     161          10 :       plumed_massert(cv_max[j]<=max,"ARG "+std::to_string(j)+": CV_MAX cannot be greater than the periodic bound "+max_str);
+     162          10 :       if(cv_min[j]==min && cv_max[j]==max)
+     163           6 :         full_period++;
+     164             :     }
+     165             :   }
+     166           8 :   if(full_period==getNumberOfArguments() && sizeUmbrellas>1) //first and last are the same point
+     167             :   {
+     168           6 :     sizeUmbrellas--;
+     169          12 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     170           6 :       centers_[j].pop_back();
+     171             :   }
+     172             : 
+     173           8 :   checkRead();
+     174             : 
+     175             : //set ECVs stuff
+     176           8 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     177           8 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     178           8 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     179             : 
+     180             : //printing some info
+     181           8 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     182           8 :   log.printf("    with SIGMA = %g\n",sigma_);
+     183           8 :   log.printf("    and SPACING = %g\n",spacing);
+     184           8 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     185           2 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     186           8 :   if(P0_contribution_==1)
+     187           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     188           8 :   if(lower_only_)
+     189           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     190           8 : }
+     191             : 
+     192         433 : void ECVumbrellasLine::calculateECVs(const double * cv)
+     193             : {
+     194         433 :   if(lower_only_)
+     195             :   {
+     196         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     197             :     {
+     198        2040 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     199             :       {
+     200        1938 :         const unsigned kk=k-P0_contribution_;
+     201        1938 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     202        1938 :         if(dist_jk>=0)
+     203             :         {
+     204         933 :           ECVs_[j][k]=0;
+     205         933 :           derECVs_[j][k]=0;
+     206             :         }
+     207             :         else
+     208             :         {
+     209        1005 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     210        1005 :           derECVs_[j][k]=dist_jk/sigma_;
+     211             :         }
+     212             :       }
+     213             :     }
+     214             :   }
+     215             :   else
+     216             :   {
+     217         804 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218             :     {
+     219        4678 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     220             :       {
+     221        4256 :         const unsigned kk=k-P0_contribution_;
+     222        4256 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     223        4256 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     224        4256 :         derECVs_[j][k]=dist_jk/sigma_;
+     225             :       }
+     226             :     }
+     227             :   }
+     228         433 : }
+     229             : 
+     230          10 : const double * ECVumbrellasLine::getPntrToECVs(unsigned j)
+     231             : {
+     232          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     233          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     234          10 :   return &ECVs_[j][0];
+     235             : }
+     236             : 
+     237          10 : const double * ECVumbrellasLine::getPntrToDerECVs(unsigned j)
+     238             : {
+     239          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     240          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     241          10 :   return &derECVs_[j][0];
+     242             : }
+     243             : 
+     244           8 : std::vector<std::string> ECVumbrellasLine::getLambdas() const
+     245             : {
+     246           8 :   std::vector<std::string> lambdas(totNumECVs_);
+     247           8 :   if(P0_contribution_==1)
+     248             :   {
+     249           2 :     std::ostringstream subs;
+     250           2 :     subs<<"P0";
+     251           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     252           2 :       subs<<"_P0";
+     253           2 :     lambdas[0]=subs.str();
+     254           2 :   }
+     255          94 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     256             :   {
+     257          86 :     const unsigned kk=k-P0_contribution_;
+     258          86 :     std::ostringstream subs;
+     259          86 :     subs<<centers_[0][kk];
+     260         124 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     261          38 :       subs<<"_"<<centers_[j][kk];
+     262          86 :     lambdas[k]=subs.str();
+     263          86 :   }
+     264           8 :   return lambdas;
+     265           0 : }
+     266             : 
+     267           8 : void ECVumbrellasLine::initECVs()
+     268             : {
+     269           8 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     270           8 :   isReady_=true;
+     271           8 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     272           8 : }
+     273             : 
+     274           5 : void ECVumbrellasLine::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     275             : {
+     276             :   //this non-linear exansion never uses automatic initialization
+     277           5 :   initECVs();
+     278           5 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     279          11 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     280          76 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     281         123 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     282           5 : }
+     283             : 
+     284           3 : void ECVumbrellasLine::initECVs_restart(const std::vector<std::string>& lambdas)
+     285             : {
+     286             :   std::size_t pos=0;
+     287           4 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     288           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     289           3 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     290           3 :   pos=lambdas[0].find("_",pos+1);
+     291           3 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     292             : 
+     293           3 :   std::vector<std::string> myLambdas=getLambdas();
+     294           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     295           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     296             : 
+     297           3 :   initECVs();
+     298           3 : }
+     299             : 
+     300             : }
+     301             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func-sort-c.html b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html new file mode 100644 index 0000000000..be7e5f1374 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE49
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func.html b/coverage/opes/ExpansionCVs.cpp.func.html new file mode 100644 index 0000000000..267d5aec5a --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12ExpansionCVsC2ERKNS_13ActionOptionsE37
_ZNK4PLMD4opes12ExpansionCVs10getIndex_kEv26
_ZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD4opes12ExpansionCVs8getStepsEddjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd24
_ZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_9
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.gcov.html b/coverage/opes/ExpansionCVs.cpp.gcov.html new file mode 100644 index 0000000000..40e0926281 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.gcov.html @@ -0,0 +1,309 @@ + + + + + + + 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-05-27 13:05: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          49 : void ExpansionCVs::registerKeywords(Keywords& keys)
+      29             : {
+      30          49 :   Action::registerKeywords(keys);
+      31          49 :   ActionWithValue::registerKeywords(keys);
+      32          49 :   ActionWithArguments::registerKeywords(keys);
+      33          49 :   ActionWithValue::useCustomisableComponents(keys);
+      34          98 :   keys.add("compulsory","TEMP","-1","temperature. If not specified tries to get it from MD engine");
+      35          49 : }
+      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         218 :       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.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func-sort-c.html b/coverage/opes/ExpansionCVs.h.func-sort-c.html new file mode 100644 index 0000000000..3ca22bd2d4 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func.html b/coverage/opes/ExpansionCVs.h.func.html new file mode 100644 index 0000000000..f63438b816 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.gcov.html b/coverage/opes/ExpansionCVs.h.gcov.html new file mode 100644 index 0000000000..237c3795f4 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func-sort-c.html b/coverage/opes/OPESexpanded.cpp.func-sort-c.html new file mode 100644 index 0000000000..07fc71e1e2 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-05-27 13:05: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_125OPESexpandedRegisterMe1796createERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe179C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe179D2Ev4168
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func.html b/coverage/opes/OPESexpanded.cpp.func.html new file mode 100644 index 0000000000..e0ea922eb2 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-05-27 13:05:14Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe1796createERKNS_13ActionOptionsE30
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe179C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_125OPESexpandedRegisterMe179D2Ev4168
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.gcov.html b/coverage/opes/OPESexpanded.cpp.gcov.html new file mode 100644 index 0000000000..1e6b2f861a --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.gcov.html @@ -0,0 +1,1020 @@ + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-05-27 13:05: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 with expanded ensembles for the target distribution.
+      35             : 
+      36             : This method is similar to the OPES method (\ref OPES "OPES") with expanded ensembles target distribution (replica-exchange-like) \cite Invernizzi2020unified.
+      37             : 
+      38             : An expanded ensemble is obtained by summing a set of ensembles at slightly different termodynamic conditions, or with slightly different Hamiltonians.
+      39             : Such ensembles can be sampled via methods like replica exchange, or this \ref OPES_EXPANDED bias action.
+      40             : A typical example is a multicanonical simulation, in which a whole range of temperatures is sampled instead of a single one.
+      41             : 
+      42             : In oreder to define an expanded target ensemble we use \ref EXPANSION_CV "expansion collective variables" (ECVs), \f$\Delta u_\lambda(\mathbf{x})\f$.
+      43             : The bias at step \f$n\f$ is
+      44             : \f[
+      45             :   V_n(\mathbf{x})=-\frac{1}{\beta}\log \left(\frac{1}{N_{\{\lambda\}}}\sum_\lambda e^{-\Delta u_\lambda(\mathbf{x})+\beta\Delta F_n(\lambda)}\right)\, .
+      46             : \f]
+      47             : See Ref.\cite Invernizzi2020unified for more details on the method.
+      48             : 
+      49             : Notice that the estimates in the DELTAFS file are expressed in energy units, and should be multiplied by \f$\beta\f$ to be dimensionless as in Ref.\cite Invernizzi2020unified.
+      50             : The DELTAFS file also contains an estimate of \f$c(t)=\frac{1}{\beta} \log \langle e^{\beta V}\rangle\f$.
+      51             : Similarly to \ref OPES_METAD, it is printed only for reference, since \f$c(t)\f$ reaches a fixed value as the bias converges, and should NOT be used for reweighting.
+      52             : Its value is also needed for restarting a simulation.
+      53             : 
+      54             : You can store the instantaneous \f$\Delta F_n(\lambda)\f$ estimates also in a more readable format using STATE_WFILE and STATE_WSTRIDE.
+      55             : Restart can be done either from a DELTAFS file or from a STATE_RFILE, it is equivalent.
+      56             : 
+      57             : Contrary to \ref OPES_METAD, \ref OPES_EXPANDED does not use kernel density estimation.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : \plumedfile
+      62             : # simulate multiple temperatures, as in parallel tempering
+      63             : ene: ENERGY
+      64             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=1000
+      65             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      66             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,opes.bias
+      67             : \endplumedfile
+      68             : 
+      69             : You can easily combine multiple ECVs.
+      70             : The \ref OPES_EXPANDED bias will create a multidimensional target grid to sample all the combinations.
+      71             : 
+      72             : \plumedfile
+      73             : # simulate multiple temperatures while biasing a CV
+      74             : ene: ENERGY
+      75             : dst: DISTANCE ATOMS=1,2
+      76             : 
+      77             : ecv1: ECV_MULTITHERMAL ARG=ene TEMP_SET_ALL=200,300,500,1000
+      78             : ecv2: ECV_UMBRELLAS_LINE ARG=dst CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      79             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500 OBSERVATION_STEPS=1
+      80             : 
+      81             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,dst,opes.bias
+      82             : \endplumedfile
+      83             : 
+      84             : If an ECV is based on more than one CV you must provide all the output component, in the proper order.
+      85             : You can use \ref Regex for that, like in the following example.
+      86             : 
+      87             : \plumedfile
+      88             : # simulate multiple temperatures and pressures while biasing a two-CVs linear path
+      89             : ene: ENERGY
+      90             : vol: VOLUME
+      91             : ecv_mtp: ECV_MULTITHERMAL_MULTIBARIC ...
+      92             :   ARG=ene,vol
+      93             :   TEMP=300
+      94             :   TEMP_MIN=200
+      95             :   TEMP_MAX=800
+      96             :   PRESSURE=0.06022140857*1000 #1 kbar
+      97             :   PRESSURE_MIN=0
+      98             :   PRESSURE_MAX=0.06022140857*2000 #2 kbar
+      99             : ...
+     100             : 
+     101             : cv1: DISTANCE ATOMS=1,2
+     102             : cv2: DISTANCE ATOMS=3,4
+     103             : ecv_umb: ECV_UMBRELLAS_LINE ARG=cv1,cv2 TEMP=300 CV_MIN=0.1,0.1 CV_MAX=1.5,1.5 SIGMA=0.2 BARRIER=70
+     104             : 
+     105             : opes: OPES_EXPANDED ARG=(ecv_.*) PACE=500 WALKERS_MPI PRINT_STRIDE=1000
+     106             : 
+     107             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,vol,cv1,cv2,opes.bias
+     108             : \endplumedfile
+     109             : 
+     110             : 
+     111             : */
+     112             : //+ENDPLUMEDOC
+     113             : 
+     114             : class OPESexpanded : public bias::Bias {
+     115             : 
+     116             : private:
+     117             :   bool isFirstStep_;
+     118             :   unsigned NumOMP_;
+     119             :   unsigned NumParallel_;
+     120             :   unsigned rank_;
+     121             :   unsigned NumWalkers_;
+     122             :   unsigned walker_rank_;
+     123             :   unsigned long long counter_;
+     124             :   std::size_t ncv_;
+     125             : 
+     126             :   std::vector<const double *> ECVs_;
+     127             :   std::vector<const double *> derECVs_;
+     128             :   std::vector<opes::ExpansionCVs*> pntrToECVsClass_;
+     129             :   std::vector< std::vector<unsigned> > index_k_;
+     130             : // A note on indexes usage:
+     131             : //  j -> underlying CVs
+     132             : //  i -> DeltaFs
+     133             : //  k -> single ECVs, which might not be trivially numbered
+     134             : //  l -> groups of ECVs, pntrToECVsClass
+     135             : //  h -> subgroups of ECVs, arguments in ECVsClass
+     136             : //  w -> walkers
+     137             : 
+     138             :   double kbt_;
+     139             :   unsigned stride_;
+     140             :   unsigned deltaF_size_; //different from deltaF_.size() if NumParallel_>1
+     141             :   std::vector<double> deltaF_;
+     142             :   std::vector<double> diff_;
+     143             :   double rct_;
+     144             : 
+     145             :   std::vector<double> all_deltaF_;
+     146             :   std::vector<int> all_size_;
+     147             :   std::vector<int> disp_;
+     148             : 
+     149             :   unsigned obs_steps_;
+     150             :   std::vector<double> obs_cvs_;
+     151             : 
+     152             :   bool calc_work_;
+     153             :   double work_;
+     154             : 
+     155             :   unsigned print_stride_;
+     156             :   OFile deltaFsOfile_;
+     157             :   std::vector<std::string> deltaF_name_;
+     158             : 
+     159             :   OFile stateOfile_;
+     160             :   int wStateStride_;
+     161             :   bool storeOldStates_;
+     162             : 
+     163             :   void init_pntrToECVsClass();
+     164             :   void init_linkECVs();
+     165             :   void init_fromObs();
+     166             : 
+     167             :   void printDeltaF();
+     168             :   void dumpStateToFile();
+     169             :   void updateDeltaF(double);
+     170             :   double getExpansion(const unsigned) const;
+     171             : 
+     172             : public:
+     173             :   explicit OPESexpanded(const ActionOptions&);
+     174             :   void calculate() override;
+     175             :   void update() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179       12564 : PLUMED_REGISTER_ACTION(OPESexpanded,"OPES_EXPANDED")
+     180             : 
+     181          32 : void OPESexpanded::registerKeywords(Keywords& keys)
+     182             : {
+     183          32 :   Bias::registerKeywords(keys);
+     184          32 :   keys.remove("ARG");
+     185          64 :   keys.add("compulsory","ARG","the label of the ECVs that define the expansion. You can use an * to make sure all the output components of the ECVs are used, as in the examples above");
+     186          64 :   keys.add("compulsory","PACE","how often the bias is updated");
+     187          64 :   keys.add("compulsory","OBSERVATION_STEPS","100","number of unbiased initial PACE steps to collect statistics for initialization");
+     188             : //DeltaFs and state files
+     189          64 :   keys.add("compulsory","FILE","DELTAFS","a file with the estimate of the relative Delta F for each component of the target and of the global c(t)");
+     190          64 :   keys.add("compulsory","PRINT_STRIDE","100","stride for printing to DELTAFS file, in units of PACE");
+     191          64 :   keys.add("optional","FMT","specify format for DELTAFS file");
+     192          64 :   keys.add("optional","STATE_RFILE","read from this file the Delta F estimates and all the info needed to RESTART the simulation");
+     193          64 :   keys.add("optional","STATE_WFILE","write to this file the Delta F estimates and all the info needed to RESTART the simulation");
+     194          64 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     195          64 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     196             : //miscellaneous
+     197          64 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     198          64 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     199          64 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     200          32 :   keys.use("RESTART");
+     201          32 :   keys.use("UPDATE_FROM");
+     202          32 :   keys.use("UPDATE_UNTIL");
+     203             : 
+     204             : //output components
+     205          32 :   componentsAreNotOptional(keys);
+     206          64 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     207          32 : }
+     208             : 
+     209          30 : OPESexpanded::OPESexpanded(const ActionOptions&ao)
+     210             :   : PLUMED_BIAS_INIT(ao)
+     211          30 :   , isFirstStep_(true)
+     212          30 :   , counter_(0)
+     213          30 :   , ncv_(getNumberOfArguments())
+     214          30 :   , deltaF_size_(0)
+     215          30 :   , rct_(0)
+     216          30 :   , work_(0)
+     217             : {
+     218             : //set pace
+     219          30 :   parse("PACE",stride_);
+     220          30 :   parse("OBSERVATION_STEPS",obs_steps_);
+     221          30 :   plumed_massert(obs_steps_!=0,"minimum is OBSERVATION_STEPS=1");
+     222          30 :   obs_cvs_.resize(obs_steps_*ncv_);
+     223             : 
+     224             : //deltaFs file
+     225             :   std::string deltaFsFileName;
+     226          30 :   parse("FILE",deltaFsFileName);
+     227          60 :   parse("PRINT_STRIDE",print_stride_);
+     228             :   std::string fmt;
+     229          60 :   parse("FMT",fmt);
+     230             : //output checkpoint of current state
+     231             :   std::string restartFileName;
+     232          60 :   parse("STATE_RFILE",restartFileName);
+     233             :   std::string stateFileName;
+     234          30 :   parse("STATE_WFILE",stateFileName);
+     235          30 :   wStateStride_=0;
+     236          30 :   parse("STATE_WSTRIDE",wStateStride_);
+     237          30 :   storeOldStates_=false;
+     238          30 :   parseFlag("STORE_STATES",storeOldStates_);
+     239          30 :   if(wStateStride_!=0 || storeOldStates_)
+     240           5 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     241          30 :   if(wStateStride_>0)
+     242           5 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus should be a multiple of PACE");
+     243          30 :   if(stateFileName.length()>0 && wStateStride_==0)
+     244           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     245             : 
+     246             : //work flag
+     247          30 :   parseFlag("CALC_WORK",calc_work_);
+     248             : 
+     249             : //multiple walkers //external MW for cp2k not supported, but anyway cp2k cannot put bias on energy!
+     250          30 :   bool walkers_mpi=false;
+     251          30 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     252          30 :   if(walkers_mpi)
+     253             :   {
+     254             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     255           4 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     256           4 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     257             : 
+     258           4 :     if(comm.Get_rank()==0) //multi_sim_comm works on first rank only
+     259             :     {
+     260           4 :       NumWalkers_=multi_sim_comm.Get_size();
+     261           4 :       walker_rank_=multi_sim_comm.Get_rank();
+     262             :     }
+     263           4 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     264           4 :     comm.Bcast(walker_rank_,0);
+     265             :   }
+     266             :   else
+     267             :   {
+     268          26 :     NumWalkers_=1;
+     269          26 :     walker_rank_=0;
+     270             :   }
+     271             : 
+     272             : //parallelization stuff
+     273          30 :   NumOMP_=OpenMP::getNumThreads();
+     274          30 :   NumParallel_=comm.Get_size();
+     275          30 :   rank_=comm.Get_rank();
+     276          30 :   bool serial=false;
+     277          30 :   parseFlag("SERIAL",serial);
+     278          30 :   if(serial)
+     279             :   {
+     280           5 :     NumOMP_=1;
+     281           5 :     NumParallel_=1;
+     282           5 :     rank_=0;
+     283             :   }
+     284             : 
+     285          30 :   checkRead();
+     286             : 
+     287             : //check ECVs and link them
+     288          30 :   init_pntrToECVsClass();
+     289             : //set kbt_
+     290          30 :   kbt_=pntrToECVsClass_[0]->getKbT();
+     291          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     292          37 :     plumed_massert(std::abs(kbt_-pntrToECVsClass_[l]->getKbT())<1e-4,"must set same TEMP for each ECV");
+     293             : 
+     294             : //restart if needed
+     295          30 :   if(getRestart())
+     296             :   {
+     297             :     bool stateRestart=true;
+     298          10 :     if(restartFileName.length()==0)
+     299             :     {
+     300             :       stateRestart=false;
+     301             :       restartFileName=deltaFsFileName;
+     302             :     }
+     303          10 :     IFile ifile;
+     304          10 :     ifile.link(*this);
+     305          10 :     if(ifile.FileExist(restartFileName))
+     306             :     {
+     307          10 :       log.printf("  RESTART - make sure all ECVs used are the same as before\n");
+     308          10 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     309          10 :       ifile.open(restartFileName);
+     310          10 :       if(stateRestart) //get all info
+     311             :       {
+     312           2 :         log.printf("    it should be a STATE file (not a DELTAFS file)\n");
+     313             :         double time; //not used
+     314           2 :         ifile.scanField("time",time);
+     315           2 :         ifile.scanField("counter",counter_);
+     316           4 :         ifile.scanField("rct",rct_);
+     317             :         std::string tmp_lambda;
+     318          66 :         while(ifile.scanField(getPntrToArgument(0)->getName(),tmp_lambda))
+     319             :         {
+     320          64 :           std::string subs="DeltaF_"+tmp_lambda;
+     321         128 :           for(unsigned jj=1; jj<ncv_; jj++)
+     322             :           {
+     323             :             tmp_lambda.clear();
+     324          64 :             ifile.scanField(getPntrToArgument(jj)->getName(),tmp_lambda);
+     325         128 :             subs+="_"+tmp_lambda;
+     326             :           }
+     327          64 :           deltaF_name_.push_back(subs);
+     328             :           double tmp_deltaF;
+     329          64 :           ifile.scanField("DeltaF",tmp_deltaF);
+     330          64 :           deltaF_.push_back(tmp_deltaF);
+     331          64 :           ifile.scanField();
+     332             :           tmp_lambda.clear();
+     333             :         }
+     334           2 :         log.printf("  successfully read %lu DeltaF values\n",deltaF_name_.size());
+     335           2 :         if(NumParallel_>1)
+     336           2 :           all_deltaF_=deltaF_;
+     337             :       }
+     338             :       else //get just deltaFs names
+     339             :       {
+     340           8 :         ifile.scanFieldList(deltaF_name_);
+     341           8 :         plumed_massert(deltaF_name_.size()>=4,"RESTART - fewer than expected FIELDS found in '"+deltaFsFileName+"' file");
+     342           8 :         plumed_massert(deltaF_name_[deltaF_name_.size()-1]=="print_stride","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     343           8 :         plumed_massert(deltaF_name_[0]=="time","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     344           8 :         plumed_massert(deltaF_name_[1]=="rct","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     345             :         deltaF_name_.pop_back();
+     346             :         deltaF_name_.erase(deltaF_name_.begin(),deltaF_name_.begin()+2);
+     347             :         std::size_t pos=5; //each name starts with "DeltaF"
+     348          22 :         for(unsigned j=0; j<ncv_; j++)
+     349          14 :           pos=deltaF_name_[0].find("_",pos+1); //checking only first one, hopefully is enough
+     350           8 :         plumed_massert(pos<deltaF_name_[0].length(),"RESTART - fewer '_' than expected in DeltaF fields: did you remove any CV?");
+     351           8 :         pos=deltaF_name_[0].find("_",pos+1);
+     352           8 :         plumed_massert(pos>deltaF_name_[0].length(),"RESTART - more '_' than expected in DeltaF fields: did you add new CV?");
+     353             :       }
+     354             :       //get lambdas, init ECVs and Link them
+     355          10 :       deltaF_size_=deltaF_name_.size();
+     356         525 :       auto getLambdaName=[](const std::string& name,const unsigned start,const unsigned dim)
+     357             :       {
+     358             :         std::size_t pos_start=5; //each name starts with "DeltaF"
+     359        1068 :         for(unsigned j=0; j<=start; j++)
+     360         543 :           pos_start=name.find("_",pos_start+1);
+     361             :         std::size_t pos_end=pos_start;
+     362        1527 :         for(unsigned j=0; j<dim; j++)
+     363        1002 :           pos_end=name.find("_",pos_end+1);
+     364         525 :         pos_start++; //do not include heading "_"
+     365         525 :         return name.substr(pos_start,pos_end-pos_start);
+     366             :       };
+     367          10 :       unsigned index_j=ncv_;
+     368             :       unsigned sizeSkip=1;
+     369          22 :       for(int l=pntrToECVsClass_.size()-1; l>=0; l--)
+     370             :       {
+     371          12 :         const unsigned dim_l=pntrToECVsClass_[l]->getNumberOfArguments();
+     372          12 :         index_j-=dim_l;
+     373          12 :         std::vector<std::string> lambdas_l(1);
+     374          12 :         lambdas_l[0]=getLambdaName(deltaF_name_[0],index_j,dim_l);
+     375         523 :         for(unsigned i=sizeSkip; i<deltaF_size_; i+=sizeSkip)
+     376             :         {
+     377         513 :           std::string tmp_lambda=getLambdaName(deltaF_name_[i],index_j,dim_l);
+     378         513 :           if(tmp_lambda==lambdas_l[0])
+     379             :             break;
+     380         511 :           lambdas_l.push_back(tmp_lambda);
+     381             :         }
+     382          12 :         pntrToECVsClass_[l]->initECVs_restart(lambdas_l);
+     383          12 :         sizeSkip*=lambdas_l.size();
+     384          12 :       }
+     385          10 :       plumed_massert(sizeSkip==deltaF_size_,"RESTART - this should not happen");
+     386          10 :       init_linkECVs(); //link ECVs and initializes index_k_
+     387          10 :       log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     388          10 :       obs_steps_=0; //avoid initializing again
+     389          10 :       if(stateRestart)
+     390             :       {
+     391           2 :         if(NumParallel_>1)
+     392             :         {
+     393           2 :           const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     394             :           unsigned iter=0;
+     395          34 :           for(unsigned i=start; i<start+deltaF_.size(); i++)
+     396          32 :             deltaF_[iter++]=all_deltaF_[i];
+     397             :         }
+     398             :       }
+     399             :       else //read each step
+     400             :       {
+     401           8 :         counter_=1;
+     402             :         unsigned count_lines=0;
+     403           8 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     404             :         double time;
+     405          48 :         while(ifile.scanField("time",time)) //only number of lines and last line is important
+     406             :         {
+     407             :           unsigned restart_stride;
+     408          16 :           ifile.scanField("print_stride",restart_stride);
+     409          16 :           ifile.scanField("rct",rct_);
+     410          16 :           if(NumParallel_==1)
+     411             :           {
+     412        1014 :             for(unsigned i=0; i<deltaF_size_; i++)
+     413         998 :               ifile.scanField(deltaF_name_[i],deltaF_[i]);
+     414             :           }
+     415             :           else
+     416             :           {
+     417           0 :             const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     418             :             unsigned iter=0;
+     419           0 :             for(unsigned i=start; i<start+deltaF_.size(); i++)
+     420           0 :               ifile.scanField(deltaF_name_[i],deltaF_[iter++]);
+     421             :           }
+     422          16 :           ifile.scanField();
+     423          16 :           if(count_lines>0)
+     424           8 :             counter_+=restart_stride;
+     425          16 :           count_lines++;
+     426             :         }
+     427           8 :         counter_*=NumWalkers_;
+     428           8 :         log.printf("  successfully read %u lines, up to t=%g\n",count_lines,time);
+     429             :       }
+     430          10 :       ifile.reset(false);
+     431          10 :       ifile.close();
+     432             :     }
+     433             :     else //same behaviour as METAD
+     434           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     435          10 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     436             :     {
+     437           2 :       std::vector<unsigned long long> all_counter(NumWalkers_);
+     438           2 :       if(comm.Get_rank()==0)
+     439           2 :         multi_sim_comm.Allgather(counter_,all_counter);
+     440           2 :       comm.Bcast(all_counter,0);
+     441             :       bool same_number_of_steps=true;
+     442           4 :       for(unsigned w=1; w<NumWalkers_; w++)
+     443           2 :         if(all_counter[0]!=all_counter[w])
+     444             :           same_number_of_steps=false;
+     445           2 :       plumed_massert(same_number_of_steps,"RESTART - not all walkers are reading the same file!");
+     446             :     }
+     447          10 :   }
+     448          20 :   else if(restartFileName.length()>0)
+     449           0 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     450             : 
+     451             : //sync all walkers to avoid opening files before reding is over (see also METAD)
+     452          30 :   comm.Barrier();
+     453          30 :   if(comm.Get_rank()==0 && walkers_mpi)
+     454           4 :     multi_sim_comm.Barrier();
+     455             : 
+     456             : //setup DeltaFs file
+     457          30 :   deltaFsOfile_.link(*this);
+     458          30 :   if(NumWalkers_>1)
+     459             :   {
+     460           4 :     if(walker_rank_>0)
+     461             :       deltaFsFileName="/dev/null"; //only first walker writes on file
+     462           8 :     deltaFsOfile_.enforceSuffix("");
+     463             :   }
+     464          30 :   deltaFsOfile_.open(deltaFsFileName);
+     465          30 :   if(fmt.length()>0)
+     466          60 :     deltaFsOfile_.fmtField(" "+fmt);
+     467             :   deltaFsOfile_.setHeavyFlush(); //do I need it?
+     468          30 :   deltaFsOfile_.addConstantField("print_stride");
+     469          30 :   deltaFsOfile_.printField("print_stride",print_stride_);
+     470             : 
+     471             : //open file for storing state
+     472          30 :   if(wStateStride_!=0)
+     473             :   {
+     474           6 :     stateOfile_.link(*this);
+     475           6 :     if(NumWalkers_>1)
+     476             :     {
+     477           0 :       if(walker_rank_>0)
+     478             :         stateFileName="/dev/null"; //only first walker writes on file
+     479           0 :       stateOfile_.enforceSuffix("");
+     480             :     }
+     481           6 :     stateOfile_.open(stateFileName);
+     482           6 :     if(fmt.length()>0)
+     483          12 :       stateOfile_.fmtField(" "+fmt);
+     484             :   }
+     485             : 
+     486             : //add output components
+     487          30 :   if(calc_work_)
+     488             :   {
+     489           6 :     addComponent("work");
+     490          12 :     componentIsNotPeriodic("work");
+     491             :   }
+     492             : 
+     493             : //printing some info
+     494          30 :   log.printf("  updating the bias with PACE = %u\n",stride_);
+     495          30 :   log.printf("  initial unbiased OBSERVATION_STEPS = %u (in units of PACE)\n",obs_steps_);
+     496          30 :   if(wStateStride_>0)
+     497           5 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     498          30 :   if(wStateStride_==-1)
+     499           1 :     log.printf("  state checkpoints are written on file '%s' only on CPT events (or never if MD code does define them!)\n",stateFileName.c_str());
+     500          30 :   if(walkers_mpi)
+     501           4 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     502          30 :   if(NumWalkers_>1)
+     503             :   {
+     504           4 :     log.printf("  using multiple walkers\n");
+     505           4 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     506           4 :     log.printf("    walker rank: %u\n",walker_rank_);
+     507             :   }
+     508          30 :   int mw_warning=0;
+     509          30 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     510           0 :     mw_warning=1;
+     511          30 :   comm.Bcast(mw_warning,0);
+     512          30 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     513           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     514          30 :   if(NumParallel_>1)
+     515           2 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     516          30 :   if(NumOMP_>1)
+     517          25 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     518          30 :   if(serial)
+     519           5 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     520          30 :   log.printf("  Bibliography: ");
+     521          60 :   log<<plumed.cite("M. Invernizzi, P.M. Piaggi, and M. Parrinello, Phys. Rev. X 10, 041034 (2020)");
+     522          30 :   log.printf("\n");
+     523          30 : }
+     524             : 
+     525        1490 : void OPESexpanded::calculate()
+     526             : {
+     527        1490 :   if(deltaF_size_==0) //no bias before initialization
+     528         325 :     return;
+     529             : 
+     530             : //get diffMax, to avoid over/underflow
+     531        1165 :   double diffMax=-std::numeric_limits<double>::max();
+     532        1165 :   #pragma omp parallel num_threads(NumOMP_)
+     533             :   {
+     534             :     #pragma omp for reduction(max:diffMax)
+     535             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     536             :     {
+     537             :       diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     538             :       if(diff_[i]>diffMax)
+     539             :         diffMax=diff_[i];
+     540             :     }
+     541             :   }
+     542        1165 :   if(NumParallel_>1)
+     543         102 :     comm.Max(diffMax);
+     544             : 
+     545             : //calculate the bias and the forces
+     546        1165 :   double sum=0;
+     547        1165 :   std::vector<double> der_sum_cv(ncv_,0);
+     548        1165 :   if(NumOMP_==1)
+     549             :   {
+     550        2730 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     551             :     {
+     552        2520 :       double add_i=std::exp(diff_[i]-diffMax);
+     553        2520 :       sum+=add_i;
+     554             :       //set derivatives
+     555        6960 :       for(unsigned j=0; j<ncv_; j++)
+     556        4440 :         der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     557             :     }
+     558             :   }
+     559             :   else
+     560             :   {
+     561         955 :     #pragma omp parallel num_threads(NumOMP_)
+     562             :     {
+     563             :       std::vector<double> omp_der_sum_cv(ncv_,0);
+     564             :       #pragma omp for reduction(+:sum) nowait
+     565             :       for(unsigned i=0; i<deltaF_.size(); i++)
+     566             :       {
+     567             :         double add_i=std::exp(diff_[i]-diffMax);
+     568             :         sum+=add_i;
+     569             :         //set derivatives
+     570             :         for(unsigned j=0; j<ncv_; j++)
+     571             :           omp_der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     572             :       }
+     573             :       #pragma omp critical
+     574             :       for(unsigned j=0; j<ncv_; j++)
+     575             :         der_sum_cv[j]+=omp_der_sum_cv[j];
+     576             :     }
+     577             :   }
+     578        1165 :   if(NumParallel_>1)
+     579             :   { //each MPI process has part of the full deltaF_ vector, so must Sum
+     580         102 :     comm.Sum(sum);
+     581         102 :     comm.Sum(der_sum_cv);
+     582             :   }
+     583             : 
+     584             : //set bias and forces
+     585        1165 :   const double bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     586             :   setBias(bias);
+     587        3163 :   for(unsigned j=0; j<ncv_; j++)
+     588        1998 :     setOutputForce(j,kbt_*der_sum_cv[j]/sum);
+     589             : }
+     590             : 
+     591        1490 : void OPESexpanded::update()
+     592             : {
+     593        1490 :   if(isFirstStep_) //skip very first step, as in METAD
+     594             :   {
+     595          30 :     isFirstStep_=false;
+     596          30 :     if(obs_steps_!=1) //if obs_steps_==1 go on with initialization
+     597             :       return;
+     598             :   }
+     599        1464 :   if(getStep()%stride_==0)
+     600             :   {
+     601         739 :     if(obs_steps_>0)
+     602             :     {
+     603         463 :       for(unsigned j=0; j<ncv_; j++)
+     604         304 :         obs_cvs_[counter_*ncv_+j]=getArgument(j);
+     605         159 :       counter_++;
+     606         159 :       if(counter_==obs_steps_)
+     607             :       {
+     608          20 :         log.printf("\nAction %s\n",getName().c_str());
+     609          20 :         init_fromObs();
+     610          20 :         log.printf("Finished initialization\n\n");
+     611          20 :         counter_=NumWalkers_; //all preliminary observations count 1
+     612          20 :         obs_steps_=0; //no more observation
+     613             :       }
+     614         159 :       return;
+     615             :     }
+     616             : 
+     617             :     //update averages
+     618         580 :     const double current_bias=getOutputQuantity(0); //the first value is always the bias
+     619         580 :     if(NumWalkers_==1)
+     620         500 :       updateDeltaF(current_bias);
+     621             :     else
+     622             :     {
+     623          80 :       std::vector<double> cvs(ncv_);
+     624         240 :       for(unsigned j=0; j<ncv_; j++)
+     625         160 :         cvs[j]=getArgument(j);
+     626          80 :       std::vector<double> all_bias(NumWalkers_);
+     627          80 :       std::vector<double> all_cvs(NumWalkers_*ncv_);
+     628          80 :       if(comm.Get_rank()==0)
+     629             :       {
+     630          80 :         multi_sim_comm.Allgather(current_bias,all_bias);
+     631          80 :         multi_sim_comm.Allgather(cvs,all_cvs);
+     632             :       }
+     633          80 :       comm.Bcast(all_bias,0);
+     634          80 :       comm.Bcast(all_cvs,0);
+     635         240 :       for(unsigned w=0; w<NumWalkers_; w++)
+     636             :       {
+     637             :         //calculate ECVs
+     638         160 :         unsigned index_wj=w*ncv_;
+     639         380 :         for(unsigned k=0; k<pntrToECVsClass_.size(); k++)
+     640             :         {
+     641         220 :           pntrToECVsClass_[k]->calculateECVs(&all_cvs[index_wj]);
+     642         220 :           index_wj+=pntrToECVsClass_[k]->getNumberOfArguments();
+     643             :         }
+     644         160 :         updateDeltaF(all_bias[w]);
+     645             :       }
+     646             :     }
+     647             : 
+     648             :     //write DeltaFs to file
+     649         580 :     if((counter_/NumWalkers_-1)%print_stride_==0)
+     650          44 :       printDeltaF();
+     651             : 
+     652             :     //calculate work if requested
+     653         580 :     if(calc_work_)
+     654             :     { //some copy and paste from calculate()
+     655             :       //get diffMax, to avoid over/underflow
+     656         110 :       double diffMax=-std::numeric_limits<double>::max();
+     657         110 :       #pragma omp parallel num_threads(NumOMP_)
+     658             :       {
+     659             :         #pragma omp for reduction(max:diffMax)
+     660             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     661             :         {
+     662             :           diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     663             :           if(diff_[i]>diffMax)
+     664             :             diffMax=diff_[i];
+     665             :         }
+     666             :       }
+     667         110 :       if(NumParallel_>1)
+     668          50 :         comm.Max(diffMax);
+     669             :       //calculate the bias
+     670         110 :       double sum=0;
+     671         110 :       #pragma omp parallel num_threads(NumOMP_)
+     672             :       {
+     673             :         #pragma omp for reduction(+:sum) nowait
+     674             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     675             :           sum+=std::exp(diff_[i]-diffMax);
+     676             :       }
+     677         110 :       if(NumParallel_>1)
+     678          50 :         comm.Sum(sum);
+     679         110 :       const double new_bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     680             :       //accumulate work
+     681         110 :       work_+=new_bias-current_bias;
+     682         220 :       getPntrToComponent("work")->set(work_);
+     683             :     }
+     684             :   }
+     685             : 
+     686             : //dump state if requested
+     687        1305 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+     688          11 :     dumpStateToFile();
+     689             : }
+     690             : 
+     691          30 : void OPESexpanded::init_pntrToECVsClass()
+     692             : {
+     693          30 :   std::vector<opes::ExpansionCVs*> all_pntrToECVsClass=plumed.getActionSet().select<opes::ExpansionCVs*>();
+     694          30 :   plumed_massert(all_pntrToECVsClass.size()>0,"no Expansion CVs found");
+     695          67 :   for(unsigned j=0; j<ncv_; j++)
+     696             :   {
+     697          74 :     std::string error_notECV("all the ARGs of "+getName()+" must be Expansion Collective Variables (ECV)");
+     698          37 :     const unsigned dot_pos=getPntrToArgument(j)->getName().find(".");
+     699          37 :     plumed_massert(dot_pos<getPntrToArgument(j)->getName().size(),error_notECV+", thus contain a dot in the name");
+     700          37 :     unsigned foundECV_l=all_pntrToECVsClass.size();
+     701          44 :     for(unsigned l=0; l<all_pntrToECVsClass.size(); l++)
+     702             :     {
+     703          44 :       if(getPntrToArgument(j)->getName().substr(0,dot_pos)==all_pntrToECVsClass[l]->getLabel())
+     704             :       {
+     705             :         foundECV_l=l;
+     706          37 :         pntrToECVsClass_.push_back(all_pntrToECVsClass[l]);
+     707          37 :         std::string missing_arg="some ECV component is missing from ARG";
+     708          37 :         plumed_massert(j+all_pntrToECVsClass[l]->getNumberOfArguments()<=getNumberOfArguments(),missing_arg);
+     709          90 :         for(unsigned h=0; h<all_pntrToECVsClass[l]->getNumberOfArguments(); h++)
+     710             :         {
+     711          53 :           std::string argName=getPntrToArgument(j+h)->getName();
+     712          53 :           std::string expectedECVname=all_pntrToECVsClass[l]->getComponentsVector()[h];
+     713          53 :           plumed_massert(argName==expectedECVname,missing_arg+", or is in wrong order: given ARG="+argName+" expected ARG="+expectedECVname);
+     714             :         }
+     715          37 :         j+=all_pntrToECVsClass[l]->getNumberOfArguments()-1;
+     716             :         break;
+     717             :       }
+     718             :     }
+     719          37 :     plumed_massert(foundECV_l<all_pntrToECVsClass.size(),error_notECV);
+     720             :   }
+     721          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     722          44 :     for(unsigned ll=l+1; ll<pntrToECVsClass_.size(); ll++)
+     723           7 :       plumed_massert(pntrToECVsClass_[l]->getLabel()!=pntrToECVsClass_[ll]->getLabel(),"cannot use same ECV twice");
+     724          30 : }
+     725             : 
+     726          30 : void OPESexpanded::init_linkECVs()
+     727             : {
+     728             :   //TODO It should be possible to make all of this more straightforward (and probably also faster):
+     729             :   //     - get rid of index_k_, making it trivial for each ECV
+     730             :   //     - store the ECVs_ and derECVs_ vectors here as a contiguous vector, and use pointers in the ECV classes
+     731             :   //     Some caveats:
+     732             :   //     - ECVmultiThermalBaric has a nontrivial index_k_ to avoid duplicates. use duplicates instead
+     733             :   //     - can the ECVs be MPI parallel or it's too complicated?
+     734          30 :   plumed_massert(deltaF_size_>0,"must set deltaF_size_ before calling init_linkECVs()");
+     735          30 :   if(NumParallel_==1)
+     736          28 :     deltaF_.resize(deltaF_size_);
+     737             :   else
+     738             :   {
+     739           2 :     const unsigned extra=(rank_<(deltaF_size_%NumParallel_)?1:0);
+     740           2 :     deltaF_.resize(deltaF_size_/NumParallel_+extra);
+     741             :     //these are used when printing deltaF_ to file
+     742           2 :     all_deltaF_.resize(deltaF_size_);
+     743           2 :     all_size_.resize(NumParallel_,deltaF_size_/NumParallel_);
+     744           2 :     disp_.resize(NumParallel_);
+     745           4 :     for(unsigned r=0; r<NumParallel_-1; r++)
+     746             :     {
+     747           2 :       if(r<deltaF_size_%NumParallel_)
+     748           0 :         all_size_[r]++;
+     749           2 :       disp_[r+1]=disp_[r]+all_size_[r];
+     750             :     }
+     751             :   }
+     752          30 :   diff_.resize(deltaF_.size());
+     753          30 :   ECVs_.resize(ncv_);
+     754          30 :   derECVs_.resize(ncv_);
+     755          30 :   index_k_.resize(deltaF_.size(),std::vector<unsigned>(ncv_));
+     756             :   unsigned index_j=0;
+     757          30 :   unsigned sizeSkip=deltaF_size_;
+     758          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     759             :   {
+     760          37 :     std::vector< std::vector<unsigned> > l_index_k(pntrToECVsClass_[l]->getIndex_k());
+     761          37 :     plumed_massert(deltaF_size_%l_index_k.size()==0,"buggy ECV: mismatch between getTotNumECVs() and getIndex_k().size()");
+     762          37 :     plumed_massert(l_index_k[0].size()==pntrToECVsClass_[l]->getNumberOfArguments(),"buggy ECV: mismatch between number of ARG and underlying CVs");
+     763          37 :     sizeSkip/=l_index_k.size();
+     764          90 :     for(unsigned h=0; h<pntrToECVsClass_[l]->getNumberOfArguments(); h++)
+     765             :     {
+     766          53 :       ECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToECVs(h);
+     767          53 :       derECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToDerECVs(h);
+     768          53 :       if(NumParallel_==1)
+     769             :       {
+     770       45589 :         for(unsigned i=0; i<deltaF_size_; i++)
+     771       45540 :           index_k_[i][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     772             :       }
+     773             :       else
+     774             :       {
+     775           4 :         const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     776             :         unsigned iter=0;
+     777          68 :         for(unsigned i=start; i<start+deltaF_.size(); i++)
+     778          64 :           index_k_[iter++][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     779             :       }
+     780             :     }
+     781          37 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     782          37 :   }
+     783          30 :   plumed_massert(sizeSkip==1,"this should not happen!");
+     784          30 : }
+     785             : 
+     786          20 : void OPESexpanded::init_fromObs() //This could probably be faster and/or require less memory...
+     787             : {
+     788             : //in case of multiple walkers gather all the statistics
+     789          20 :   if(NumWalkers_>1)
+     790             :   {
+     791           2 :     std::vector<double> all_obs_cv(ncv_*obs_steps_*NumWalkers_);
+     792           2 :     if(comm.Get_rank()==0)
+     793           2 :       multi_sim_comm.Allgather(obs_cvs_,all_obs_cv);
+     794           2 :     comm.Bcast(all_obs_cv,0);
+     795           2 :     obs_cvs_=all_obs_cv; //could this lead to memory issues?
+     796           2 :     obs_steps_*=NumWalkers_;
+     797             :   }
+     798             : 
+     799             : //initialize ECVs from observations
+     800             :   unsigned index_j=0;
+     801          20 :   deltaF_size_=1;
+     802          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     803             :   {
+     804          25 :     pntrToECVsClass_[l]->initECVs_observ(obs_cvs_,ncv_,index_j);
+     805          25 :     deltaF_size_*=pntrToECVsClass_[l]->getTotNumECVs(); //ECVs from different exansions will be combined
+     806          25 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     807             :   }
+     808          20 :   plumed_massert(index_j==getNumberOfArguments(),"mismatch between number of linked CVs and number of ARG");
+     809             : //link ECVs and initialize index_k_, mapping each deltaF to a single ECVs set
+     810          20 :   init_linkECVs();
+     811             : 
+     812             : //initialize deltaF_ from obs
+     813             : //for the first point, t=0, the ECVs are calculated by initECVs_observ, setting also any initial guess
+     814             :   index_j=0;
+     815       12379 :   for(unsigned i=0; i<deltaF_.size(); i++)
+     816       56923 :     for(unsigned j=0; j<ncv_; j++)
+     817       44564 :       deltaF_[i]+=kbt_*ECVs_[j][index_k_[i][j]];
+     818         179 :   for(unsigned t=1; t<obs_steps_; t++) //starts from t=1
+     819             :   {
+     820             :     unsigned index_j=0;
+     821         383 :     for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     822             :     {
+     823         224 :       pntrToECVsClass_[l]->calculateECVs(&obs_cvs_[t*ncv_+index_j]);
+     824         224 :       index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     825             :     }
+     826      102677 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     827             :     {
+     828      102518 :       const double diff_i=(-getExpansion(i)+deltaF_[i]/kbt_-std::log(t));
+     829      102518 :       if(diff_i>0) //save exp from overflow
+     830       16071 :         deltaF_[i]-=kbt_*(diff_i+std::log1p(std::exp(-diff_i))+std::log1p(-1./(1.+t)));
+     831             :       else
+     832       86447 :         deltaF_[i]-=kbt_*(std::log1p(std::exp(diff_i))+std::log1p(-1./(1.+t)));
+     833             :     }
+     834             :   }
+     835             :   obs_cvs_.clear();
+     836             : 
+     837             : //set deltaF_name_
+     838          20 :   deltaF_name_.resize(deltaF_size_,"DeltaF");
+     839          20 :   unsigned sizeSkip=deltaF_size_;
+     840          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     841             :   {
+     842          25 :     std::vector<std::string> lambdas_l=pntrToECVsClass_[l]->getLambdas();
+     843          25 :     plumed_massert(lambdas_l.size()==pntrToECVsClass_[l]->getTotNumECVs(),"buggy ECV: mismatch between getTotNumECVs() and getLambdas().size()");
+     844          25 :     sizeSkip/=lambdas_l.size();
+     845       22457 :     for(unsigned i=0; i<deltaF_size_; i++)
+     846       44864 :       deltaF_name_[i]+="_"+lambdas_l[(i/sizeSkip)%lambdas_l.size()];
+     847          25 :   }
+     848             : 
+     849             : //print initialization to file
+     850          20 :   log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     851          20 :   printDeltaF();
+     852          20 : }
+     853             : 
+     854          64 : void OPESexpanded::printDeltaF()
+     855             : {
+     856          64 :   deltaFsOfile_.printField("time",getTime());
+     857          64 :   deltaFsOfile_.printField("rct",rct_);
+     858          64 :   if(NumParallel_==1)
+     859             :   {
+     860       23988 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     861       23926 :       deltaFsOfile_.printField(deltaF_name_[i],deltaF_[i]);
+     862             :   }
+     863             :   else
+     864             :   {
+     865           2 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     866          66 :     for(unsigned i=0; i<deltaF_size_; i++)
+     867          64 :       deltaFsOfile_.printField(deltaF_name_[i],all_deltaF_[i]);
+     868             :   }
+     869          64 :   deltaFsOfile_.printField();
+     870          64 : }
+     871             : 
+     872          11 : void OPESexpanded::dumpStateToFile()
+     873             : {
+     874             : //rewrite header or rewind file
+     875          11 :   if(storeOldStates_)
+     876           3 :     stateOfile_.clearFields();
+     877           8 :   else if(walker_rank_==0)
+     878           8 :     stateOfile_.rewind();
+     879             : //define fields
+     880          11 :   stateOfile_.addConstantField("time");
+     881          11 :   stateOfile_.addConstantField("counter");
+     882          11 :   stateOfile_.addConstantField("rct");
+     883             : //print
+     884          11 :   stateOfile_.printField("time",getTime());
+     885          11 :   stateOfile_.printField("counter",counter_);
+     886          11 :   stateOfile_.printField("rct",rct_);
+     887          11 :   if(NumParallel_>1)
+     888           0 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     889         240 :   for(unsigned i=0; i<deltaF_size_; i++)
+     890             :   {
+     891             :     std::size_t pos_start=7; //skip "DeltaF_"
+     892         687 :     for(unsigned j=0; j<ncv_; j++)
+     893             :     {
+     894             :       plumed_dbg_massert(pos_start>6,"not enought _ in deltaF_name_"+std::to_string(i-1)+" string?");
+     895         458 :       const std::size_t pos_end=deltaF_name_[i].find("_",pos_start);
+     896         916 :       stateOfile_.printField(getPntrToArgument(j)->getName(),"  "+deltaF_name_[i].substr(pos_start,pos_end-pos_start));
+     897         458 :       pos_start=pos_end+1;
+     898             :     }
+     899         229 :     if(NumParallel_==1)
+     900         458 :       stateOfile_.printField("DeltaF",deltaF_[i]);
+     901             :     else
+     902           0 :       stateOfile_.printField("DeltaF",all_deltaF_[i]);
+     903         229 :     stateOfile_.printField();
+     904             :   }
+     905             : //make sure file is written even if small
+     906          11 :   if(!storeOldStates_)
+     907           8 :     stateOfile_.flush();
+     908          11 : }
+     909             : 
+     910         660 : void OPESexpanded::updateDeltaF(double bias)
+     911             : {
+     912             :   plumed_dbg_massert(counter_>0,"deltaF_ must be initialized");
+     913         660 :   counter_++;
+     914         660 :   const double arg=(bias-rct_)/kbt_-std::log(counter_-1.);
+     915             :   double increment;
+     916         660 :   if(arg>0) //save exp from overflow
+     917          28 :     increment=kbt_*(arg+std::log1p(std::exp(-arg)));
+     918             :   else
+     919         632 :     increment=kbt_*(std::log1p(std::exp(arg)));
+     920         660 :   #pragma omp parallel num_threads(NumOMP_)
+     921             :   {
+     922             :     #pragma omp for
+     923             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     924             :     {
+     925             :       const double diff_i=(-getExpansion(i)+(bias-rct_+deltaF_[i])/kbt_-std::log(counter_-1.));
+     926             :       if(diff_i>0) //save exp from overflow
+     927             :         deltaF_[i]+=increment-kbt_*(diff_i+std::log1p(std::exp(-diff_i)));
+     928             :       else
+     929             :         deltaF_[i]+=increment-kbt_*std::log1p(std::exp(diff_i));
+     930             :     }
+     931             :   }
+     932         660 :   rct_+=increment+kbt_*std::log1p(-1./counter_);
+     933         660 : }
+     934             : 
+     935      644469 : double OPESexpanded::getExpansion(unsigned i) const
+     936             : {
+     937             :   double expansion=0;
+     938     3003062 :   for(unsigned j=0; j<ncv_; j++)
+     939     2358593 :     expansion+=ECVs_[j][index_k_[i][j]]; //the index_k could be trivially guessed for most ECVs, but unfourtunately not all
+     940      644469 :   return expansion;
+     941             : }
+     942             : 
+     943             : }
+     944             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func-sort-c.html b/coverage/opes/OPESmetad.cpp.func-sort-c.html new file mode 100644 index 0000000000..e50d3f098a --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func-sort-c.html @@ -0,0 +1,208 @@ + + + + + + + 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:79583195.7 %
Date:2024-05-27 13:05:14Functions:333497.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe3006createERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe2566createERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe256C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe256D2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe300C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe300D2Ev4168
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func.html b/coverage/opes/OPESmetad.cpp.func.html new file mode 100644 index 0000000000..bb77e5e49b --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func.html @@ -0,0 +1,208 @@ + + + + + + + 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:79583195.7 %
Date:2024-05-27 13:05:14Functions:333497.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe2566createERKNS_13ActionOptionsE14
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe256C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_cRegisterMe256D2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe3006createERKNS_13ActionOptionsE7
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe300C2Ev4168
_ZN4PLMD4opes12_GLOBAL__N_124OPESmetad_eRegisterMe300D2Ev4168
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.gcov.html b/coverage/opes/OPESmetad.cpp.gcov.html new file mode 100644 index 0000000000..07c8092dd9 --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.gcov.html @@ -0,0 +1,1838 @@ + + + + + + + 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:79583195.7 %
Date:2024-05-27 13:05: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 with metadynamics-like target distribution.
+      33             : 
+      34             : This On-the-fly probability enhanced sampling (\ref OPES "OPES") method with metadynamics-like target distribution is described in \cite Invernizzi2020rethinking.
+      35             : 
+      36             : 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$.
+      37             : 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.
+      38             : Similarly to \ref METAD, \ref OPES_METAD optimizes the bias on-the-fly, with a given PACE.
+      39             : It does so by reweighting via kernel density estimation the unbiased distribution in the CV space, \f$P(\mathbf{s})\f$.
+      40             : A compression algorithm is used to prevent the number of kernels from growing linearly with the simulation time.
+      41             : The bias at step \f$n\f$ is
+      42             : \f[
+      43             : V_n(\mathbf{s}) = (1-1/\gamma)\frac{1}{\beta}\log\left(\frac{P_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+      44             : \f]
+      45             : See Ref.\cite Invernizzi2020rethinking for a complete description of the method.
+      46             : 
+      47             : 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.
+      48             : 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.
+      49             : For this reason, it is possible to use standard umbrella sampling reweighting (see \ref REWEIGHT_BIAS) to analyse the trajectory.
+      50             : 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).
+      51             : The estimated \f$c(t)\f$ is printed for reference only, since it should converge to a fixed value as the bias converges.
+      52             : This \f$c(t)\f$ should NOT be used for reweighting.
+      53             : 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.
+      54             : 
+      55             : Notice that \ref OPES_METAD is more sensitive to degenerate CVs than \ref METAD.
+      56             : 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.
+      57             : This can be useful to diagnose problems with your collective variable.
+      58             : 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.
+      59             : 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).
+      60             : 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.
+      61             : 
+      62             : The parameter BARRIER should be set to be at least equal to the highest free energy barrier you wish to overcome.
+      63             : If it is much lower than that, you will not cross the barrier, if it is much higher, convergence might take a little longer.
+      64             : If the system has a basin that is clearly more stable than the others, it is better to start the simulation from there.
+      65             : 
+      66             : 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).
+      67             : However, notice that depending on the system this might not be the optimal choice for SIGMA.
+      68             : 
+      69             : You can target a uniform flat distribution by explicitly setting BIASFACTOR=inf.
+      70             : However, this should be useful only in very specific cases.
+      71             : 
+      72             : 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.
+      73             : To do so, one has to add those biases with the EXTRA_BIAS keyword, as in the example below.
+      74             : 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).
+      75             : 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).
+      76             : 
+      77             : Through the EXCLUDED_REGION keywork, it is possible to specify a region of CV space where no kernels will be deposited.
+      78             : This can be useful for example for making sure the bias does not modify the transition region, thus allowing for rate calculation.
+      79             : See below for an example of how to use this keyword.
+      80             : 
+      81             : 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).
+      82             : For an exact restart you must use STATE_RFILE to read a checkpoint with all the needed info.
+      83             : To save such checkpoints, define a STATE_WFILE and choose how often to print them with STATE_WSTRIDE.
+      84             : By default this file is overwritten, but you can instead append to it using the flag STORE_STATES.
+      85             : 
+      86             : Multiple walkers are supported only with MPI communication, via the keyword WALKERS_MPI.
+      87             : 
+      88             : \par Examples
+      89             : 
+      90             : 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.
+      91             : The \ref opes-metad can also be useful to get started with the method.
+      92             : 
+      93             : The following is a minimal working example:
+      94             : 
+      95             : \plumedfile
+      96             : cv: DISTANCE ATOMS=1,2
+      97             : opes: OPES_METAD ARG=cv PACE=200 BARRIER=40
+      98             : PRINT STRIDE=200 FILE=COLVAR ARG=*
+      99             : \endplumedfile
+     100             : 
+     101             : Another more articulated one:
+     102             : 
+     103             : \plumedfile
+     104             : phi: TORSION ATOMS=5,7,9,15
+     105             : psi: TORSION ATOMS=7,9,15,17
+     106             : opes: OPES_METAD ...
+     107             :   FILE=Kernels.data
+     108             :   TEMP=300
+     109             :   ARG=phi,psi
+     110             :   PACE=500
+     111             :   BARRIER=50
+     112             :   SIGMA=0.15,0.15
+     113             :   SIGMA_MIN=0.01,0.01
+     114             :   STATE_RFILE=Restart.data
+     115             :   STATE_WFILE=State.data
+     116             :   STATE_WSTRIDE=500*100
+     117             :   STORE_STATES
+     118             :   WALKERS_MPI
+     119             :   NLIST
+     120             : ...
+     121             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=phi,psi,opes.*
+     122             : \endplumedfile
+     123             : 
+     124             : Next is an example of how to define a custom target distribution different from the well-tempered one.
+     125             : Here we chose to focus more on the transition state, that is around \f$\phi=0\f$.
+     126             : 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$.
+     127             : 
+     128             : \plumedfile
+     129             : phi: TORSION ATOMS=5,7,9,15
+     130             : FtgValue: CUSTOM ARG=phi PERIODIC=NO FUNC=(x/0.4)^2
+     131             : Ftg: BIASVALUE ARG=FtgValue
+     132             : opes: OPES_METAD ...
+     133             :   ARG=phi
+     134             :   PACE=500
+     135             :   BARRIER=50
+     136             :   SIGMA=0.2
+     137             :   BIASFACTOR=inf
+     138             :   EXTRA_BIAS=Ftg.bias
+     139             : ...
+     140             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,Ftg.bias,opes.bias
+     141             : \endplumedfile
+     142             : 
+     143             : 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.
+     144             : 
+     145             : Finally, an example of how to use the EXCLUDED_REGION keyword.
+     146             : It expects a characteristic function that is different from zero in the region to be excluded.
+     147             : You can use \ref CUSTOM and a combination of the step function to define it.
+     148             : 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$:
+     149             : 
+     150             : \plumedfile
+     151             : phi: TORSION ATOMS=5,7,9,15
+     152             : psi: TORSION ATOMS=7,9,15,17
+     153             : xx: CUSTOM PERIODIC=NO ARG=phi FUNC=step(x+0.6)-step(x-0.7)
+     154             : opes: OPES_METAD ...
+     155             :   ARG=phi,psi
+     156             :   PACE=500
+     157             :   BARRIER=30
+     158             :   EXCLUDED_REGION=xx
+     159             :   NLIST
+     160             : ...
+     161             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,psi,xx,opes.*
+     162             : \endplumedfile
+     163             : 
+     164             : */
+     165             : //+ENDPLUMEDOC
+     166             : 
+     167             : template <class mode>
+     168             : class OPESmetad : public bias::Bias {
+     169             : 
+     170             : private:
+     171             :   bool isFirstStep_;
+     172             :   unsigned NumOMP_;
+     173             :   unsigned NumParallel_;
+     174             :   unsigned rank_;
+     175             :   unsigned NumWalkers_;
+     176             :   unsigned walker_rank_;
+     177             :   unsigned long long counter_;
+     178             :   std::size_t ncv_;
+     179             : 
+     180             :   double kbt_;
+     181             :   double biasfactor_;
+     182             :   double bias_prefactor_;
+     183             :   unsigned stride_;
+     184             :   std::vector<double> sigma0_;
+     185             :   std::vector<double> sigma_min_;
+     186             :   unsigned adaptive_sigma_stride_;
+     187             :   unsigned long long adaptive_counter_;
+     188             :   std::vector<double> av_cv_;
+     189             :   std::vector<double> av_M2_;
+     190             :   bool fixed_sigma_;
+     191             :   bool adaptive_sigma_;
+     192             :   double epsilon_;
+     193             :   double sum_weights_;
+     194             :   double sum_weights2_;
+     195             : 
+     196             :   bool no_Zed_;
+     197             :   double Zed_;
+     198             :   double KDEnorm_;
+     199             : 
+     200             :   double threshold2_;
+     201             :   bool recursive_merge_;
+     202             : //kernels are truncated diagonal Gaussians
+     203        1050 :   struct kernel
+     204             :   {
+     205             :     double height;
+     206             :     std::vector<double> center;
+     207             :     std::vector<double> sigma;
+     208        1050 :     kernel(double h, const std::vector<double>& c,const std::vector<double>& s):
+     209        1050 :       height(h),center(c),sigma(s) {}
+     210             :   };
+     211             :   double cutoff2_;
+     212             :   double val_at_cutoff_;
+     213             :   void mergeKernels(kernel&,const kernel&); //merge the second one into the first one
+     214             :   double evaluateKernel(const kernel&,const std::vector<double>&) const;
+     215             :   double evaluateKernel(const kernel&,const std::vector<double>&,std::vector<double>&,std::vector<double>&);
+     216             :   std::vector<kernel> kernels_; //all compressed kernels
+     217             :   OFile kernelsOfile_;
+     218             : //neighbour list stuff
+     219             :   bool nlist_;
+     220             :   double nlist_param_[2];
+     221             :   std::vector<unsigned> nlist_index_;
+     222             :   std::vector<double> nlist_center_;
+     223             :   std::vector<double> nlist_dev2_;
+     224             :   unsigned nlist_steps_;
+     225             :   bool nlist_update_;
+     226             :   bool nlist_pace_reset_;
+     227             : 
+     228             :   bool calc_work_;
+     229             :   double work_;
+     230             :   double old_KDEnorm_;
+     231             :   std::vector<kernel> delta_kernels_;
+     232             : 
+     233             :   Value* excluded_region_;
+     234             :   std::vector<Value*> extra_biases_;
+     235             : 
+     236             :   OFile stateOfile_;
+     237             :   int wStateStride_;
+     238             :   bool storeOldStates_;
+     239             : 
+     240             :   double getProbAndDerivatives(const std::vector<double>&,std::vector<double>&);
+     241             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&);
+     242             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&,const double); //also print to file
+     243             :   unsigned getMergeableKernel(const std::vector<double>&,const unsigned);
+     244             :   void updateNlist(const std::vector<double>&);
+     245             :   void dumpStateToFile();
+     246             : 
+     247             : public:
+     248             :   explicit OPESmetad(const ActionOptions&);
+     249             :   void calculate() override;
+     250             :   void update() override;
+     251             :   static void registerKeywords(Keywords& keys);
+     252             : };
+     253             : 
+     254             : struct convergence { static const bool explore=false; };
+     255             : typedef OPESmetad<convergence> OPESmetad_c;
+     256       12532 : PLUMED_REGISTER_ACTION(OPESmetad_c,"OPES_METAD")
+     257             : 
+     258             : //OPES_METAD_EXPLORE is very similar from the point of view of the code,
+     259             : //but conceptually it is better to make it a separate BIAS action
+     260             : 
+     261             : //+PLUMEDOC OPES_BIAS OPES_METAD_EXPLORE
+     262             : /*
+     263             : On-the-fly probability enhanced sampling with well-tempered target distribution in exploreation mode.
+     264             : 
+     265             : On-the-fly probability enhanced sampling with well-tempered target distribution (\ref OPES "OPES") with well-tempered target distribution, exploration mode \cite Invernizzi2022explore .
+     266             : 
+     267             : 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$.
+     268             : 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.
+     269             : The bias at step \f$n\f$ is
+     270             : \f[
+     271             : V_n(\mathbf{s}) = (\gamma-1)\frac{1}{\beta}\log\left(\frac{p^{\text{WT}}_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+     272             : \f]
+     273             : See Ref.\cite Invernizzi2022explore for a complete description of the method.
+     274             : 
+     275             : 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.
+     276             : Given enough simulation time, both will converge to the same bias potential but they do so in a qualitatively different way.
+     277             : 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.
+     278             : This goes at the expenses of a typically slower convergence of the reweight estimate.
+     279             : \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.
+     280             : 
+     281             : Similarly to \ref OPES_METAD, also \ref OPES_METAD_EXPLORE uses a kernel density estimation with the same on-the-fly compression algorithm.
+     282             : The only difference is that the kernels are not weighted, since it estimates the sampled distribution and not the reweighted unbiased one.
+     283             : 
+     284             : 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.
+     285             : 
+     286             : \par Examples
+     287             : 
+     288             : The following is a minimal working example:
+     289             : 
+     290             : \plumedfile
+     291             : cv: DISTANCE ATOMS=1,2
+     292             : opes: OPES_METAD_EXPLORE ARG=cv PACE=500 BARRIER=40
+     293             : PRINT STRIDE=100 FILE=COLVAR ARG=cv,opes.*
+     294             : \endplumedfile
+     295             : */
+     296             : //+ENDPLUMEDOC
+     297             : 
+     298             : struct exploration { static const bool explore=true; };
+     299             : typedef OPESmetad<exploration> OPESmetad_e;
+     300       12518 : PLUMED_REGISTER_ACTION(OPESmetad_e,"OPES_METAD_EXPLORE")
+     301             : 
+     302             : template <class mode>
+     303          25 : void OPESmetad<mode>::registerKeywords(Keywords& keys)
+     304             : {
+     305          25 :   Bias::registerKeywords(keys);
+     306          25 :   keys.use("ARG");
+     307          50 :   keys.add("compulsory","TEMP","-1","temperature. If not set, it is taken from MD engine, but not all MD codes provide it");
+     308          50 :   keys.add("compulsory","PACE","the frequency for kernel deposition");
+     309          25 :   std::string info_sigma("the initial widths of the kernels");
+     310             :   if(mode::explore)
+     311             :     info_sigma+=", divided by the square root of gamma";
+     312             :   info_sigma+=". If not set, an adaptive sigma will be used with the given ADAPTIVE_SIGMA_STRIDE";
+     313          50 :   keys.add("compulsory","SIGMA","ADAPTIVE",info_sigma);
+     314          50 :   keys.add("compulsory","BARRIER","the free energy barrier to be overcome. It is used to set BIASFACTOR, EPSILON, and KERNEL_CUTOFF to reasonable values");
+     315          50 :   keys.add("compulsory","COMPRESSION_THRESHOLD","1","merge kernels if closer than this threshold, in units of sigma");
+     316             : //extra options
+     317          50 :   keys.add("optional","ADAPTIVE_SIGMA_STRIDE","number of steps for measuring adaptive sigma. Default is 10xPACE");
+     318          50 :   keys.add("optional","SIGMA_MIN","never reduce SIGMA below this value");
+     319          25 :   std::string info_biasfactor("the gamma bias factor used for the well-tempered target distribution. ");
+     320             :   if(mode::explore)
+     321             :     info_biasfactor+="Cannot be 'inf'";
+     322             :   else
+     323             :     info_biasfactor+="Set to 'inf' for uniform flat target";
+     324          50 :   keys.add("optional","BIASFACTOR",info_biasfactor);
+     325          50 :   keys.add("optional","EPSILON","the value of the regularization constant for the probability");
+     326          50 :   keys.add("optional","KERNEL_CUTOFF","truncate kernels at this distance, in units of sigma");
+     327          50 :   keys.add("optional","NLIST_PARAMETERS","( default=3.0,0.5 ) the two cutoff parameters for the kernels neighbor list");
+     328          50 :   keys.addFlag("NLIST",false,"use neighbor list for kernels summation, faster but experimental");
+     329          50 :   keys.addFlag("NLIST_PACE_RESET",false,"force the reset of the neighbor list at each PACE. Can be useful with WALKERS_MPI");
+     330          50 :   keys.addFlag("FIXED_SIGMA",false,"do not decrease sigma as the simulation proceeds. Can be added in a RESTART, to keep in check the number of compressed kernels");
+     331          50 :   keys.addFlag("RECURSIVE_MERGE_OFF",false,"do not recursively attempt kernel merging when a new one is added");
+     332          50 :   keys.addFlag("NO_ZED",false,"do not normalize over the explored CV space, Z_n=1");
+     333             : //kernels and state files
+     334          50 :   keys.add("compulsory","FILE","KERNELS","a file in which the list of all deposited kernels is stored");
+     335          50 :   keys.add("optional","FMT","specify format for KERNELS file");
+     336          50 :   keys.add("optional","STATE_RFILE","read from this file the compressed kernels and all the info needed to RESTART the simulation");
+     337          50 :   keys.add("optional","STATE_WFILE","write to this file the compressed kernels and all the info needed to RESTART the simulation");
+     338          50 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     339          50 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     340             : //miscellaneous
+     341          50 :   keys.add("optional","EXCLUDED_REGION","kernels are not deposited when the action provided here has a nonzero value, see example above");
+     342             :   if(!mode::explore)
+     343          32 :     keys.add("optional","EXTRA_BIAS","consider also these other bias potentials for the internal reweighting. This can be used e.g. for sampling a custom target distribution (see example above)");
+     344          50 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     345          50 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     346          50 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     347          25 :   keys.use("RESTART");
+     348          25 :   keys.use("UPDATE_FROM");
+     349          25 :   keys.use("UPDATE_UNTIL");
+     350             : 
+     351             : //output components
+     352          50 :   keys.addOutputComponent("rct","default","estimate of c(t). \\f$\\frac{1}{\\beta}\\log \\langle e^{\\beta V} \\rangle\\f$, should become flat as the simulation converges. Do NOT use for reweighting");
+     353          50 :   keys.addOutputComponent("zed","default","estimate of Z_n. should become flat once no new CV-space region is explored");
+     354          50 :   keys.addOutputComponent("neff","default","effective sample size");
+     355          50 :   keys.addOutputComponent("nker","default","total number of compressed kernels used to represent the bias");
+     356          50 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     357          50 :   keys.addOutputComponent("nlker","NLIST","number of kernels in the neighbor list");
+     358          50 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     359          25 : }
+     360             : 
+     361             : template <class mode>
+     362          21 : OPESmetad<mode>::OPESmetad(const ActionOptions& ao)
+     363             :   : PLUMED_BIAS_INIT(ao)
+     364          21 :   , isFirstStep_(true)
+     365          21 :   , counter_(1)
+     366          21 :   , ncv_(getNumberOfArguments())
+     367          21 :   , Zed_(1)
+     368          21 :   , work_(0)
+     369          21 :   , excluded_region_(NULL)
+     370             : {
+     371          42 :   std::string error_in_input1("Error in input in action "+getName()+" with label "+getLabel()+": the keyword ");
+     372          21 :   std::string error_in_input2(" could not be read correctly");
+     373             : 
+     374             : //set kbt_
+     375          21 :   const double kB=plumed.getAtoms().getKBoltzmann();
+     376          21 :   kbt_=plumed.getAtoms().getKbT();
+     377          21 :   double temp=-1;
+     378          21 :   parse("TEMP",temp);
+     379          21 :   if(temp>0)
+     380             :   {
+     381          21 :     if(kbt_>0 && std::abs(kbt_-kB*temp)>1e-4)
+     382           0 :       log.printf(" +++ WARNING +++ using TEMP=%g while MD engine uses %g\n",temp,kbt_/kB);
+     383          21 :     kbt_=kB*temp;
+     384             :   }
+     385          21 :   plumed_massert(kbt_>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     386             : 
+     387             : //other compulsory input
+     388          21 :   parse("PACE",stride_);
+     389             : 
+     390          21 :   double barrier=0;
+     391          21 :   parse("BARRIER",barrier);
+     392          21 :   plumed_massert(barrier>=0,"the BARRIER should be greater than zero");
+     393             : 
+     394          21 :   biasfactor_=barrier/kbt_;
+     395             :   std::string biasfactor_str;
+     396          42 :   parse("BIASFACTOR",biasfactor_str);
+     397          38 :   if(biasfactor_str=="inf" || biasfactor_str=="INF")
+     398             :   {
+     399           4 :     biasfactor_=std::numeric_limits<double>::infinity();
+     400           4 :     bias_prefactor_=1;
+     401             :   }
+     402             :   else
+     403             :   {
+     404          17 :     if(biasfactor_str.length()>0)
+     405           3 :       plumed_massert(Tools::convertNoexcept(biasfactor_str,biasfactor_),error_in_input1+"BIASFACTOR"+error_in_input2);
+     406          17 :     plumed_massert(biasfactor_>1,"BIASFACTOR must be greater than one (use 'inf' for uniform target)");
+     407          17 :     bias_prefactor_=1-1./biasfactor_;
+     408             :   }
+     409             :   if(mode::explore)
+     410             :   {
+     411           7 :     plumed_massert(!std::isinf(biasfactor_),"BIASFACTOR=inf is not compatible with EXPLORE mode");
+     412           7 :     bias_prefactor_=biasfactor_-1;
+     413             :   }
+     414             : 
+     415          21 :   adaptive_sigma_=false;
+     416          21 :   adaptive_sigma_stride_=0;
+     417          42 :   parse("ADAPTIVE_SIGMA_STRIDE",adaptive_sigma_stride_);
+     418             :   std::vector<std::string> sigma_str;
+     419          21 :   parseVector("SIGMA",sigma_str);
+     420          21 :   sigma0_.resize(ncv_);
+     421             :   double dummy;
+     422          21 :   if(sigma_str.size()==1 && !Tools::convertNoexcept(sigma_str[0],dummy))
+     423             :   {
+     424          11 :     plumed_massert(sigma_str[0]=="ADAPTIVE" || sigma_str[0]=="adaptive",error_in_input1+"SIGMA"+error_in_input2);
+     425          11 :     plumed_massert(!std::isinf(biasfactor_),"cannot use BIASFACTOR=inf with adaptive SIGMA");
+     426          11 :     adaptive_counter_=0;
+     427          11 :     if(adaptive_sigma_stride_==0)
+     428           2 :       adaptive_sigma_stride_=10*stride_; //NB: this is arbitrary, chosen from few tests
+     429          11 :     av_cv_.resize(ncv_,0);
+     430          11 :     av_M2_.resize(ncv_,0);
+     431          11 :     plumed_massert(adaptive_sigma_stride_>=stride_,"better to chose ADAPTIVE_SIGMA_STRIDE > PACE");
+     432          11 :     adaptive_sigma_=true;
+     433             :   }
+     434             :   else
+     435             :   {
+     436          10 :     plumed_massert(sigma_str.size()==ncv_,"number of SIGMA parameters does not match number of arguments");
+     437          10 :     plumed_massert(adaptive_sigma_stride_==0,"if SIGMA is not ADAPTIVE you cannot set an ADAPTIVE_SIGMA_STRIDE");
+     438          29 :     for(unsigned i=0; i<ncv_; i++)
+     439             :     {
+     440          19 :       plumed_massert(Tools::convertNoexcept(sigma_str[i],sigma0_[i]),error_in_input1+"SIGMA"+error_in_input2);
+     441             :       if(mode::explore)
+     442           6 :         sigma0_[i]*=std::sqrt(biasfactor_); //the sigma of the target is broader Ftg(s)=1/gamma*F(s)
+     443             :     }
+     444             :   }
+     445          42 :   parseVector("SIGMA_MIN",sigma_min_);
+     446          21 :   plumed_massert(sigma_min_.size()==0 || sigma_min_.size()==ncv_,"number of SIGMA_MIN does not match number of arguments");
+     447          21 :   if(sigma_min_.size()>0 && !adaptive_sigma_)
+     448             :   {
+     449           3 :     for(unsigned i=0; i<ncv_; i++)
+     450           2 :       plumed_massert(sigma_min_[i]<=sigma0_[i],"SIGMA_MIN should be smaller than SIGMA");
+     451             :   }
+     452             : 
+     453          21 :   epsilon_=std::exp(-barrier/bias_prefactor_/kbt_);
+     454          21 :   parse("EPSILON",epsilon_);
+     455          21 :   plumed_massert(epsilon_>0,"you must choose a value for EPSILON greater than zero. Is your BARRIER too high?");
+     456          21 :   sum_weights_=std::pow(epsilon_,bias_prefactor_); //to avoid NANs we start with counter_=1 and w0=exp(beta*V0)
+     457          21 :   sum_weights2_=sum_weights_*sum_weights_;
+     458             : 
+     459          21 :   double cutoff=sqrt(2.*barrier/bias_prefactor_/kbt_);
+     460             :   if(mode::explore)
+     461           7 :     cutoff=sqrt(2.*barrier/kbt_); //otherwise it is too small
+     462          21 :   parse("KERNEL_CUTOFF",cutoff);
+     463          21 :   plumed_massert(cutoff>0,"you must choose a value for KERNEL_CUTOFF greater than zero");
+     464          21 :   cutoff2_=cutoff*cutoff;
+     465          21 :   val_at_cutoff_=std::exp(-0.5*cutoff2_);
+     466             : 
+     467          21 :   threshold2_=1;
+     468          21 :   parse("COMPRESSION_THRESHOLD",threshold2_);
+     469          21 :   threshold2_*=threshold2_;
+     470          21 :   if(threshold2_!=0)
+     471          21 :     plumed_massert(threshold2_>0 && threshold2_<cutoff2_,"COMPRESSION_THRESHOLD cannot be bigger than the KERNEL_CUTOFF");
+     472             : 
+     473             : //setup neighbor list
+     474          21 :   nlist_=false;
+     475          21 :   parseFlag("NLIST",nlist_);
+     476          21 :   nlist_pace_reset_=false;
+     477          21 :   parseFlag("NLIST_PACE_RESET",nlist_pace_reset_);
+     478          21 :   if(nlist_pace_reset_)
+     479           2 :     nlist_=true;
+     480             :   std::vector<double> nlist_param;
+     481          42 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     482          21 :   if(nlist_param.size()==0)
+     483             :   {
+     484          17 :     nlist_param_[0]=3.0;//*cutoff2_ -> max distance of neighbors
+     485          17 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     486             :   }
+     487             :   else
+     488             :   {
+     489           4 :     nlist_=true;
+     490           4 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     491           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");
+     492           4 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]))+0.16;
+     493           4 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     494           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));
+     495           4 :     nlist_param_[0]=nlist_param[0];
+     496           4 :     nlist_param_[1]=nlist_param[1];
+     497             :   }
+     498          21 :   nlist_center_.resize(ncv_);
+     499          21 :   nlist_dev2_.resize(ncv_,0.);
+     500          21 :   nlist_steps_=0;
+     501          21 :   nlist_update_=true;
+     502             : 
+     503             : //optional stuff
+     504          21 :   no_Zed_=false;
+     505          21 :   parseFlag("NO_ZED",no_Zed_);
+     506          21 :   if(no_Zed_)
+     507             :   { //this makes it more gentle in the initial phase
+     508           6 :     sum_weights_=1;
+     509           6 :     sum_weights2_=1;
+     510             :   }
+     511          21 :   fixed_sigma_=false;
+     512          21 :   parseFlag("FIXED_SIGMA",fixed_sigma_);
+     513          21 :   bool recursive_merge_off=false;
+     514          21 :   parseFlag("RECURSIVE_MERGE_OFF",recursive_merge_off);
+     515          21 :   recursive_merge_=!recursive_merge_off;
+     516          42 :   parseFlag("CALC_WORK",calc_work_);
+     517             : 
+     518             : //options involving extra arguments
+     519             :   std::vector<Value*> args;
+     520          42 :   parseArgumentList("EXCLUDED_REGION",args);
+     521          21 :   if(args.size()>0)
+     522             :   {
+     523           2 :     plumed_massert(args.size()==1,"only one characteristic function should define the region to be excluded");
+     524           2 :     requestExtraDependencies(args);
+     525           2 :     excluded_region_=args[0];
+     526             :   }
+     527             :   if(!mode::explore)
+     528             :   {
+     529          28 :     parseArgumentList("EXTRA_BIAS",extra_biases_);
+     530          14 :     if(extra_biases_.size()>0)
+     531           2 :       requestExtraDependencies(extra_biases_);
+     532             :   }
+     533             : 
+     534             : //kernels file
+     535             :   std::string kernelsFileName;
+     536          42 :   parse("FILE",kernelsFileName);
+     537             :   std::string fmt;
+     538          42 :   parse("FMT",fmt);
+     539             : 
+     540             : //output checkpoint of current state
+     541             :   std::string restartFileName;
+     542          42 :   parse("STATE_RFILE",restartFileName);
+     543             :   std::string stateFileName;
+     544          21 :   parse("STATE_WFILE",stateFileName);
+     545          21 :   wStateStride_=0;
+     546          21 :   parse("STATE_WSTRIDE",wStateStride_);
+     547          21 :   storeOldStates_=false;
+     548          21 :   parseFlag("STORE_STATES",storeOldStates_);
+     549          21 :   if(wStateStride_!=0 || storeOldStates_)
+     550          10 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     551          21 :   if(wStateStride_>0)
+     552          10 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus it is suggested to use a multiple of PACE");
+     553          21 :   if(stateFileName.length()>0 && wStateStride_==0)
+     554           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     555             : 
+     556             : //multiple walkers //TODO implement also external mw for cp2k
+     557          21 :   bool walkers_mpi=false;
+     558          21 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     559          21 :   if(walkers_mpi)
+     560             :   {
+     561             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     562          10 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     563          10 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     564             : 
+     565          10 :     if(comm.Get_rank()==0)//multi_sim_comm works on first rank only
+     566             :     {
+     567          10 :       NumWalkers_=multi_sim_comm.Get_size();
+     568          10 :       walker_rank_=multi_sim_comm.Get_rank();
+     569             :     }
+     570          10 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     571          10 :     comm.Bcast(walker_rank_,0);
+     572             :   }
+     573             :   else
+     574             :   {
+     575          11 :     NumWalkers_=1;
+     576          11 :     walker_rank_=0;
+     577             :   }
+     578             : 
+     579             : //parallelization stuff
+     580          21 :   NumOMP_=OpenMP::getNumThreads();
+     581          21 :   NumParallel_=comm.Get_size();
+     582          21 :   rank_=comm.Get_rank();
+     583          21 :   bool serial=false;
+     584          21 :   parseFlag("SERIAL",serial);
+     585          21 :   if(serial)
+     586             :   {
+     587           4 :     NumOMP_=1;
+     588           4 :     NumParallel_=1;
+     589           4 :     rank_=0;
+     590             :   }
+     591             : 
+     592          21 :   checkRead();
+     593             : 
+     594             : //restart if needed
+     595             :   bool convertKernelsToState=false;
+     596          21 :   if(getRestart())
+     597             :   {
+     598             :     bool stateRestart=true;
+     599          11 :     if(restartFileName.length()==0)
+     600             :     {
+     601             :       stateRestart=false;
+     602             :       restartFileName=kernelsFileName;
+     603             :     }
+     604          11 :     IFile ifile;
+     605          11 :     ifile.link(*this);
+     606          11 :     if(ifile.FileExist(restartFileName))
+     607             :     {
+     608          11 :       bool tmp_nlist=nlist_;
+     609          11 :       nlist_=false; // NLIST is not needed while restarting
+     610          11 :       ifile.open(restartFileName);
+     611          11 :       log.printf("  RESTART - make sure all used options are compatible\n");
+     612          11 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     613          11 :       std::string action_name=getName();
+     614          11 :       if(stateRestart)
+     615             :       {
+     616           6 :         log.printf("    it should be a STATE file (not a KERNELS file)\n");
+     617             :         action_name+="_state";
+     618             :       }
+     619             :       else
+     620             :       {
+     621           5 :         log.printf(" +++ WARNING +++ RESTART from KERNELS might be approximate, use STATE_WFILE and STATE_RFILE to restart from the exact state\n");
+     622             :         action_name+="_kernels";
+     623             :       }
+     624             :       std::string old_action_name;
+     625          11 :       ifile.scanField("action",old_action_name);
+     626          11 :       plumed_massert(action_name==old_action_name,"RESTART - mismatch between old and new action name. Expected '"+action_name+"', but found '"+old_action_name+"'");
+     627             :       std::string old_biasfactor_str;
+     628          22 :       ifile.scanField("biasfactor",old_biasfactor_str);
+     629          21 :       if(old_biasfactor_str=="inf" || old_biasfactor_str=="INF")
+     630             :       {
+     631           1 :         if(!std::isinf(biasfactor_))
+     632           0 :           log.printf(" +++ WARNING +++ previous bias factor was inf while now it is %g\n",biasfactor_);
+     633             :       }
+     634             :       else
+     635             :       {
+     636             :         double old_biasfactor;
+     637          10 :         ifile.scanField("biasfactor",old_biasfactor);
+     638          10 :         if(std::abs(biasfactor_-old_biasfactor)>1e-6*biasfactor_)
+     639           0 :           log.printf(" +++ WARNING +++ previous bias factor was %g while now it is %g. diff = %g\n",old_biasfactor,biasfactor_,biasfactor_-old_biasfactor);
+     640             :       }
+     641             :       double old_epsilon;
+     642          11 :       ifile.scanField("epsilon",old_epsilon);
+     643          11 :       if(std::abs(epsilon_-old_epsilon)>1e-6*epsilon_)
+     644           8 :         log.printf(" +++ WARNING +++ previous epsilon was %g while now it is %g. diff = %g\n",old_epsilon,epsilon_,epsilon_-old_epsilon);
+     645             :       double old_cutoff;
+     646          11 :       ifile.scanField("kernel_cutoff",old_cutoff);
+     647          11 :       if(std::abs(cutoff-old_cutoff)>1e-6*cutoff)
+     648           0 :         log.printf(" +++ WARNING +++ previous kernel_cutoff was %g while now it is %g. diff = %g\n",old_cutoff,cutoff,cutoff-old_cutoff);
+     649             :       double old_threshold;
+     650          11 :       const double threshold=sqrt(threshold2_);
+     651          11 :       ifile.scanField("compression_threshold",old_threshold);
+     652          11 :       if(std::abs(threshold-old_threshold)>1e-6*threshold)
+     653           0 :         log.printf(" +++ WARNING +++ previous compression_threshold was %g while now it is %g. diff = %g\n",old_threshold,threshold,threshold-old_threshold);
+     654          11 :       if(stateRestart)
+     655             :       {
+     656           6 :         ifile.scanField("zed",Zed_);
+     657           6 :         ifile.scanField("sum_weights",sum_weights_);
+     658           6 :         ifile.scanField("sum_weights2",sum_weights2_);
+     659           6 :         ifile.scanField("counter",counter_);
+     660           6 :         if(adaptive_sigma_)
+     661             :         {
+     662           6 :           ifile.scanField("adaptive_counter",adaptive_counter_);
+     663           6 :           if(NumWalkers_==1)
+     664             :           {
+     665           6 :             for(unsigned i=0; i<ncv_; i++)
+     666             :             {
+     667           8 :               ifile.scanField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+     668           8 :               ifile.scanField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+     669           8 :               ifile.scanField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+     670             :             }
+     671             :           }
+     672             :           else
+     673             :           {
+     674          12 :             for(unsigned w=0; w<NumWalkers_; w++)
+     675          24 :               for(unsigned i=0; i<ncv_; i++)
+     676             :               {
+     677             :                 double tmp0,tmp1,tmp2;
+     678          32 :                 const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+     679          16 :                 ifile.scanField("sigma0_"+arg_iw,tmp0);
+     680          16 :                 ifile.scanField("av_cv_"+arg_iw,tmp1);
+     681          16 :                 ifile.scanField("av_M2_"+arg_iw,tmp2);
+     682          16 :                 if(w==walker_rank_)
+     683             :                 {
+     684           8 :                   sigma0_[i]=tmp0;
+     685           8 :                   av_cv_[i]=tmp1;
+     686           8 :                   av_M2_[i]=tmp2;
+     687             :                 }
+     688             :               }
+     689             :           }
+     690             :         }
+     691             :       }
+     692          33 :       for(unsigned i=0; i<ncv_; i++)
+     693             :       {
+     694          22 :         if(getPntrToArgument(i)->isPeriodic())
+     695             :         {
+     696             :           std::string arg_min,arg_max;
+     697          22 :           getPntrToArgument(i)->getDomain(arg_min,arg_max);
+     698             :           std::string file_min,file_max;
+     699          44 :           ifile.scanField("min_"+getPntrToArgument(i)->getName(),file_min);
+     700          22 :           ifile.scanField("max_"+getPntrToArgument(i)->getName(),file_max);
+     701          22 :           plumed_massert(file_min==arg_min,"RESTART - mismatch between old and new ARG periodicity");
+     702          22 :           plumed_massert(file_max==arg_max,"RESTART - mismatch between old and new ARG periodicity");
+     703             :         }
+     704             :       }
+     705          11 :       if(stateRestart)
+     706             :       {
+     707             :         double time;
+     708          60 :         while(ifile.scanField("time",time))
+     709             :         {
+     710          24 :           std::vector<double> center(ncv_);
+     711          24 :           std::vector<double> sigma(ncv_);
+     712             :           double height;
+     713          72 :           for(unsigned i=0; i<ncv_; i++)
+     714          48 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     715          72 :           for(unsigned i=0; i<ncv_; i++)
+     716          96 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     717          24 :           ifile.scanField("height",height);
+     718          24 :           ifile.scanField();
+     719          24 :           kernels_.emplace_back(height,center,sigma);
+     720             :         }
+     721           6 :         log.printf("    a total of %lu kernels where read\n",kernels_.size());
+     722             :       }
+     723             :       else
+     724             :       {
+     725           5 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     726             :         double time;
+     727         270 :         while(ifile.scanField("time",time))
+     728             :         {
+     729         130 :           std::vector<double> center(ncv_);
+     730         130 :           std::vector<double> sigma(ncv_);
+     731             :           double height;
+     732             :           double logweight;
+     733         390 :           for(unsigned i=0; i<ncv_; i++)
+     734         260 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     735         390 :           for(unsigned i=0; i<ncv_; i++)
+     736         520 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     737         130 :           if(counter_==(1+walker_rank_) && adaptive_sigma_)
+     738           0 :             sigma0_=sigma;
+     739         130 :           ifile.scanField("height",height);
+     740         130 :           ifile.scanField("logweight",logweight);
+     741         130 :           ifile.scanField();
+     742         130 :           addKernel(height,center,sigma);
+     743         130 :           const double weight=std::exp(logweight);
+     744         130 :           sum_weights_+=weight; //this sum is slightly inaccurate, because when printing some precision is lost
+     745         130 :           sum_weights2_+=weight*weight;
+     746         130 :           counter_++;
+     747             :         }
+     748           5 :         KDEnorm_=mode::explore?counter_:sum_weights_;
+     749           5 :         if(!no_Zed_)
+     750             :         {
+     751           2 :           double sum_uprob=0;
+     752          48 :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+     753        1104 :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+     754        1058 :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+     755           2 :           if(NumParallel_>1)
+     756           0 :             comm.Sum(sum_uprob);
+     757           2 :           Zed_=sum_uprob/KDEnorm_/kernels_.size();
+     758             :         }
+     759           5 :         log.printf("    a total of %llu kernels where read, and compressed to %lu\n",counter_-1,kernels_.size());
+     760             :         convertKernelsToState=true;
+     761             :       }
+     762          11 :       ifile.reset(false);
+     763          11 :       ifile.close();
+     764          11 :       nlist_=tmp_nlist;
+     765             :     }
+     766             :     else //same behaviour as METAD
+     767           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     768          11 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     769             :     {
+     770           6 :       const unsigned kernels_size=kernels_.size();
+     771           6 :       std::vector<unsigned> all_kernels_size(NumWalkers_);
+     772           6 :       if(comm.Get_rank()==0)
+     773           6 :         multi_sim_comm.Allgather(kernels_size,all_kernels_size);
+     774           6 :       comm.Bcast(all_kernels_size,0);
+     775             :       bool same_number_of_kernels=true;
+     776          12 :       for(unsigned w=1; w<NumWalkers_; w++)
+     777           6 :         if(all_kernels_size[0]!=all_kernels_size[w])
+     778             :           same_number_of_kernels=false;
+     779           6 :       plumed_massert(same_number_of_kernels,"RESTART - not all walkers are reading the same file!");
+     780             :     }
+     781          11 :   }
+     782          10 :   else if(restartFileName.length()>0)
+     783           4 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     784             : 
+     785             : //sync all walkers to avoid opening files before reading is over (see also METAD)
+     786          21 :   comm.Barrier();
+     787          21 :   if(comm.Get_rank()==0 && walkers_mpi)
+     788          10 :     multi_sim_comm.Barrier();
+     789             : 
+     790             : //setup output kernels file
+     791          21 :   kernelsOfile_.link(*this);
+     792          21 :   if(NumWalkers_>1)
+     793             :   {
+     794          10 :     if(walker_rank_>0)
+     795             :       kernelsFileName="/dev/null"; //only first walker writes on file
+     796          20 :     kernelsOfile_.enforceSuffix("");
+     797             :   }
+     798          21 :   kernelsOfile_.open(kernelsFileName);
+     799          21 :   if(fmt.length()>0)
+     800          42 :     kernelsOfile_.fmtField(" "+fmt);
+     801             :   kernelsOfile_.setHeavyFlush(); //do I need it?
+     802             :   //define and set const fields
+     803          21 :   kernelsOfile_.addConstantField("action");
+     804          21 :   kernelsOfile_.addConstantField("biasfactor");
+     805          21 :   kernelsOfile_.addConstantField("epsilon");
+     806          21 :   kernelsOfile_.addConstantField("kernel_cutoff");
+     807          21 :   kernelsOfile_.addConstantField("compression_threshold");
+     808          61 :   for(unsigned i=0; i<ncv_; i++)
+     809          40 :     kernelsOfile_.setupPrintValue(getPntrToArgument(i));
+     810          42 :   kernelsOfile_.printField("action",getName()+"_kernels");
+     811          21 :   kernelsOfile_.printField("biasfactor",biasfactor_);
+     812          21 :   kernelsOfile_.printField("epsilon",epsilon_);
+     813          21 :   kernelsOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+     814          21 :   kernelsOfile_.printField("compression_threshold",sqrt(threshold2_));
+     815             : 
+     816             : //open file for storing state
+     817          21 :   if(wStateStride_!=0)
+     818             :   {
+     819          11 :     stateOfile_.link(*this);
+     820          11 :     if(NumWalkers_>1)
+     821             :     {
+     822           8 :       if(walker_rank_>0)
+     823             :         stateFileName="/dev/null"; //only first walker writes on file
+     824          16 :       stateOfile_.enforceSuffix("");
+     825             :     }
+     826          11 :     stateOfile_.open(stateFileName);
+     827          11 :     if(fmt.length()>0)
+     828          22 :       stateOfile_.fmtField(" "+fmt);
+     829          11 :     if(convertKernelsToState)
+     830           0 :       dumpStateToFile();
+     831             :   }
+     832             : 
+     833             : //set initial old values
+     834          21 :   KDEnorm_=mode::explore?counter_:sum_weights_;
+     835          21 :   old_KDEnorm_=KDEnorm_;
+     836             : 
+     837             : //add and set output components
+     838          21 :   addComponent("rct");
+     839          21 :   componentIsNotPeriodic("rct");
+     840          21 :   getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+     841          21 :   addComponent("zed");
+     842          21 :   componentIsNotPeriodic("zed");
+     843          21 :   getPntrToComponent("zed")->set(Zed_);
+     844          21 :   addComponent("neff");
+     845          21 :   componentIsNotPeriodic("neff");
+     846          21 :   getPntrToComponent("neff")->set(std::pow(1+sum_weights_,2)/(1+sum_weights2_));
+     847          21 :   addComponent("nker");
+     848          21 :   componentIsNotPeriodic("nker");
+     849          21 :   getPntrToComponent("nker")->set(kernels_.size());
+     850          21 :   if(calc_work_)
+     851             :   {
+     852           7 :     addComponent("work");
+     853          14 :     componentIsNotPeriodic("work");
+     854             :   }
+     855          21 :   if(nlist_)
+     856             :   {
+     857           5 :     addComponent("nlker");
+     858           5 :     componentIsNotPeriodic("nlker");
+     859           5 :     addComponent("nlsteps");
+     860          10 :     componentIsNotPeriodic("nlsteps");
+     861             :   }
+     862             : 
+     863             : //printing some info
+     864          21 :   log.printf("  temperature = %g\n",kbt_/kB);
+     865          21 :   log.printf("  beta = %g\n",1./kbt_);
+     866          21 :   log.printf("  depositing new kernels with PACE = %u\n",stride_);
+     867          21 :   log.printf("  expected BARRIER is %g\n",barrier);
+     868          21 :   log.printf("  using target distribution with BIASFACTOR gamma = %g\n",biasfactor_);
+     869          21 :   if(std::isinf(biasfactor_))
+     870           4 :     log.printf("    (thus a uniform flat target distribution, no well-tempering)\n");
+     871          21 :   if(excluded_region_!=NULL)
+     872           2 :     log.printf(" -- EXCLUDED_REGION: kernels will be deposited only when '%s' is equal to zero\n",excluded_region_->getName().c_str());
+     873          21 :   if(extra_biases_.size()>0)
+     874             :   {
+     875           2 :     log.printf(" -- EXTRA_BIAS: ");
+     876           5 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+     877           3 :       log.printf("%s ",extra_biases_[e]->getName().c_str());
+     878           2 :     log.printf("will be reweighted\n");
+     879             :   }
+     880          21 :   if(adaptive_sigma_)
+     881             :   {
+     882          11 :     log.printf("  adaptive SIGMA will be used, with ADAPTIVE_SIGMA_STRIDE = %u\n",adaptive_sigma_stride_);
+     883          11 :     unsigned x=std::ceil(adaptive_sigma_stride_/stride_);
+     884          11 :     log.printf("    thus the first x kernel depositions will be skipped, x = ADAPTIVE_SIGMA_STRIDE/PACE = %u\n",x);
+     885             :   }
+     886             :   else
+     887             :   {
+     888          10 :     log.printf("  kernels have initial SIGMA = ");
+     889          29 :     for(unsigned i=0; i<ncv_; i++)
+     890          19 :       log.printf(" %g",sigma0_[i]);
+     891          10 :     log.printf("\n");
+     892             :   }
+     893          21 :   if(sigma_min_.size()>0)
+     894             :   {
+     895           3 :     log.printf("  kernels have a SIGMA_MIN = ");
+     896           9 :     for(unsigned i=0; i<ncv_; i++)
+     897           6 :       log.printf(" %g",sigma_min_[i]);
+     898           3 :     log.printf("\n");
+     899             :   }
+     900          21 :   if(fixed_sigma_)
+     901           6 :     log.printf(" -- FIXED_SIGMA: sigma will not decrease as the simulation proceeds\n");
+     902          21 :   log.printf("  kernels are truncated with KERNELS_CUTOFF = %g\n",cutoff);
+     903          21 :   if(cutoff<3.5)
+     904           0 :     log.printf(" +++ WARNING +++ probably kernels are truncated too much\n");
+     905          21 :   log.printf("  the value at cutoff is = %g\n",val_at_cutoff_);
+     906          21 :   log.printf("  regularization EPSILON = %g\n",epsilon_);
+     907          21 :   if(val_at_cutoff_>epsilon_*(1+1e-6))
+     908           0 :     log.printf(" +++ WARNING +++ the KERNEL_CUTOFF might be too small for the given EPSILON\n");
+     909          21 :   log.printf("  kernels will be compressed when closer than COMPRESSION_THRESHOLD = %g\n",sqrt(threshold2_));
+     910          21 :   if(threshold2_==0)
+     911           0 :     log.printf(" +++ WARNING +++ kernels will never merge, expect slowdowns\n");
+     912          21 :   if(!recursive_merge_)
+     913           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");
+     914          21 :   if(nlist_)
+     915           5 :     log.printf(" -- NLIST: using neighbor list for kernels, with parameters: %g,%g\n",nlist_param_[0],nlist_param_[1]);
+     916          21 :   if(nlist_pace_reset_)
+     917           2 :     log.printf(" -- NLIST_PACE_RESET: forcing the neighbor list to update every PACE\n");
+     918          21 :   if(no_Zed_)
+     919           6 :     log.printf(" -- NO_ZED: using fixed normalization factor = %g\n",Zed_);
+     920          21 :   if(wStateStride_>0)
+     921          10 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     922          21 :   if(wStateStride_==-1)
+     923           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());
+     924          21 :   if(walkers_mpi)
+     925          10 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     926          21 :   if(NumWalkers_>1)
+     927             :   {
+     928          10 :     log.printf("  using multiple walkers\n");
+     929          10 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     930          10 :     log.printf("    walker rank: %u\n",walker_rank_);
+     931             :   }
+     932          21 :   int mw_warning=0;
+     933          21 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     934           0 :     mw_warning=1;
+     935          21 :   comm.Bcast(mw_warning,0);
+     936          21 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     937           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     938          21 :   if(NumParallel_>1)
+     939           4 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     940          21 :   if(NumOMP_>1)
+     941          17 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     942          21 :   if(serial)
+     943           4 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     944          21 :   log.printf("  Bibliography: ");
+     945          42 :   log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Phys. Chem. Lett. 11, 2731-2736 (2020)");
+     946          14 :   if(mode::explore || adaptive_sigma_)
+     947          28 :     log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Chem. Theory Comput. 18, 3988-3996 (2022)");
+     948          21 :   log.printf("\n");
+     949          42 : }
+     950             : 
+     951             : template <class mode>
+     952        1071 : void OPESmetad<mode>::calculate()
+     953             : {
+     954             : //get cv
+     955        1071 :   std::vector<double> cv(ncv_);
+     956        3111 :   for(unsigned i=0; i<ncv_; i++)
+     957        2040 :     cv[i]=getArgument(i);
+     958             : 
+     959             : //check neighbor list
+     960        1071 :   if(nlist_)
+     961             :   {
+     962         255 :     nlist_steps_++;
+     963         255 :     if(getExchangeStep())
+     964           0 :       nlist_update_=true;
+     965             :     else
+     966             :     {
+     967         275 :       for(unsigned i=0; i<ncv_; i++)
+     968             :       {
+     969         270 :         const double diff_i=difference(i,cv[i],nlist_center_[i]);
+     970         270 :         if(diff_i*diff_i>nlist_param_[1]*nlist_dev2_[i])
+     971             :         {
+     972         250 :           nlist_update_=true;
+     973         250 :           break;
+     974             :         }
+     975             :       }
+     976             :     }
+     977         255 :     if(nlist_update_)
+     978         250 :       updateNlist(cv);
+     979             :   }
+     980             : 
+     981             : //set bias and forces
+     982        1071 :   std::vector<double> der_prob(ncv_,0);
+     983        1071 :   const double prob=getProbAndDerivatives(cv,der_prob);
+     984        1071 :   const double bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+     985             :   setBias(bias);
+     986        3111 :   for(unsigned i=0; i<ncv_; i++)
+     987        2040 :     setOutputForce(i,-kbt_*bias_prefactor_/(prob/Zed_+epsilon_)*der_prob[i]/Zed_);
+     988        1071 : }
+     989             : 
+     990             : template <class mode>
+     991        1071 : void OPESmetad<mode>::update()
+     992             : {
+     993        1071 :   if(isFirstStep_)//same in MetaD, useful for restarts?
+     994             :   {
+     995          21 :     isFirstStep_=false;
+     996          21 :     return;
+     997             :   }
+     998             : 
+     999             : //update variance if adaptive sigma
+    1000        1050 :   if(adaptive_sigma_)
+    1001             :   {
+    1002         550 :     adaptive_counter_++;
+    1003         550 :     unsigned tau=adaptive_sigma_stride_;
+    1004         550 :     if(adaptive_counter_<adaptive_sigma_stride_)
+    1005          45 :       tau=adaptive_counter_;
+    1006        1600 :     for(unsigned i=0; i<ncv_; i++)
+    1007             :     { //Welford's online algorithm for standard deviation
+    1008             :       const double cv_i=getArgument(i);
+    1009        1050 :       const double diff_i=difference(i,av_cv_[i],cv_i);
+    1010        1050 :       av_cv_[i]+=diff_i/tau; //exponentially decaying average
+    1011        1050 :       av_M2_[i]+=diff_i*difference(i,av_cv_[i],cv_i);
+    1012             :     }
+    1013         550 :     if(adaptive_counter_<adaptive_sigma_stride_ && counter_==1) //counter_>1 if restarting
+    1014             :       return; //do not apply bias before having measured sigma
+    1015             :   }
+    1016             : 
+    1017             : //do update
+    1018        1005 :   if(getStep()%stride_==0 && (excluded_region_==NULL || excluded_region_->get()==0))
+    1019             :   {
+    1020         257 :     old_KDEnorm_=KDEnorm_;
+    1021         257 :     delta_kernels_.clear();
+    1022         257 :     unsigned old_nker=kernels_.size();
+    1023             : 
+    1024             :     //get new kernel height
+    1025         257 :     double log_weight=getOutputQuantity(0)/kbt_; //first value is always the current bias
+    1026         277 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+    1027          20 :       log_weight+=extra_biases_[e]->get()/kbt_; //extra biases contribute to the weight
+    1028         257 :     double height=std::exp(log_weight);
+    1029             : 
+    1030             :     //update sum_weights_ and neff
+    1031         257 :     double sum_heights=height;
+    1032         257 :     double sum_heights2=height*height;
+    1033         257 :     if(NumWalkers_>1)
+    1034             :     {
+    1035         126 :       if(comm.Get_rank()==0)
+    1036             :       {
+    1037         126 :         multi_sim_comm.Sum(sum_heights);
+    1038         126 :         multi_sim_comm.Sum(sum_heights2);
+    1039             :       }
+    1040         126 :       comm.Bcast(sum_heights,0);
+    1041         126 :       comm.Bcast(sum_heights2,0);
+    1042             :     }
+    1043         257 :     counter_+=NumWalkers_;
+    1044         257 :     sum_weights_+=sum_heights;
+    1045         257 :     sum_weights2_+=sum_heights2;
+    1046         257 :     const double neff=std::pow(1+sum_weights_,2)/(1+sum_weights2_); //adding 1 makes it more robust at the start
+    1047         257 :     getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+    1048         257 :     getPntrToComponent("neff")->set(neff);
+    1049             :     if(mode::explore)
+    1050             :     {
+    1051          68 :       KDEnorm_=counter_;
+    1052          68 :       height=1; //plain KDE, bias reweight does not enter here
+    1053             :     }
+    1054             :     else
+    1055         189 :       KDEnorm_=sum_weights_;
+    1056             : 
+    1057             :     //if needed, rescale sigma and height
+    1058         257 :     std::vector<double> sigma=sigma0_;
+    1059         257 :     if(adaptive_sigma_)
+    1060             :     {
+    1061          93 :       const double factor=mode::explore?1:biasfactor_;
+    1062         131 :       if(counter_==1+NumWalkers_) //first time only
+    1063             :       {
+    1064          14 :         for(unsigned i=0; i<ncv_; i++)
+    1065           9 :           av_M2_[i]*=biasfactor_; //from unbiased, thus must be adjusted
+    1066          14 :         for(unsigned i=0; i<ncv_; i++)
+    1067           9 :           sigma0_[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1068           5 :         if(sigma_min_.size()==0)
+    1069             :         {
+    1070          14 :           for(unsigned i=0; i<ncv_; i++)
+    1071           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");
+    1072             :         }
+    1073             :         else
+    1074             :         {
+    1075           0 :           for(unsigned i=0; i<ncv_; i++)
+    1076           0 :             sigma0_[i]=std::max(sigma0_[i],sigma_min_[i]);
+    1077             :         }
+    1078             :       }
+    1079         388 :       for(unsigned i=0; i<ncv_; i++)
+    1080         257 :         sigma[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1081         131 :       if(sigma_min_.size()==0)
+    1082             :       {
+    1083         238 :         for(unsigned i=0; i<ncv_; i++)
+    1084             :         {
+    1085         157 :           if(sigma[i]<1e-6)
+    1086             :           {
+    1087           0 :             log.printf("+++ WARNING +++ the ADAPTIVE SIGMA is suspiciously small, you should set a safe SIGMA_MIN. 1e-6 will be used here\n");
+    1088           0 :             sigma[i]=1e-6;
+    1089           0 :             sigma_min_.resize(ncv_,1e-6);
+    1090             :           }
+    1091             :         }
+    1092             :       }
+    1093             :       else
+    1094             :       {
+    1095         150 :         for(unsigned i=0; i<ncv_; i++)
+    1096         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1097             :       }
+    1098             :     }
+    1099         257 :     if(!fixed_sigma_)
+    1100             :     {
+    1101          38 :       const double size=mode::explore?counter_:neff; //for EXPLORE neff is not relevant
+    1102         197 :       const double s_rescaling=std::pow(size*(ncv_+2.)/4.,-1./(4+ncv_));
+    1103         576 :       for(unsigned i=0; i<ncv_; i++)
+    1104         379 :         sigma[i]*=s_rescaling;
+    1105         197 :       if(sigma_min_.size()>0)
+    1106             :       {
+    1107         150 :         for(unsigned i=0; i<ncv_; i++)
+    1108         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1109             :       }
+    1110             :     }
+    1111             :     //the height should be divided by sqrt(2*pi)*sigma0_,
+    1112             :     //but this overall factor would be canceled when dividing by Zed
+    1113             :     //thus we skip it altogether, but keep any other sigma rescaling
+    1114         756 :     for(unsigned i=0; i<ncv_; i++)
+    1115         499 :       height*=(sigma0_[i]/sigma[i]);
+    1116             : 
+    1117             :     //get new kernel center
+    1118         257 :     std::vector<double> center(ncv_);
+    1119         756 :     for(unsigned i=0; i<ncv_; i++)
+    1120         499 :       center[i]=getArgument(i);
+    1121             : 
+    1122             :     //add new kernel(s)
+    1123         257 :     if(NumWalkers_==1)
+    1124         131 :       addKernel(height,center,sigma,log_weight);
+    1125             :     else
+    1126             :     {
+    1127         126 :       std::vector<double> all_height(NumWalkers_,0.0);
+    1128         126 :       std::vector<double> all_center(NumWalkers_*ncv_,0.0);
+    1129         126 :       std::vector<double> all_sigma(NumWalkers_*ncv_,0.0);
+    1130         126 :       std::vector<double> all_logweight(NumWalkers_,0.0);
+    1131         126 :       if(comm.Get_rank()==0)
+    1132             :       {
+    1133         126 :         multi_sim_comm.Allgather(height,all_height);
+    1134         126 :         multi_sim_comm.Allgather(center,all_center);
+    1135         126 :         multi_sim_comm.Allgather(sigma,all_sigma);
+    1136         126 :         multi_sim_comm.Allgather(log_weight,all_logweight);
+    1137             :       }
+    1138         126 :       comm.Bcast(all_height,0);
+    1139         126 :       comm.Bcast(all_center,0);
+    1140         126 :       comm.Bcast(all_sigma,0);
+    1141         126 :       comm.Bcast(all_logweight,0);
+    1142         126 :       if(nlist_)
+    1143             :       { //gather all the nlist_index_, so merging can be done using it
+    1144          50 :         std::vector<int> all_nlist_size(NumWalkers_);
+    1145          50 :         if(comm.Get_rank()==0)
+    1146             :         {
+    1147          50 :           all_nlist_size[walker_rank_]=nlist_index_.size();
+    1148          50 :           multi_sim_comm.Sum(all_nlist_size);
+    1149             :         }
+    1150          50 :         comm.Bcast(all_nlist_size,0);
+    1151             :         unsigned tot_size=0;
+    1152         150 :         for(unsigned w=0; w<NumWalkers_; w++)
+    1153         100 :           tot_size+=all_nlist_size[w];
+    1154          50 :         if(tot_size>0)
+    1155             :         {
+    1156          50 :           std::vector<int> disp(NumWalkers_);
+    1157         100 :           for(unsigned w=0; w<NumWalkers_-1; w++)
+    1158          50 :             disp[w+1]=disp[w]+all_nlist_size[w];
+    1159          50 :           std::vector<unsigned> all_nlist_index(tot_size);
+    1160          50 :           if(comm.Get_rank()==0)
+    1161          50 :             multi_sim_comm.Allgatherv(nlist_index_,all_nlist_index,&all_nlist_size[0],&disp[0]);
+    1162          50 :           comm.Bcast(all_nlist_index,0);
+    1163          50 :           std::set<unsigned> nlist_index_set(all_nlist_index.begin(),all_nlist_index.end()); //remove duplicates and sort
+    1164          50 :           nlist_index_.assign(nlist_index_set.begin(),nlist_index_set.end());
+    1165             :         }
+    1166             :       }
+    1167         378 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1168             :       {
+    1169         252 :         std::vector<double> center_w(all_center.begin()+ncv_*w,all_center.begin()+ncv_*(w+1));
+    1170         252 :         std::vector<double> sigma_w(all_sigma.begin()+ncv_*w,all_sigma.begin()+ncv_*(w+1));
+    1171         252 :         addKernel(all_height[w],center_w,sigma_w,all_logweight[w]);
+    1172             :       }
+    1173             :     }
+    1174         257 :     getPntrToComponent("nker")->set(kernels_.size());
+    1175         257 :     if(nlist_)
+    1176             :     {
+    1177         106 :       getPntrToComponent("nlker")->set(nlist_index_.size());
+    1178         106 :       if(nlist_pace_reset_)
+    1179          50 :         nlist_update_=true;
+    1180             :     }
+    1181             : 
+    1182             :     //update Zed_
+    1183         257 :     if(!no_Zed_)
+    1184             :     {
+    1185         197 :       double sum_uprob=0;
+    1186         197 :       const unsigned ks=kernels_.size();
+    1187         197 :       const unsigned ds=delta_kernels_.size();
+    1188         197 :       const bool few_kernels=(ks*ks<(3*ks*ds+2*ds*ds*NumParallel_+100)); //this seems reasonable, but is not rigorous...
+    1189         197 :       if(few_kernels) //really needed? Probably is almost always false
+    1190             :       {
+    1191         147 :         #pragma omp parallel num_threads(NumOMP_)
+    1192             :         {
+    1193             :           #pragma omp for reduction(+:sum_uprob) nowait
+    1194             :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1195             :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+    1196             :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+    1197             :         }
+    1198         147 :         if(NumParallel_>1)
+    1199          50 :           comm.Sum(sum_uprob);
+    1200             :       }
+    1201             :       else
+    1202             :       {
+    1203             :         // Here instead of redoing the full summation, we add only the changes, knowing that
+    1204             :         // uprob = old_uprob + delta_uprob
+    1205             :         // and we also need to consider that in the new sum there are some novel centers and some disappeared ones
+    1206          50 :         double delta_sum_uprob=0;
+    1207          50 :         if(!nlist_)
+    1208             :         {
+    1209           0 :           #pragma omp parallel num_threads(NumOMP_)
+    1210             :           {
+    1211             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1212             :             for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1213             :             {
+    1214             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1215             :               {
+    1216             :                 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
+    1217             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1218             :               }
+    1219             :             }
+    1220             :           }
+    1221             :         }
+    1222             :         else
+    1223             :         {
+    1224          50 :           #pragma omp parallel num_threads(NumOMP_)
+    1225             :           {
+    1226             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1227             :             for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1228             :             {
+    1229             :               const unsigned k=nlist_index_[nk];
+    1230             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1231             :               {
+    1232             :                 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
+    1233             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1234             :               }
+    1235             :             }
+    1236             :           }
+    1237             :         }
+    1238          50 :         if(NumParallel_>1)
+    1239           0 :           comm.Sum(delta_sum_uprob);
+    1240          50 :         #pragma omp parallel num_threads(NumOMP_)
+    1241             :         {
+    1242             :           #pragma omp for reduction(+:delta_sum_uprob)
+    1243             :           for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1244             :           {
+    1245             :             for(unsigned dd=0; dd<delta_kernels_.size(); dd++)
+    1246             :             { //now subtract the delta_uprob added before, but not needed
+    1247             :               const double sign=delta_kernels_[d].height<0?-1:1;
+    1248             :               delta_sum_uprob-=sign*evaluateKernel(delta_kernels_[dd],delta_kernels_[d].center);
+    1249             :             }
+    1250             :           }
+    1251             :         }
+    1252          50 :         sum_uprob=Zed_*old_KDEnorm_*old_nker+delta_sum_uprob;
+    1253             :       }
+    1254         197 :       Zed_=sum_uprob/KDEnorm_/kernels_.size();
+    1255         394 :       getPntrToComponent("zed")->set(Zed_);
+    1256             :     }
+    1257             : 
+    1258             :     //calculate work if requested
+    1259         257 :     if(calc_work_)
+    1260             :     {
+    1261          70 :       std::vector<double> dummy(ncv_); //derivatives are not actually needed
+    1262          70 :       const double prob=getProbAndDerivatives(center,dummy);
+    1263          70 :       const double new_bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+    1264          70 :       work_+=new_bias-getOutputQuantity(0);
+    1265         140 :       getPntrToComponent("work")->set(work_);
+    1266             :     }
+    1267             :   }
+    1268             : 
+    1269             : //dump state if requested
+    1270        1005 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+    1271          18 :     dumpStateToFile();
+    1272             : }
+    1273             : 
+    1274             : template <class mode>
+    1275        1141 : double OPESmetad<mode>::getProbAndDerivatives(const std::vector<double>& cv,std::vector<double>& der_prob)
+    1276             : {
+    1277        1141 :   double prob=0.0;
+    1278        1141 :   if(!nlist_)
+    1279             :   {
+    1280         886 :     if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1281             :     {
+    1282             :       // for performances and thread safety
+    1283         707 :       std::vector<double> dist(ncv_);
+    1284        2647 :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1285        1940 :         prob+=evaluateKernel(kernels_[k],cv,der_prob,dist);
+    1286             :     }
+    1287             :     else
+    1288             :     {
+    1289         179 :       #pragma omp parallel num_threads(NumOMP_)
+    1290             :       {
+    1291             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1292             :         // for performances and thread safety
+    1293             :         std::vector<double> dist(ncv_);
+    1294             :         #pragma omp for reduction(+:prob) nowait
+    1295             :         for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1296             :           prob+=evaluateKernel(kernels_[k],cv,omp_deriv,dist);
+    1297             :         #pragma omp critical
+    1298             :         for(unsigned i=0; i<ncv_; i++)
+    1299             :           der_prob[i]+=omp_deriv[i];
+    1300             :       }
+    1301             :     }
+    1302             :   }
+    1303             :   else
+    1304             :   {
+    1305         255 :     if(NumOMP_==1 || (unsigned)nlist_index_.size()<2*NumOMP_*NumParallel_)
+    1306             :     {
+    1307             :       // for performances and thread safety
+    1308         230 :       std::vector<double> dist(ncv_);
+    1309         660 :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1310         430 :         prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,der_prob,dist);
+    1311             :     }
+    1312             :     else
+    1313             :     {
+    1314          25 :       #pragma omp parallel num_threads(NumOMP_)
+    1315             :       {
+    1316             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1317             :         // for performances and thread safety
+    1318             :         std::vector<double> dist(ncv_);
+    1319             :         #pragma omp for reduction(+:prob) nowait
+    1320             :         for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1321             :           prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,omp_deriv,dist);
+    1322             :         #pragma omp critical
+    1323             :         for(unsigned i=0; i<ncv_; i++)
+    1324             :           der_prob[i]+=omp_deriv[i];
+    1325             :       }
+    1326             :     }
+    1327             :   }
+    1328        1141 :   if(NumParallel_>1)
+    1329             :   {
+    1330         224 :     comm.Sum(prob);
+    1331         224 :     comm.Sum(der_prob);
+    1332             :   }
+    1333             : //normalize the estimate
+    1334        1141 :   prob/=KDEnorm_;
+    1335        3311 :   for(unsigned i=0; i<ncv_; i++)
+    1336        2170 :     der_prob[i]/=KDEnorm_;
+    1337             : 
+    1338        1141 :   return prob;
+    1339             : }
+    1340             : 
+    1341             : template <class mode>
+    1342         513 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma)
+    1343             : {
+    1344             :   bool no_match=true;
+    1345         513 :   if(threshold2_!=0)
+    1346             :   {
+    1347         513 :     unsigned taker_k=getMergeableKernel(center,kernels_.size());
+    1348         513 :     if(taker_k<kernels_.size())
+    1349             :     {
+    1350             :       no_match=false;
+    1351         388 :       delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1352         776 :       mergeKernels(kernels_[taker_k],kernel(height,center,sigma));
+    1353         388 :       delta_kernels_.push_back(kernels_[taker_k]);
+    1354         388 :       if(recursive_merge_) //the overhead is worth it if it keeps low the total number of kernels
+    1355             :       {
+    1356             :         unsigned giver_k=taker_k;
+    1357         337 :         taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1358         337 :         while(taker_k<kernels_.size())
+    1359             :         {
+    1360           0 :           delta_kernels_.pop_back();
+    1361           0 :           delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1362           0 :           if(taker_k>giver_k) //saves time when erasing
+    1363             :             std::swap(taker_k,giver_k);
+    1364           0 :           mergeKernels(kernels_[taker_k],kernels_[giver_k]);
+    1365           0 :           delta_kernels_.push_back(kernels_[taker_k]);
+    1366           0 :           kernels_.erase(kernels_.begin()+giver_k);
+    1367           0 :           if(nlist_)
+    1368             :           {
+    1369             :             unsigned giver_nk=0;
+    1370             :             bool found_giver=false;
+    1371           0 :             for(unsigned nk=0; nk<nlist_index_.size(); nk++)
+    1372             :             {
+    1373           0 :               if(found_giver)
+    1374           0 :                 nlist_index_[nk]--; //all the indexes shift due to erase
+    1375           0 :               if(nlist_index_[nk]==giver_k)
+    1376             :               {
+    1377             :                 giver_nk=nk;
+    1378             :                 found_giver=true;
+    1379             :               }
+    1380             :             }
+    1381             :             plumed_dbg_massert(found_giver,"problem with merging and NLIST");
+    1382           0 :             nlist_index_.erase(nlist_index_.begin()+giver_nk);
+    1383             :           }
+    1384             :           giver_k=taker_k;
+    1385           0 :           taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1386             :         }
+    1387             :       }
+    1388             :     }
+    1389             :   }
+    1390             :   if(no_match)
+    1391             :   {
+    1392         125 :     kernels_.emplace_back(height,center,sigma);
+    1393         125 :     delta_kernels_.emplace_back(height,center,sigma);
+    1394         125 :     if(nlist_)
+    1395          12 :       nlist_index_.push_back(kernels_.size()-1);
+    1396             :   }
+    1397         513 : }
+    1398             : 
+    1399             : template <class mode>
+    1400         383 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma,const double logweight)
+    1401             : {
+    1402         383 :   addKernel(height,center,sigma);
+    1403             : //write to file
+    1404         383 :   kernelsOfile_.printField("time",getTime());
+    1405        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1406         751 :     kernelsOfile_.printField(getPntrToArgument(i),center[i]);
+    1407        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1408        1502 :     kernelsOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    1409         383 :   kernelsOfile_.printField("height",height);
+    1410         383 :   kernelsOfile_.printField("logweight",logweight);
+    1411         383 :   kernelsOfile_.printField();
+    1412         383 : }
+    1413             : 
+    1414             : template <class mode>
+    1415         850 : unsigned OPESmetad<mode>::getMergeableKernel(const std::vector<double>& giver_center,const unsigned giver_k)
+    1416             : { //returns kernels_.size() if no match is found
+    1417         850 :   unsigned min_k=kernels_.size();
+    1418         850 :   double min_norm2=threshold2_;
+    1419         850 :   if(!nlist_)
+    1420             :   {
+    1421         550 :     #pragma omp parallel num_threads(NumOMP_)
+    1422             :     {
+    1423             :       unsigned min_k_omp = min_k;
+    1424             :       double min_norm2_omp = threshold2_;
+    1425             :       #pragma omp for nowait
+    1426             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1427             :       {
+    1428             :         if(k==giver_k) //a kernel should not be merged with itself
+    1429             :           continue;
+    1430             :         double norm2=0;
+    1431             :         for(unsigned i=0; i<ncv_; i++)
+    1432             :         {
+    1433             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1434             :           norm2+=dist_i*dist_i;
+    1435             :           if(norm2>=min_norm2_omp)
+    1436             :             break;
+    1437             :         }
+    1438             :         if(norm2<min_norm2_omp)
+    1439             :         {
+    1440             :           min_norm2_omp=norm2;
+    1441             :           min_k_omp=k;
+    1442             :         }
+    1443             :       }
+    1444             :       #pragma omp critical
+    1445             :       {
+    1446             :         if(min_norm2_omp < min_norm2)
+    1447             :         {
+    1448             :           min_norm2 = min_norm2_omp;
+    1449             :           min_k = min_k_omp;
+    1450             :         }
+    1451             :       }
+    1452             :     }
+    1453             :   }
+    1454             :   else
+    1455             :   {
+    1456         300 :     #pragma omp parallel num_threads(NumOMP_)
+    1457             :     {
+    1458             :       unsigned min_k_omp = min_k;
+    1459             :       double min_norm2_omp = threshold2_;
+    1460             :       #pragma omp for nowait
+    1461             :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1462             :       {
+    1463             :         const unsigned k=nlist_index_[nk];
+    1464             :         if(k==giver_k) //a kernel should not be merged with itself
+    1465             :           continue;
+    1466             :         double norm2=0;
+    1467             :         for(unsigned i=0; i<ncv_; i++)
+    1468             :         {
+    1469             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1470             :           norm2+=dist_i*dist_i;
+    1471             :           if(norm2>=min_norm2)
+    1472             :             break;
+    1473             :         }
+    1474             :         if(norm2<min_norm2_omp)
+    1475             :         {
+    1476             :           min_norm2_omp=norm2;
+    1477             :           min_k_omp=k;
+    1478             :         }
+    1479             :       }
+    1480             :       #pragma omp critical
+    1481             :       {
+    1482             :         if(min_norm2_omp < min_norm2)
+    1483             :         {
+    1484             :           min_norm2 = min_norm2_omp;
+    1485             :           min_k = min_k_omp;
+    1486             :         }
+    1487             :       }
+    1488             :     }
+    1489             :   }
+    1490         850 :   if(NumParallel_>1)
+    1491             :   {
+    1492         134 :     std::vector<double> all_min_norm2(NumParallel_);
+    1493         134 :     std::vector<unsigned> all_min_k(NumParallel_);
+    1494         134 :     comm.Allgather(min_norm2,all_min_norm2);
+    1495         134 :     comm.Allgather(min_k,all_min_k);
+    1496             :     const unsigned best=std::distance(std::begin(all_min_norm2),std::min_element(std::begin(all_min_norm2),std::end(all_min_norm2)));
+    1497         134 :     min_k=all_min_k[best];
+    1498             :   }
+    1499         850 :   return min_k;
+    1500             : }
+    1501             : 
+    1502             : template <class mode>
+    1503         250 : void OPESmetad<mode>::updateNlist(const std::vector<double>& new_center)
+    1504             : {
+    1505         250 :   if(kernels_.size()==0) //no need to check for neighbors
+    1506           6 :     return;
+    1507             : 
+    1508         244 :   nlist_center_=new_center;
+    1509         244 :   nlist_index_.clear();
+    1510             :   //first we gather all the nlist_index
+    1511         244 :   if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1512             :   {
+    1513         198 :     for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1514             :     {
+    1515             :       double norm2_k=0;
+    1516         444 :       for(unsigned i=0; i<ncv_; i++)
+    1517             :       {
+    1518         296 :         const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1519         296 :         norm2_k+=dist_ik*dist_ik;
+    1520             :       }
+    1521         148 :       if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1522         104 :         nlist_index_.push_back(k);
+    1523             :     }
+    1524             :   }
+    1525             :   else
+    1526             :   {
+    1527         194 :     #pragma omp parallel num_threads(NumOMP_)
+    1528             :     {
+    1529             :       std::vector<unsigned> private_nlist_index;
+    1530             :       #pragma omp for nowait
+    1531             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1532             :       {
+    1533             :         double norm2_k=0;
+    1534             :         for(unsigned i=0; i<ncv_; i++)
+    1535             :         {
+    1536             :           const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1537             :           norm2_k+=dist_ik*dist_ik;
+    1538             :         }
+    1539             :         if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1540             :           private_nlist_index.push_back(k);
+    1541             :       }
+    1542             :       #pragma omp critical
+    1543             :       nlist_index_.insert(nlist_index_.end(),private_nlist_index.begin(),private_nlist_index.end());
+    1544             :     }
+    1545         194 :     if(recursive_merge_)
+    1546         194 :       std::sort(nlist_index_.begin(),nlist_index_.end());
+    1547             :   }
+    1548         244 :   if(NumParallel_>1)
+    1549             :   {
+    1550         100 :     std::vector<int> all_nlist_size(NumParallel_);
+    1551         100 :     all_nlist_size[rank_]=nlist_index_.size();
+    1552         100 :     comm.Sum(all_nlist_size);
+    1553             :     unsigned tot_size=0;
+    1554         300 :     for(unsigned r=0; r<NumParallel_; r++)
+    1555         200 :       tot_size+=all_nlist_size[r];
+    1556         100 :     if(tot_size>0)
+    1557             :     {
+    1558         100 :       std::vector<int> disp(NumParallel_);
+    1559         200 :       for(unsigned r=0; r<NumParallel_-1; r++)
+    1560         100 :         disp[r+1]=disp[r]+all_nlist_size[r];
+    1561         100 :       std::vector<unsigned> local_nlist_index=nlist_index_;
+    1562         100 :       nlist_index_.resize(tot_size);
+    1563         100 :       comm.Allgatherv(local_nlist_index,nlist_index_,&all_nlist_size[0],&disp[0]);
+    1564         100 :       if(recursive_merge_)
+    1565         100 :         std::sort(nlist_index_.begin(),nlist_index_.end());
+    1566             :     }
+    1567             :   }
+    1568             :   //calculate the square deviation
+    1569         244 :   std::vector<double> dev2(ncv_,0.);
+    1570         773 :   for(unsigned k=rank_; k<nlist_index_.size(); k+=NumParallel_)
+    1571             :   {
+    1572        1587 :     for(unsigned i=0; i<ncv_; i++)
+    1573             :     {
+    1574        1058 :       const double diff_ik=difference(i,nlist_center_[i],kernels_[nlist_index_[k]].center[i]);
+    1575        1058 :       dev2[i]+=diff_ik*diff_ik;
+    1576             :     }
+    1577             :   }
+    1578         244 :   if(NumParallel_>1)
+    1579         100 :     comm.Sum(dev2);
+    1580         732 :   for(unsigned i=0; i<ncv_; i++)
+    1581             :   {
+    1582         488 :     if(dev2[i]==0) //e.g. if nlist_index_.size()==0
+    1583          56 :       nlist_dev2_[i]=std::pow(kernels_.back().sigma[i],2);
+    1584             :     else
+    1585         432 :       nlist_dev2_[i]=dev2[i]/nlist_index_.size();
+    1586             :   }
+    1587         244 :   getPntrToComponent("nlker")->set(nlist_index_.size());
+    1588         244 :   getPntrToComponent("nlsteps")->set(nlist_steps_);
+    1589         244 :   nlist_steps_=0;
+    1590         244 :   nlist_update_=false;
+    1591             : }
+    1592             : 
+    1593             : template <class mode>
+    1594          18 : void OPESmetad<mode>::dumpStateToFile()
+    1595             : {
+    1596             : //gather adaptive sigma info if needed
+    1597             : //doing this while writing to file can lead to misterious slowdowns
+    1598             :   std::vector<double> all_sigma0;
+    1599             :   std::vector<double> all_av_cv;
+    1600             :   std::vector<double> all_av_M2;
+    1601          18 :   if(adaptive_sigma_ && NumWalkers_>1)
+    1602             :   {
+    1603          16 :     all_sigma0.resize(NumWalkers_*ncv_);
+    1604          16 :     all_av_cv.resize(NumWalkers_*ncv_);
+    1605          16 :     all_av_M2.resize(NumWalkers_*ncv_);
+    1606          16 :     if(comm.Get_rank()==0)
+    1607             :     {
+    1608          16 :       multi_sim_comm.Allgather(sigma0_,all_sigma0);
+    1609          16 :       multi_sim_comm.Allgather(av_cv_,all_av_cv);
+    1610          16 :       multi_sim_comm.Allgather(av_M2_,all_av_M2);
+    1611             :     }
+    1612          16 :     comm.Bcast(all_sigma0,0);
+    1613          16 :     comm.Bcast(all_av_cv,0);
+    1614          16 :     comm.Bcast(all_av_M2,0);
+    1615             :   }
+    1616             : 
+    1617             : //rewrite header or rewind file
+    1618          18 :   if(storeOldStates_)
+    1619          16 :     stateOfile_.clearFields();
+    1620           2 :   else if(walker_rank_==0)
+    1621           2 :     stateOfile_.rewind();
+    1622             : //define fields
+    1623          18 :   stateOfile_.addConstantField("action");
+    1624          18 :   stateOfile_.addConstantField("biasfactor");
+    1625          18 :   stateOfile_.addConstantField("epsilon");
+    1626          18 :   stateOfile_.addConstantField("kernel_cutoff");
+    1627          18 :   stateOfile_.addConstantField("compression_threshold");
+    1628          18 :   stateOfile_.addConstantField("zed");
+    1629          18 :   stateOfile_.addConstantField("sum_weights");
+    1630          18 :   stateOfile_.addConstantField("sum_weights2");
+    1631          18 :   stateOfile_.addConstantField("counter");
+    1632          18 :   if(adaptive_sigma_)
+    1633             :   {
+    1634          18 :     stateOfile_.addConstantField("adaptive_counter");
+    1635          18 :     if(NumWalkers_==1)
+    1636             :     {
+    1637           6 :       for(unsigned i=0; i<ncv_; i++)
+    1638             :       {
+    1639           8 :         stateOfile_.addConstantField("sigma0_"+getPntrToArgument(i)->getName());
+    1640           8 :         stateOfile_.addConstantField("av_cv_"+getPntrToArgument(i)->getName());
+    1641           8 :         stateOfile_.addConstantField("av_M2_"+getPntrToArgument(i)->getName());
+    1642             :       }
+    1643             :     }
+    1644             :     else
+    1645             :     {
+    1646          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1647          96 :         for(unsigned i=0; i<ncv_; i++)
+    1648             :         {
+    1649         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1650          64 :           stateOfile_.addConstantField("sigma0_"+arg_iw);
+    1651          64 :           stateOfile_.addConstantField("av_cv_"+arg_iw);
+    1652         128 :           stateOfile_.addConstantField("av_M2_"+arg_iw);
+    1653             :         }
+    1654             :     }
+    1655             :   }
+    1656             : //print fields
+    1657          54 :   for(unsigned i=0; i<ncv_; i++) //periodicity of CVs
+    1658          36 :     stateOfile_.setupPrintValue(getPntrToArgument(i));
+    1659          36 :   stateOfile_.printField("action",getName()+"_state");
+    1660          18 :   stateOfile_.printField("biasfactor",biasfactor_);
+    1661          18 :   stateOfile_.printField("epsilon",epsilon_);
+    1662          18 :   stateOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+    1663          18 :   stateOfile_.printField("compression_threshold",sqrt(threshold2_));
+    1664          18 :   stateOfile_.printField("zed",Zed_);
+    1665          18 :   stateOfile_.printField("sum_weights",sum_weights_);
+    1666          18 :   stateOfile_.printField("sum_weights2",sum_weights2_);
+    1667          18 :   stateOfile_.printField("counter",counter_);
+    1668          18 :   if(adaptive_sigma_)
+    1669             :   {
+    1670          18 :     stateOfile_.printField("adaptive_counter",adaptive_counter_);
+    1671          18 :     if(NumWalkers_==1)
+    1672             :     {
+    1673           6 :       for(unsigned i=0; i<ncv_; i++)
+    1674             :       {
+    1675           8 :         stateOfile_.printField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+    1676           8 :         stateOfile_.printField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+    1677           8 :         stateOfile_.printField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+    1678             :       }
+    1679             :     }
+    1680             :     else
+    1681             :     {
+    1682          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1683          96 :         for(unsigned i=0; i<ncv_; i++)
+    1684             :         {
+    1685         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1686          64 :           stateOfile_.printField("sigma0_"+arg_iw,all_sigma0[w*ncv_+i]);
+    1687          64 :           stateOfile_.printField("av_cv_"+arg_iw,all_av_cv[w*ncv_+i]);
+    1688         128 :           stateOfile_.printField("av_M2_"+arg_iw,all_av_M2[w*ncv_+i]);
+    1689             :         }
+    1690             :     }
+    1691             :   }
+    1692             : //print kernels
+    1693          82 :   for(unsigned k=0; k<kernels_.size(); k++)
+    1694             :   {
+    1695          64 :     stateOfile_.printField("time",getTime()); //this is not very usefull
+    1696         192 :     for(unsigned i=0; i<ncv_; i++)
+    1697         128 :       stateOfile_.printField(getPntrToArgument(i),kernels_[k].center[i]);
+    1698         192 :     for(unsigned i=0; i<ncv_; i++)
+    1699         256 :       stateOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),kernels_[k].sigma[i]);
+    1700          64 :     stateOfile_.printField("height",kernels_[k].height);
+    1701          64 :     stateOfile_.printField();
+    1702             :   }
+    1703             : //make sure file is written even if small
+    1704          18 :   if(!storeOldStates_)
+    1705           2 :     stateOfile_.flush();
+    1706          18 : }
+    1707             : 
+    1708             : template <class mode>
+    1709        5969 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x) const
+    1710             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1711             :   double norm2=0;
+    1712       13923 :   for(unsigned i=0; i<ncv_; i++)
+    1713             :   {
+    1714       10288 :     const double dist_i=difference(i,G.center[i],x[i])/G.sigma[i];
+    1715       10288 :     norm2+=dist_i*dist_i;
+    1716       10288 :     if(norm2>=cutoff2_)
+    1717             :       return 0;
+    1718             :   }
+    1719        3635 :   return G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1720             : }
+    1721             : 
+    1722             : template <class mode>
+    1723        3364 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x, std::vector<double>& acc_der, std::vector<double>& dist)
+    1724             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1725             :   double norm2=0;
+    1726        7483 :   for(unsigned i=0; i<ncv_; i++)
+    1727             :   {
+    1728        5578 :     dist[i]=difference(i,G.center[i],x[i])/G.sigma[i];
+    1729        5578 :     norm2+=dist[i]*dist[i];
+    1730        5578 :     if(norm2>=cutoff2_)
+    1731             :       return 0;
+    1732             :   }
+    1733        1905 :   const double val=G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1734        5576 :   for(unsigned i=0; i<ncv_; i++)
+    1735        3671 :     acc_der[i]-=dist[i]/G.sigma[i]*val; //NB: we accumulate the derivative into der
+    1736             :   return val;
+    1737             : }
+    1738             : 
+    1739             : template <class mode>
+    1740         388 : inline void OPESmetad<mode>::mergeKernels(kernel& k1,const kernel& k2)
+    1741             : {
+    1742         388 :   const double h=k1.height+k2.height;
+    1743        1159 :   for(unsigned i=0; i<k1.center.size(); i++)
+    1744             :   {
+    1745         771 :     const bool isPeriodic_i=getPntrToArgument(i)->isPeriodic();
+    1746         771 :     if(isPeriodic_i)
+    1747         771 :       k1.center[i]=k2.center[i]+difference(i,k2.center[i],k1.center[i]); //fix PBC
+    1748         771 :     const double c_i=(k1.height*k1.center[i]+k2.height*k2.center[i])/h;
+    1749         771 :     const double ss_k1_part=k1.height*(k1.sigma[i]*k1.sigma[i]+k1.center[i]*k1.center[i]);
+    1750         771 :     const double ss_k2_part=k2.height*(k2.sigma[i]*k2.sigma[i]+k2.center[i]*k2.center[i]);
+    1751         771 :     const double ss_i=(ss_k1_part+ss_k2_part)/h-c_i*c_i;
+    1752         771 :     if(isPeriodic_i)
+    1753         771 :       k1.center[i]=bringBackInPbc(i,c_i);
+    1754             :     else
+    1755           0 :       k1.center[i]=c_i;
+    1756         771 :     k1.sigma[i]=sqrt(ss_i);
+    1757             :   }
+    1758         388 :   k1.height=h;
+    1759         388 : }
+    1760             : 
+    1761             : }
+    1762             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-f.html b/coverage/opes/index-sort-f.html new file mode 100644 index 0000000000..952d16eb35 --- /dev/null +++ b/coverage/opes/index-sort-f.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2161224996.1 %
Date:2024-05-27 13:05: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
ECVmultiThermal.cpp +
95.6%95.6%
+
95.6 %108 / 11392.3 %12 / 13
ECVlinear.cpp +
95.8%95.8%
+
95.8 %115 / 12092.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 %431 / 44393.8 %15 / 16
OPESmetad.cpp +
95.7%95.7%
+
95.7 %795 / 83197.1 %33 / 34
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-l.html b/coverage/opes/index-sort-l.html new file mode 100644 index 0000000000..64a24f7c70 --- /dev/null +++ b/coverage/opes/index-sort-l.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2161224996.1 %
Date:2024-05-27 13:05: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.7%95.7%
+
95.7 %795 / 83197.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 %431 / 44393.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.16
+
+ + + diff --git a/coverage/opes/index.html b/coverage/opes/index.html new file mode 100644 index 0000000000..3c3effa89c --- /dev/null +++ b/coverage/opes/index.html @@ -0,0 +1,183 @@ + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2161224996.1 %
Date:2024-05-27 13:05: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 %431 / 44393.8 %15 / 16
OPESmetad.cpp +
95.7%95.7%
+
95.7 %795 / 83197.1 %33 / 34
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html b/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html new file mode 100644 index 0000000000..58b0a96173 --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.func.html b/coverage/pamm/HBPammHydrogens.cpp.func.html new file mode 100644 index 0000000000..2c109f7e4b --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe606createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_127HBPammHydrogensRegisterMe60D2Ev4168
_ZN4PLMD4pamm15HBPammHydrogens10isPeriodicEv0
_ZN4PLMD4pamm15HBPammHydrogens16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm15HBPammHydrogensC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogensC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.gcov.html b/coverage/pamm/HBPammHydrogens.cpp.gcov.html new file mode 100644 index 0000000000..d8e2eaa771 --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(HBPammHydrogens,"HBPAMM_SH")
+      61             : 
+      62           4 : void HBPammHydrogens::registerKeywords( Keywords& keys ) {
+      63           4 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      64           8 :   keys.add("atoms-1","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list.");
+      65           8 :   keys.add("atoms-1","SITES","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+      66             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+      67             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      68             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      69             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      70             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      71           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+      72             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      73             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      74             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      75             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      76           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+      77             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      78             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      79             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      80             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      81           8 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      82           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      83           8 :   keys.reset_style("CLUSTERS","compulsory");
+      84             :   // Use actionWithDistributionKeywords
+      85          16 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      86          16 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      87          16 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("SUM");
+      88           4 : }
+      89             : 
+      90           2 : HBPammHydrogens::HBPammHydrogens(const ActionOptions&ao):
+      91             :   Action(ao),
+      92           2 :   MultiColvarBase(ao)
+      93             : {
+      94             :   // Read in the atoms
+      95           2 :   usespecies=true; weightHasDerivatives=false;
+      96             :   // Read in hydrogen atom indicees
+      97           4 :   std::vector<AtomNumber> all_atoms; parseMultiColvarAtomList("HYDROGENS",-1,all_atoms);
+      98           2 :   if( atom_lab.size()==0 ) error("no hydrogens specified in input file");
+      99             :   // Now create a task list - one task per hydrogen
+     100         136 :   unsigned nH = atom_lab.size(); for(unsigned i=0; i<nH; ++i) addTaskToList(i);
+     101             :   // Read in other atoms in hydrogen bond
+     102           4 :   ablocks.resize(1); parseMultiColvarAtomList("SITES",-1,all_atoms);
+     103           2 :   if( atom_lab.size()>nH ) {
+     104           2 :     block1upper=atom_lab.size() - nH + 1; block2lower=0; ablocks[0].resize( atom_lab.size() - nH );
+     105          69 :     for(unsigned i=nH; i<atom_lab.size(); ++i) ablocks[0][i-nH]=i;
+     106             :   } else {
+     107           0 :     parseMultiColvarAtomList("DONORS",-1,all_atoms);
+     108           0 :     block1upper=block2lower=atom_lab.size() - nH + 1;
+     109           0 :     for(unsigned i=nH; i<atom_lab.size(); ++i) ablocks[0].push_back(i);
+     110           0 :     parseMultiColvarAtomList("ACCEPTORS",-1,all_atoms);
+     111           0 :     if( atom_lab.size()>(block1upper+nH-1) || (block1upper-1)>0 ) error("no acceptor donor pairs in input specified therefore no hydrogen bonds");
+     112           0 :     for(unsigned i=nH+block2lower-1; i<atom_lab.size(); ++i) ablocks[0].push_back(i);
+     113             :   }
+     114           2 :   setupMultiColvarBase( all_atoms );
+     115             : 
+     116           4 :   double reg; parse("REGULARISE",reg);
+     117           2 :   unsigned nnode_t=mybasemulticolvars.size(); if( nnode_t==0 ) nnode_t=1;
+     118           0 :   if( nnode_t==1 ) {
+     119           4 :     std::string errormsg, desc; parse("CLUSTERS",desc);
+     120             :     hbpamm_obj.resize(1,1);
+     121           2 :     hbpamm_obj(0,0).setup(desc, reg, this, errormsg );
+     122           2 :     if( errormsg.length()>0 ) error( errormsg );
+     123             :   } else {
+     124             :     unsigned nr=nnode_t, nc=nnode_t;
+     125             :     hbpamm_obj.resize( nr, nc );
+     126           0 :     for(unsigned i=0; i<nr; ++i) {
+     127             :       // Retrieve the base number
+     128             :       unsigned ibase;
+     129           0 :       if( nc<10 ) {
+     130           0 :         ibase=(i+1)*10;
+     131           0 :       } else if ( nc<100 ) {
+     132           0 :         ibase=(i+1)*100;
+     133             :       } else {
+     134           0 :         error("wow this is an error I never would have expected");
+     135             :       }
+     136             : 
+     137           0 :       for(unsigned j=i; j<nc; ++j) {
+     138           0 :         std::string errormsg, desc; parseNumbered("CLUSTERS",ibase+j+1,desc);
+     139           0 :         if( i==j ) {
+     140           0 :           hbpamm_obj(i,j).setup( desc, reg, this, errormsg );
+     141           0 :           if( errormsg.length()>0 ) error( errormsg );
+     142             :         } else {
+     143           0 :           hbpamm_obj(i,j).setup( desc, reg, this, errormsg );
+     144           0 :           hbpamm_obj(j,i).setup( desc, reg, this, errormsg );
+     145           0 :           if( errormsg.length()>0 ) error( errormsg );
+     146             :         }
+     147             :       }
+     148             :     }
+     149             :   }
+     150             : 
+     151             :   // Set the link cell cutoff
+     152           2 :   double sfmax=0;
+     153           4 :   for(unsigned i=0; i<hbpamm_obj.ncols(); ++i) {
+     154           4 :     for(unsigned j=i; j<hbpamm_obj.nrows(); ++j) {
+     155           2 :       double rcut=hbpamm_obj(i,j).get_cutoff();
+     156           2 :       if( rcut>sfmax ) { sfmax=rcut; }
+     157             :     }
+     158             :   }
+     159           2 :   setLinkCellCutoff( sfmax );
+     160           2 :   rcut2 = sfmax*sfmax;
+     161             : 
+     162             :   // Setup the multicolvar base
+     163           2 :   setupMultiColvarBase( all_atoms );
+     164             :   // And setup the ActionWithVessel
+     165           2 :   checkRead();
+     166           2 : }
+     167             : 
+     168         134 : double HBPammHydrogens::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     169             :   double value=0, md_da ;
+     170             : 
+     171             :   // Calculate the coordination number
+     172        8344 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     173        8210 :     if( i>block1upper ) continue;
+     174      532552 :     for(unsigned j=1; j<myatoms.getNumberOfAtoms(); ++j) {
+     175      524342 :       if( i==j || j<block2lower ) continue ;
+     176             :       // Get the base colvar numbers
+     177      516132 :       unsigned dno = atom_lab[myatoms.getIndex(i)].first;
+     178      516132 :       unsigned ano = atom_lab[myatoms.getIndex(j)].first;
+     179      516132 :       Vector d_da=getSeparation( myatoms.getPosition(i), myatoms.getPosition(j) );
+     180     1032264 :       if ( (md_da=d_da[0]*d_da[0])<rcut2 &&
+     181      516132 :            (md_da+=d_da[1]*d_da[1])<rcut2 &&
+     182      412196 :            (md_da+=d_da[2]*d_da[2])<rcut2) value += hbpamm_obj(dno,ano).evaluate( i, j, 0, d_da, sqrt(md_da), myatoms );
+     183             :     }
+     184             :   }
+     185             : 
+     186         134 :   return value;
+     187             : }
+     188             : 
+     189             : }
+     190             : }
+     191             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..f77a4d2181 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func.html b/coverage/pamm/HBPammMatrix.cpp.func.html new file mode 100644 index 0000000000..95e8456f36 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe616createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_124HBPammMatrixRegisterMe61D2Ev4168
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.gcov.html b/coverage/pamm/HBPammMatrix.cpp.gcov.html new file mode 100644 index 0000000000..d5fc54ef89 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(HBPammMatrix,"HBPAMM_MATRIX")
+      62             : 
+      63           4 : void HBPammMatrix::registerKeywords( Keywords& keys ) {
+      64           4 :   adjmat::AdjacencyMatrixBase::registerKeywords( keys );
+      65           8 :   keys.add("atoms-1","SITES","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+      66             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+      67             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      68             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      69             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      70             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      71           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+      72             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      73             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      74             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      75             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      76           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+      77             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      78             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      79             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      80             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      81           8 :   keys.add("atoms","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list, "
+      82             :            "an index range or by using a \\ref GROUP");
+      83           8 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      84           8 :   keys.reset_style("CLUSTERS","compulsory"); keys.use("SUM");
+      85           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      86           4 : }
+      87             : 
+      88             : 
+      89           2 : HBPammMatrix::HBPammMatrix(const ActionOptions& ao):
+      90             :   Action(ao),
+      91           2 :   AdjacencyMatrixBase(ao)
+      92             : {
+      93           4 :   readMaxThreeSpeciesMatrix("SITES", "DONORS", "ACCEPTORS", "HYDROGENS", false );
+      94             :   // Retrieve dimensions of hbonding matrix and resize
+      95           2 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+      96           2 :   myhb_objs.resize( nrows, ncols );
+      97             :   // Read in the regularisation parameter
+      98           2 :   parse("REGULARISE",regulariser);
+      99             :   // Read in the switching functions
+     100           2 :   parseConnectionDescriptions("CLUSTERS",false,ndonor_types);
+     101             : 
+     102             :   // Find cutoff for link cells
+     103           2 :   double sfmax=0;
+     104           4 :   for(unsigned i=0; i<myhb_objs.ncols(); ++i) {
+     105           4 :     for(unsigned j=i; j<myhb_objs.nrows(); ++j) {
+     106           2 :       double rcut=myhb_objs(i,j).get_cutoff();
+     107           2 :       if( rcut>sfmax ) { sfmax=rcut; }
+     108             :     }
+     109             :   }
+     110           2 :   setLinkCellCutoff( sfmax );
+     111           2 : }
+     112             : 
+     113           2 : void HBPammMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     114           2 :   log.printf("  reading definition of hydrogen bond between between type %u and %u from file %s \n",i,j,desc[0].c_str() );
+     115           2 :   plumed_assert( desc.size()==1 ); std::string errors;
+     116           2 :   if( i==j ) {
+     117           2 :     myhb_objs( i, j ).setup( desc[0], regulariser, this, errors );
+     118             :   } else {
+     119           0 :     myhb_objs( i, j ).setup( desc[0], regulariser, this, errors );
+     120           0 :     myhb_objs( j, i ).setup( desc[0], regulariser, this, errors );
+     121             :   }
+     122           2 :   if( errors.length()>0 ) error( errors );
+     123           2 : }
+     124             : 
+     125        4038 : double HBPammMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     126        4038 :   Vector d_da = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double md_da = d_da.modulo(); // acceptor - donor
+     127             : 
+     128             :   // Get the base colvar numbers
+     129             :   unsigned ano, dno = getBaseColvarNumber( myatoms.getIndex(0) );
+     130        4038 :   if( ndonor_types==0 ) ano = getBaseColvarNumber( myatoms.getIndex(1) );
+     131           0 :   else ano = getBaseColvarNumber( myatoms.getIndex(1) ) - ndonor_types;
+     132             : 
+     133             :   double value=0;
+     134        4038 :   if( myatoms.getNumberOfAtoms()>3 ) {
+     135             :     const HBPammObject& myhb=myhb_objs(dno,ano);
+     136      520170 :     for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     137      516132 :       value+=myhb.evaluate( 0, 1, i, d_da, md_da, myatoms );
+     138             :     }
+     139             :   } else {
+     140             :     plumed_dbg_assert( myatoms.getNumberOfAtoms()==3 );
+     141           0 :     value=myhb_objs(dno,ano).evaluate( 0, 1, 2, d_da, md_da, myatoms );
+     142             :   }
+     143             : 
+     144        4038 :   return value;
+     145             : }
+     146             : 
+     147             : }
+     148             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.func-sort-c.html b/coverage/pamm/HBPammObject.cpp.func-sort-c.html new file mode 100644 index 0000000000..29e946a220 --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.func.html b/coverage/pamm/HBPammObject.cpp.func.html new file mode 100644 index 0000000000..919a7987ae --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.gcov.html b/coverage/pamm/HBPammObject.cpp.gcov.html new file mode 100644 index 0000000000..99ae38363d --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.gcov.html @@ -0,0 +1,152 @@ + + + + + + + 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-05-27 13:05: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          44 :     double rcut = mypamm.getKernelCenter(k)[2] + mypamm.getKernelSupport(k)[2];
+      39          44 :     if( rcut>sfmax ) { sfmax=rcut; }
+      40             :   }
+      41           4 :   return sfmax;
+      42             : }
+      43             : 
+      44      787016 : double HBPammObject::evaluate( const unsigned& dno, const unsigned& ano, const unsigned& hno,
+      45             :                                const Vector& d_da, const double& md_da, multicolvar::AtomValuePack& myatoms ) const {
+      46      787016 :   Vector d_dh = mymulti->getSeparation( myatoms.getPosition(dno), myatoms.getPosition(hno) ); double md_dh = d_dh.modulo(); // hydrogen - donor
+      47      787016 :   Vector d_ah = mymulti->getSeparation( myatoms.getPosition(ano), myatoms.getPosition(hno) ); double md_ah = d_ah.modulo(); // hydrogen - acceptor
+      48             : 
+      49             :   // Create some vectors locally for pamm evaluation
+      50      787016 :   std::vector<double> invals( 3 ), outvals( mypamm.getNumberOfKernels() );
+      51      787016 :   std::vector<std:: vector<double> > der( mypamm.getNumberOfKernels() );
+      52     9444192 :   for(unsigned i=0; i<der.size(); ++i) der[i].resize(3);
+      53             : 
+      54             :   // Evaluate the pamm object
+      55      787016 :   invals[0]=md_dh - md_ah; invals[1]=md_dh+md_ah; invals[2]=md_da;
+      56      787016 :   mypamm.evaluate( invals, outvals, der );
+      57             : 
+      58      787016 :   if( !mymulti->doNotCalculateDerivatives() ) {
+      59          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][0])/md_dh)*d_dh, myatoms );
+      60          72 :     mymulti->addAtomDerivatives( 1, ano, ((+der[0][0])/md_ah)*d_ah, myatoms  );
+      61          72 :     mymulti->addAtomDerivatives( 1, hno, ((+der[0][0])/md_dh)*d_dh - ((+der[0][0])/md_ah)*d_ah, myatoms );
+      62          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][0])/md_dh)*Tensor(d_dh,d_dh) - ((-der[0][0])/md_ah)*Tensor(d_ah,d_ah) );
+      63          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][1])/md_dh)*d_dh, myatoms );
+      64          72 :     mymulti->addAtomDerivatives( 1, ano, ((-der[0][1])/md_ah)*d_ah, myatoms );
+      65          72 :     mymulti->addAtomDerivatives( 1, hno, ((+der[0][1])/md_dh)*d_dh + ((+der[0][1])/md_ah)*d_ah, myatoms );
+      66          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][1])/md_dh)*Tensor(d_dh,d_dh) + ((-der[0][1])/md_ah)*Tensor(d_ah,d_ah) );
+      67          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][2])/md_da)*d_da, myatoms );
+      68          72 :     mymulti->addAtomDerivatives( 1, ano, ((+der[0][2])/md_da)*d_da, myatoms );
+      69          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][2])/md_da)*Tensor(d_da,d_da) );
+      70             :   }
+      71      787016 :   return outvals[0];
+      72             : 
+      73      787016 : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.func-sort-c.html b/coverage/pamm/HBPammObject.h.func-sort-c.html new file mode 100644 index 0000000000..42c9bce97d --- /dev/null +++ b/coverage/pamm/HBPammObject.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.func.html b/coverage/pamm/HBPammObject.h.func.html new file mode 100644 index 0000000000..ece5452775 --- /dev/null +++ b/coverage/pamm/HBPammObject.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.gcov.html b/coverage/pamm/HBPammObject.h.gcov.html new file mode 100644 index 0000000000..275a128bb0 --- /dev/null +++ b/coverage/pamm/HBPammObject.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + 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-05-27 13:05: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=nullptr;
+      38             : public:
+      39             : /// Setup the HBPamm object
+      40             :   void setup( const std::string& filename, const double& reg, multicolvar::MultiColvarBase* mybase, std::string& errorstr );
+      41             : /// Get the cutoff to use throughout
+      42             :   double get_cutoff() const ;
+      43             : /// Evaluate the HBPamm Object
+      44             :   double evaluate( const unsigned& dno, const unsigned& ano, const unsigned& hno,
+      45             :                    const Vector& d_da, const double& md_da, multicolvar::AtomValuePack& myatoms ) const ;
+      46             : };
+      47             : 
+      48             : }
+      49             : }
+      50             : 
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func-sort-c.html b/coverage/pamm/PAMM.cpp.func-sort-c.html new file mode 100644 index 0000000000..dfdcf2cc9d --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func.html b/coverage/pamm/PAMM.cpp.func.html new file mode 100644 index 0000000000..6e26252786 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe1326createERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132C2Ev4168
_ZN4PLMD4pamm12_GLOBAL__N_117PAMMRegisterMe132D2Ev4168
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZN4PLMD4pamm4PAMM14getCentralAtomEv0
_ZN4PLMD4pamm4PAMM15calculateWeightERNS_11multicolvar13AtomValuePackE0
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.gcov.html b/coverage/pamm/PAMM.cpp.gcov.html new file mode 100644 index 0000000000..debf369e0c --- /dev/null +++ b/coverage/pamm/PAMM.cpp.gcov.html @@ -0,0 +1,328 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(PAMM,"PAMM")
+     133             : 
+     134           4 : void PAMM::registerKeywords( Keywords& keys ) {
+     135           4 :   MultiColvarBase::registerKeywords( keys );
+     136           8 :   keys.add("compulsory","DATA","the multicolvars from which the pamm coordinates are calculated");
+     137           8 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the clusters");
+     138           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+     139          20 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+     140          28 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+     141           4 :   keys.setComponentsIntroduction("When the label of this action is used as the input for a second you are not referring to a scalar quantity as you are in "
+     142             :                                  "regular collective variables.  The label is used to reference the full set of quantities calculated by "
+     143             :                                  "the action.  This is usual when using \\ref multicolvarfunction. Generally when doing this the set of PAMM variables "
+     144             :                                  "will be referenced using the DATA keyword rather than ARG.\n\n"
+     145             :                                  "This Action can be used to calculate the following scalar quantities directly from the underlying set of PAMM variables. "
+     146             :                                  "These quantities are calculated by employing the keywords listed below and they can be referenced elsewhere in the input "
+     147             :                                  "file by using this Action's label followed by a dot and the name of the quantity.  The particular PAMM variable that should "
+     148             :                                  "be averaged in a MEAN command or transformed by a switching function in a LESS_THAN command is specified using the COMPONENT "
+     149             :                                  "keyword. COMPONENT=1 refers to the PAMM variable in which the first kernel in your input file is on the numerator, COMPONENT=2 refers to "
+     150             :                                  "PAMM variable in which the second kernel in the input file is on the numerator and so on.  The same quantity can be calculated "
+     151             :                                  "multiple times for different PAMM components by a single PAMM action.  In this case the relevant keyword must appear multiple "
+     152             :                                  "times on the input line followed by a numerical identifier i.e. MEAN1, MEAN2, ...  The quantities calculated when multiple "
+     153             :                                  "MEAN commands appear on the input line can be reference elsewhere in the input file by using the name of the quantity followed "
+     154             :                                  "followed by a numerical identifier e.g. <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 etc.  Alternatively, you can "
+     155             :                                  "customize the labels of the quantities by using the LABEL keyword in the description of the keyword.");
+     156           4 :   keys.remove("ALL_INPUT_SAME_TYPE");
+     157           4 : }
+     158             : 
+     159           2 : PAMM::PAMM(const ActionOptions& ao):
+     160             :   Action(ao),
+     161           2 :   MultiColvarBase(ao)
+     162             : {
+     163             :   // This builds the lists
+     164           2 :   buildSets();
+     165             :   // Check for reasonable input
+     166           5 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     167           3 :     if( getBaseMultiColvar(i)->getNumberOfQuantities()!=2 ) error("cannot use PAMM with " + getBaseMultiColvar(i)->getName() );
+     168             :   }
+     169             : 
+     170           2 :   bool mixed=getBaseMultiColvar(0)->isPeriodic();
+     171           2 :   std::vector<bool> pbc( getNumberOfBaseMultiColvars() );
+     172           2 :   std::vector<std::string> valnames( getNumberOfBaseMultiColvars() );
+     173           2 :   std::vector<std::string> min( getNumberOfBaseMultiColvars() ), max( getNumberOfBaseMultiColvars() );
+     174           5 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     175           3 :     if( getBaseMultiColvar(i)->isPeriodic()!=mixed ) warning("mixing of periodic and aperiodic base variables in pamm is untested");
+     176           3 :     pbc[i]=getBaseMultiColvar(i)->isPeriodic();
+     177           3 :     if( pbc[i] ) getBaseMultiColvar(i)->retrieveDomain( min[i], max[i] );
+     178           3 :     valnames[i]=getBaseMultiColvar(i)->getLabel();
+     179             :   }
+     180             : 
+     181           4 :   double regulariser; parse("REGULARISE",regulariser);
+     182           2 :   std::string errorstr, filename; parse("CLUSTERS",filename);
+     183           2 :   mypamm.setup( filename, regulariser, valnames, pbc, min, max, errorstr );
+     184           2 :   if( errorstr.length()>0 ) error( errorstr );
+     185           4 : }
+     186             : 
+     187          86 : unsigned PAMM::getNumberOfQuantities() const {
+     188          86 :   return 1 + mypamm.getNumberOfKernels();
+     189             : }
+     190             : 
+     191           0 : void PAMM::calculateWeight( multicolvar::AtomValuePack& myatoms ) {
+     192             :   unsigned nvars = getNumberOfBaseMultiColvars();
+     193             :   // Weight of point is average of weights of input colvars?
+     194           0 :   std::vector<double> tval(2); double ww=0;
+     195           0 :   for(unsigned i=0; i<nvars; ++i) {
+     196           0 :     getInputData( i, false, myatoms, tval ); ww+=tval[0];
+     197             :   }
+     198           0 :   myatoms.setValue( 0, ww / static_cast<double>( nvars ) );
+     199             : 
+     200           0 :   if(!doNotCalculateDerivatives() ) {
+     201           0 :     double pref = 1.0 / static_cast<double>( nvars );
+     202           0 :     for(unsigned ivar=0; ivar<nvars; ++ivar) {
+     203             :       // Get the values of derivatives
+     204           0 :       const MultiValue& myder=getInputDerivatives( ivar, false, myatoms );
+     205           0 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     206           0 :         unsigned jder=myder.getActiveIndex(j);
+     207           0 :         myatoms.addDerivative( 0, jder, pref*myder.getDerivative( 0, jder ) );
+     208             :       }
+     209             :     }
+     210             :   }
+     211           0 : }
+     212             : 
+     213          28 : double PAMM::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     214             :   unsigned nvars = getNumberOfBaseMultiColvars();
+     215          28 :   std::vector<std::vector<double> > tderiv( mypamm.getNumberOfKernels() );
+     216         174 :   for(unsigned i=0; i<tderiv.size(); ++i) tderiv[i].resize( nvars );
+     217          28 :   std::vector<double> tval(2), invals( nvars ), vals( mypamm.getNumberOfKernels() );
+     218             : 
+     219          74 :   for(unsigned i=0; i<nvars; ++i) {
+     220          46 :     getInputData( i, false, myatoms, tval ); invals[i]=tval[1];
+     221             :   }
+     222          28 :   mypamm.evaluate( invals, vals, tderiv );
+     223             : 
+     224             :   // Now set all values other than the first one
+     225             :   // This is because of some peverse choices in multicolvar
+     226         146 :   for(unsigned i=1; i<vals.size(); ++i) myatoms.setValue( 1+i, vals[i] );
+     227             : 
+     228          28 :   if( !doNotCalculateDerivatives() ) {
+     229          28 :     std::vector<double> mypref( 1 + vals.size() );
+     230          74 :     for(unsigned ivar=0; ivar<nvars; ++ivar) {
+     231             :       // Get the values of the derivatives
+     232          46 :       MultiValue& myder = getInputDerivatives( ivar, false, myatoms );
+     233             :       // And calculate the derivatives
+     234         318 :       for(unsigned i=0; i<vals.size(); ++i) mypref[1+i] = tderiv[i][ivar];
+     235             :       // This is basically doing the chain rule to get the final derivatives
+     236          46 :       splitInputDerivatives( 1, 1, 1+vals.size(), ivar, mypref, myder, myatoms );
+     237             :       // And clear the derivatives
+     238          46 :       myder.clearAll();
+     239             :     }
+     240             :   }
+     241             : 
+     242          56 :   return vals[0];
+     243          28 : }
+     244             : 
+     245           0 : Vector PAMM::getCentralAtom() {
+     246             :   // Who knows how this should work
+     247           0 :   plumed_error();
+     248             :   // return Vector(1.0,0.0,0.0);
+     249             : }
+     250             : 
+     251             : }
+     252             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.func-sort-c.html b/coverage/pamm/PammObject.cpp.func-sort-c.html new file mode 100644 index 0000000000..f7358747f2 --- /dev/null +++ b/coverage/pamm/PammObject.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.func.html b/coverage/pamm/PammObject.cpp.func.html new file mode 100644 index 0000000000..1dfa9364c8 --- /dev/null +++ b/coverage/pamm/PammObject.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.gcov.html b/coverage/pamm/PammObject.cpp.gcov.html new file mode 100644 index 0000000000..6c05ad8579 --- /dev/null +++ b/coverage/pamm/PammObject.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.func-sort-c.html b/coverage/pamm/PammObject.h.func-sort-c.html new file mode 100644 index 0000000000..16638535df --- /dev/null +++ b/coverage/pamm/PammObject.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.func.html b/coverage/pamm/PammObject.h.func.html new file mode 100644 index 0000000000..44d4925480 --- /dev/null +++ b/coverage/pamm/PammObject.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.gcov.html b/coverage/pamm/PammObject.h.gcov.html new file mode 100644 index 0000000000..7d7df6921f --- /dev/null +++ b/coverage/pamm/PammObject.h.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/index-sort-f.html b/coverage/pamm/index-sort-f.html new file mode 100644 index 0000000000..f28030bb3c --- /dev/null +++ b/coverage/pamm/index-sort-f.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21526481.4 %
Date:2024-05-27 13:05: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
PammObject.h +
100.0%
+
100.0 %3 / 3-0 / 0
HBPammObject.h +
100.0%
+
100.0 %1 / 1-0 / 0
HBPammObject.cpp +
100.0%
+
100.0 %32 / 32100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index-sort-l.html b/coverage/pamm/index-sort-l.html new file mode 100644 index 0000000000..a28a935c8d --- /dev/null +++ b/coverage/pamm/index-sort-l.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21526481.4 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/pamm/index.html b/coverage/pamm/index.html new file mode 100644 index 0000000000..43f517065a --- /dev/null +++ b/coverage/pamm/index.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21526481.4 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func-sort-c.html b/coverage/piv/PIV.cpp.func-sort-c.html new file mode 100644 index 0000000000..f0aa4580a0 --- /dev/null +++ b/coverage/piv/PIV.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe2346createERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe234C2Ev4168
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe234D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func.html b/coverage/piv/PIV.cpp.func.html new file mode 100644 index 0000000000..df848e05af --- /dev/null +++ b/coverage/piv/PIV.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe2346createERKNS_13ActionOptionsE12
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe234C2Ev4168
_ZN4PLMD3piv12_GLOBAL__N_116PIVRegisterMe234D2Ev4168
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.gcov.html b/coverage/piv/PIV.cpp.gcov.html new file mode 100644 index 0000000000..5b60e59396 --- /dev/null +++ b/coverage/piv/PIV.cpp.gcov.html @@ -0,0 +1,1338 @@ + + + + + + + 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:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2017 of Pipolo Silvio and Fabio Pietrucci.
+       3             : 
+       4             : The piv module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The piv module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : #include "colvar/Colvar.h"
+      18             : #include "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             : #include "core/ActionSet.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <iostream>
+      31             : 
+      32             : using namespace std;
+      33             : 
+      34             : namespace PLMD
+      35             : {
+      36             : namespace piv
+      37             : {
+      38             : 
+      39             : //+PLUMEDOC PIVMOD_COLVAR PIV
+      40             : /*
+      41             : Calculates the PIV-distance.
+      42             : 
+      43             : PIV distance is the squared Cartesian distance between the PIV \cite gallet2013structural \cite pipolo2017navigating
+      44             : associated to the configuration of the system during the dynamics and a reference configuration provided
+      45             : as input (PDB file format).
+      46             : PIV can be used together with \ref FUNCPATHMSD to define a path in the PIV space.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following example calculates PIV-distances from three reference configurations in Ref1.pdb, Ref2.pdb and Ref3.pdb
+      51             : and prints the results in a file named colvar.
+      52             : 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.
+      53             : SFACTOR is a scaling factor that multiplies the contribution to the PIV-distance given by the single PIV block.
+      54             : NLIST sets the use of neighbor lists for calculating atom-atom distances.
+      55             : The SWITCH keyword specifies the parameters of the switching function that transforms atom-atom distances.
+      56             : SORT=1 means that the PIV block elements are sorted (SORT=0 no sorting.)
+      57             : Values for SORT, SFACTOR and the neighbor list parameters have to be specified for each block.
+      58             : 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).
+      59             : The sorting operation within each PIV block is performed using the counting sort algorithm, PRECISION specifies the size of the counting array.
+      60             : 
+      61             : \plumedfile
+      62             : PIV ...
+      63             : LABEL=Pivd1
+      64             : PRECISION=1000
+      65             : NLIST
+      66             : REF_FILE=Ref1.pdb
+      67             : PIVATOMS=3
+      68             : ATOMTYPES=A,B,C
+      69             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      70             : SORT=1,1,1,1,1,1
+      71             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      72             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      73             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      74             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      75             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      76             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      77             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      78             : NL_STRIDE=10,10,10,10,10,10
+      79             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      80             : ... PIV
+      81             : PIV ...
+      82             : LABEL=Pivd2
+      83             : PRECISION=1000
+      84             : NLIST
+      85             : REF_FILE=Ref2.pdb
+      86             : PIVATOMS=3
+      87             : ATOMTYPES=A,B,C
+      88             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      89             : SORT=1,1,1,1,1,1
+      90             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      91             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      92             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      93             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      94             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      95             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      96             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      97             : NL_STRIDE=10,10,10,10,10,10
+      98             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      99             : ... PIV
+     100             : PIV ...
+     101             : LABEL=Pivd3
+     102             : PRECISION=1000
+     103             : NLIST
+     104             : REF_FILE=Ref3.pdb
+     105             : PIVATOMS=3
+     106             : ATOMTYPES=A,B,C
+     107             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+     108             : SORT=1,1,1,1,1,1
+     109             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     110             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     111             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+     112             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+     113             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+     114             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+     115             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+     116             : NL_STRIDE=10,10,10,10,10,10
+     117             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     118             : ... PIV
+     119             : 
+     120             : PRINT ARG=Pivd1,Pivd2,Pivd3 FILE=colvar
+     121             : \endplumedfile
+     122             : 
+     123             : WARNING:
+     124             : 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:
+     125             : 
+     126             : \verbatim
+     127             : CRYST1   31.028   36.957   23.143  89.93  92.31  89.99 P 1           1
+     128             : ATOM      1  OW1 wate    1      15.630  19.750   1.520  1.00  0.00
+     129             : \endverbatim
+     130             : 
+     131             : 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.
+     132             : 
+     133             : The following example calculates the PIV-distances from two reference configurations Ref1.pdb and Ref2.pdb
+     134             : and uses PIV-distances to define a Path Collective Variable (\ref FUNCPATHMSD) with only two references (Ref1.pdb and Ref2.pdb).
+     135             : 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.
+     136             : 
+     137             : \plumedfile
+     138             : PIV ...
+     139             : LABEL=c1
+     140             : PRECISION=1000
+     141             : VOLUME=12.15
+     142             : NLIST
+     143             : REF_FILE=Ref1.pdb
+     144             : PIVATOMS=2
+     145             : ATOMTYPES=A,B
+     146             : ONLYDIRECT
+     147             : SFACTOR=1.0,0.2
+     148             : SORT=1,1
+     149             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     150             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     151             : NL_CUTOFF=1.2,1.2
+     152             : NL_STRIDE=10,10
+     153             : NL_SKIN=0.1,0.1
+     154             : ... PIV
+     155             : PIV ...
+     156             : LABEL=c2
+     157             : PRECISION=1000
+     158             : VOLUME=12.15
+     159             : NLIST
+     160             : REF_FILE=Ref2.pdb
+     161             : PIVATOMS=2
+     162             : ATOMTYPES=A,B
+     163             : ONLYDIRECT
+     164             : SFACTOR=1.0,0.2
+     165             : SORT=1,1
+     166             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     167             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     168             : NL_CUTOFF=1.2,1.2
+     169             : NL_STRIDE=10,10
+     170             : NL_SKIN=0.1,0.1
+     171             : ... PIV
+     172             : 
+     173             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     174             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     175             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     176             : \endplumedfile
+     177             : 
+     178             : When using PIV please cite \cite pipolo2017navigating .
+     179             : 
+     180             : (See also \ref PRINT)
+     181             : 
+     182             : */
+     183             : //+ENDPLUMEDOC
+     184             : 
+     185             : class PIV      : public Colvar
+     186             : {
+     187             : private:
+     188             :   bool pbc, serial, timer;
+     189             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     190             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     191             :   int updatePIV;
+     192             :   size_t Nprec;
+     193             :   unsigned Natm,Nlist,NLsize;
+     194             :   double Fvol,Vol0,m_PIVdistance;
+     195             :   std::string ref_file;
+     196             :   std::unique_ptr<NeighborList> nlall;
+     197             :   std::vector<SwitchingFunction> sfs;
+     198             :   std::vector<std:: vector<double> > rPIV;
+     199             :   std::vector<double> scaling,r00;
+     200             :   std::vector<double> nl_skin;
+     201             :   std::vector<double> fmass;
+     202             :   std::vector<bool> dosort;
+     203             :   std::vector<Vector> compos;
+     204             :   std::vector<string> sw;
+     205             :   std::vector<std::unique_ptr<NeighborList>> nl;
+     206             :   std::vector<std::unique_ptr<NeighborList>> nlcom;
+     207             :   std::vector<Vector> m_deriv;
+     208             :   Tensor m_virial;
+     209             :   bool Svol,cross,direct,doneigh,test,CompDer,com;
+     210             : 
+     211             :   /// Local structure, used to store data that should be
+     212             :   /// shared across multiple PIV instances
+     213           6 :   struct SharedData {
+     214             :     int prev_stp=-1;
+     215             :     int init_stp=1;
+     216             :     std:: vector<std:: vector<Vector> > prev_pos;
+     217             :     std:: vector<std:: vector<double> > cPIV;
+     218             :     std:: vector<std:: vector<int> > Atom0;
+     219             :     std:: vector<std:: vector<int> > Atom1;
+     220             :   };
+     221             :   /// Owning pointer. Will only be allocated by the first PIV instance
+     222             :   std::unique_ptr<SharedData> sharedData_unique;
+     223             :   /// Raw pointer. Will have the same value for all PIV instances
+     224             :   SharedData* sharedData=nullptr;
+     225             : 
+     226             : public:
+     227             :   static void registerKeywords( Keywords& keys );
+     228             :   explicit PIV(const ActionOptions&);
+     229             :   // active methods:
+     230             :   virtual void calculate();
+     231           0 :   void checkFieldsAllowed() {}
+     232             : };
+     233             : 
+     234       12528 : PLUMED_REGISTER_ACTION(PIV,"PIV")
+     235             : 
+     236          14 : void PIV::registerKeywords( Keywords& keys )
+     237             : {
+     238          14 :   Colvar::registerKeywords( keys );
+     239          28 :   keys.add("numbered","SWITCH","The switching functions parameter."
+     240             :            "You should specify a Switching function for all PIV blocks."
+     241             :            "Details of the various switching "
+     242             :            "functions you can use are provided on \\ref switchingfunction.");
+     243          28 :   keys.add("compulsory","PRECISION","the precision for approximating reals with integers in sorting.");
+     244          28 :   keys.add("compulsory","REF_FILE","PDB file name that contains the \\f$i\\f$th reference structure.");
+     245          28 :   keys.add("compulsory","PIVATOMS","Number of atoms to use for PIV.");
+     246          28 :   keys.add("compulsory","SORT","Whether to sort or not the PIV block.");
+     247          28 :   keys.add("compulsory","ATOMTYPES","The atom types to use for PIV.");
+     248          28 :   keys.add("optional","SFACTOR","Scale the PIV-distance by such block-specific factor");
+     249          28 :   keys.add("optional","VOLUME","Scale atom-atom distances by the cubic root of the cell volume. The input volume is used to scale the R_0 value of the switching function. ");
+     250          28 :   keys.add("optional","UPDATEPIV","Frequency (in steps) at which the PIV is updated.");
+     251          28 :   keys.addFlag("TEST",false,"Print the actual and reference PIV and exit");
+     252          28 :   keys.addFlag("COM",false,"Use centers of mass of groups of atoms instead of atoms as specified in the Pdb file");
+     253          28 :   keys.addFlag("ONLYCROSS",false,"Use only cross-terms (A-B, A-C, B-C, ...) in PIV");
+     254          28 :   keys.addFlag("ONLYDIRECT",false,"Use only direct-terms (A-A, B-B, C-C, ...) in PIV");
+     255          28 :   keys.addFlag("DERIVATIVES",false,"Activate the calculation of the PIV for every class (needed for numerical derivatives).");
+     256          28 :   keys.addFlag("NLIST",false,"Use a neighbor list for distance calculations.");
+     257          28 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     258          28 :   keys.addFlag("TIMER",false,"Perform timing analysis on heavy loops.");
+     259          28 :   keys.add("optional","NL_CUTOFF","Neighbor lists cutoff.");
+     260          28 :   keys.add("optional","NL_STRIDE","Update neighbor lists every NL_STRIDE steps.");
+     261          28 :   keys.add("optional","NL_SKIN","The maximum atom displacement tolerated for the neighbor lists update.");
+     262          28 :   keys.reset_style("SWITCH","compulsory");
+     263          14 : }
+     264             : 
+     265          12 : PIV::PIV(const ActionOptions&ao):
+     266             :   PLUMED_COLVAR_INIT(ao),
+     267          12 :   pbc(true),
+     268          12 :   serial(false),
+     269          12 :   timer(false),
+     270          12 :   updatePIV(1),
+     271          12 :   Nprec(1000),
+     272          12 :   Natm(1),
+     273          12 :   Nlist(1),
+     274          12 :   NLsize(1),
+     275          12 :   Fvol(1.),
+     276          12 :   Vol0(0.),
+     277          12 :   m_PIVdistance(0.),
+     278          12 :   rPIV(std:: vector<std:: vector<double> >(Nlist)),
+     279          12 :   scaling(std:: vector<double>(Nlist)),
+     280          12 :   r00(std:: vector<double>(Nlist)),
+     281          12 :   nl_skin(std:: vector<double>(Nlist)),
+     282          12 :   fmass(std:: vector<double>(Nlist)),
+     283          12 :   dosort(std:: vector<bool>(Nlist)),
+     284          12 :   compos(std:: vector<Vector>(NLsize)),
+     285          12 :   sw(std:: vector<string>(Nlist)),
+     286          12 :   nl(Nlist),
+     287          12 :   nlcom(NLsize),
+     288          12 :   m_deriv(std:: vector<Vector>(1)),
+     289          12 :   Svol(false),
+     290          12 :   cross(true),
+     291          12 :   direct(true),
+     292          12 :   doneigh(false),
+     293          12 :   test(false),
+     294          12 :   CompDer(false),
+     295          24 :   com(false)
+     296             : {
+     297          12 :   log << "Starting PIV Constructor\n";
+     298             : 
+     299             :   {
+     300             :     // look for another PIV instance previously allocated
+     301          12 :     auto* previous=plumed.getActionSet().selectLatest<PIV*>(this);
+     302             : 
+     303             :     // Uncommenting the following line, it is possible to force
+     304             :     // a separate object per instance of the PIB object.
+     305             :     // Results are unaffected, but performance is worse.
+     306             :     // I think this is the expected behavior. GB
+     307             :     // previous=nullptr;
+     308             : 
+     309          12 :     if(!previous) {
+     310             :       // if not found, allocate the shared data struct
+     311          12 :       sharedData_unique=Tools::make_unique<SharedData>();
+     312             :       // then set the raw pointer
+     313           6 :       sharedData=sharedData_unique.get();
+     314             :     } else {
+     315             :       // if found, use the previous raw pointer
+     316           6 :       sharedData=previous->sharedData;
+     317           6 :       log << "(a previous PIV action was found)\n";
+     318             :     }
+     319             :   }
+     320             : 
+     321             :   // Precision on the real-to-integer transformation for the sorting
+     322          12 :   parse("PRECISION",Nprec);
+     323          12 :   if(Nprec<2) error("Precision must be => 2");
+     324             : 
+     325             :   // PBC
+     326          12 :   bool nopbc=!pbc;
+     327          12 :   parseFlag("NOPBC",nopbc);
+     328          12 :   pbc=!nopbc;
+     329          12 :   if(pbc) {
+     330          12 :     log << "Using Periodic Boundary Conditions\n";
+     331             :   } else  {
+     332           0 :     log << "Isolated System (NO PBC)\n";
+     333             :   }
+     334             : 
+     335             :   // SERIAL/PARALLEL
+     336          12 :   parseFlag("SERIAL",serial);
+     337          12 :   if(serial) {
+     338           0 :     log << "Serial PIV construction\n";
+     339             :   } else     {
+     340          12 :     log << "Parallel PIV construction\n";
+     341             :   }
+     342             : 
+     343             :   // Derivatives
+     344          12 :   parseFlag("DERIVATIVES",CompDer);
+     345          12 :   if(CompDer) log << "Computing Derivatives\n";
+     346             : 
+     347             :   // Timing
+     348          12 :   parseFlag("TIMER",timer);
+     349          12 :   if(timer) {
+     350           1 :     log << "Timing analysis\n";
+     351           1 :     stopwatch.start();
+     352           1 :     stopwatch.pause();
+     353             :   }
+     354             : 
+     355             :   // Test
+     356          12 :   parseFlag("TEST",test);
+     357             : 
+     358             :   // UPDATEPIV
+     359          24 :   if(keywords.exists("UPDATEPIV")) {
+     360          24 :     parse("UPDATEPIV",updatePIV);
+     361             :   }
+     362             : 
+     363             :   // Test
+     364          12 :   parseFlag("COM",com);
+     365          12 :   if(com) log << "Building PIV using COMs\n";
+     366             : 
+     367             :   // Volume Scaling
+     368          12 :   parse("VOLUME",Vol0);
+     369          12 :   if (Vol0>0) {
+     370          12 :     Svol=true;
+     371             :   }
+     372             : 
+     373             :   // PIV direct and cross blocks
+     374          12 :   bool oc=false,od=false;
+     375          12 :   parseFlag("ONLYCROSS",oc);
+     376          12 :   parseFlag("ONLYDIRECT",od);
+     377          12 :   if (oc&&od) {
+     378           0 :     error("ONLYCROSS and ONLYDIRECT are incompatible options!");
+     379             :   }
+     380          12 :   if(oc) {
+     381           4 :     direct=false;
+     382           4 :     log << "Using only CROSS-PIV blocks\n";
+     383             :   }
+     384          12 :   if(od) {
+     385           4 :     cross=false;
+     386           4 :     log << "Using only DIRECT-PIV blocks\n";
+     387             :   }
+     388             : 
+     389             :   // Atoms for PIV
+     390          12 :   parse("PIVATOMS",Natm);
+     391          12 :   std:: vector<string> atype(Natm);
+     392          12 :   parseVector("ATOMTYPES",atype);
+     393             :   //if(atype.size()!=getNumberOfArguments() && atype.size()!=0) error("not enough values for ATOMTYPES");
+     394             : 
+     395             :   // Reference PDB file
+     396          12 :   parse("REF_FILE",ref_file);
+     397          12 :   PDB mypdb;
+     398          12 :   FILE* fp=fopen(ref_file.c_str(),"r");
+     399          12 :   if (fp!=NULL) {
+     400          12 :     log<<"Opening PDB file with reference frame: "<<ref_file.c_str()<<"\n";
+     401          24 :     mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength());
+     402          12 :     fclose (fp);
+     403             :   } else {
+     404           0 :     error("Error in reference PDB file");
+     405             :   }
+     406             : 
+     407             :   // Build COM/Atom lists of AtomNumbers (this might be done in PBC.cpp)
+     408             :   // Atomlist or Plist used to build pair lists
+     409          12 :   std:: vector<std:: vector<AtomNumber> > Plist(Natm);
+     410             :   // Atomlist used to build list of atoms for each COM
+     411          12 :   std:: vector<std:: vector<AtomNumber> > comatm(1);
+     412             :   // NLsize is the number of atoms in the pdb cell
+     413          12 :   NLsize=mypdb.getAtomNumbers().size();
+     414             :   // In the following P stands for Point (either an Atom or a COM)
+     415             :   unsigned resnum=0;
+     416             :   // Presind (array size: number of residues) contains the contains the residue number
+     417             :   //   this is because the residue numbers may not always be ordered from 1 to resnum
+     418             :   std:: vector<unsigned> Presind;
+     419             :   // Build Presind
+     420       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     421       19392 :     unsigned rind=mypdb.getResidueNumber(mypdb.getAtomNumbers()[i]);
+     422             :     bool oldres=false;
+     423     7705008 :     for (unsigned j=0; j<Presind.size(); j++) {
+     424     7685616 :       if(rind==Presind[j]) {
+     425             :         oldres=true;
+     426             :       }
+     427             :     }
+     428       19392 :     if(!oldres) {
+     429        4848 :       Presind.push_back(rind);
+     430             :     }
+     431             :   }
+     432          12 :   resnum=Presind.size();
+     433             : 
+     434             :   // Pind0 is the atom/COM used in Nlists (for COM Pind0 is the first atom in the pdb belonging to that COM)
+     435             :   unsigned Pind0size;
+     436          12 :   if(com) {
+     437             :     Pind0size=resnum;
+     438             :   } else {
+     439          12 :     Pind0size=NLsize;
+     440             :   }
+     441          12 :   std:: vector<unsigned> Pind0(Pind0size);
+     442             :   // If COM resize important arrays
+     443          12 :   comatm.resize(NLsize);
+     444          12 :   if(com) {
+     445           0 :     nlcom.resize(NLsize);
+     446           0 :     compos.resize(NLsize);
+     447           0 :     fmass.resize(NLsize,0.);
+     448             :   }
+     449          12 :   log << "Total COM/Atoms: " << Natm*resnum << " \n";
+     450             :   // Build lists of Atoms/COMs for NLists
+     451             :   //   comatm filled also for non_COM calculation for analysis purposes
+     452          36 :   for (unsigned j=0; j<Natm; j++) {
+     453             :     unsigned oind;
+     454       38808 :     for (unsigned i=0; i<Pind0.size(); i++) {
+     455       38784 :       Pind0[i]=0;
+     456             :     }
+     457       38808 :     for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     458             :       // Residue/Atom AtomNumber: used to build NL for COMS/Atoms pairs.
+     459       38784 :       AtomNumber anum=mypdb.getAtomNumbers()[i];
+     460             :       // ResidueName/Atomname associated to atom
+     461       38784 :       string rname=mypdb.getResidueName(anum);
+     462       38784 :       string aname=mypdb.getAtomName(anum);
+     463             :       // Index associated to residue/atom: used to separate COM-lists
+     464       38784 :       unsigned rind=mypdb.getResidueNumber(anum);
+     465             :       unsigned aind=anum.index();
+     466             :       // This builds lists for NL
+     467             :       string Pname;
+     468             :       unsigned Pind;
+     469       38784 :       if(com) {
+     470             :         Pname=rname;
+     471           0 :         for(unsigned l=0; l<resnum; l++) {
+     472           0 :           if(rind==Presind[l]) {
+     473             :             Pind=l;
+     474             :           }
+     475             :         }
+     476             :       } else {
+     477             :         Pname=aname;
+     478             :         Pind=aind;
+     479             :       }
+     480       38784 :       if(Pname==atype[j]) {
+     481       14544 :         if(Pind0[Pind]==0) {
+     482             :           // adding the atomnumber to the atom/COM list for pairs
+     483       14544 :           Plist[j].push_back(anum);
+     484       14544 :           Pind0[Pind]=aind+1;
+     485             :           oind=Pind;
+     486             :         }
+     487             :         // adding the atomnumber to list of atoms for every COM/Atoms
+     488       14544 :         comatm[Pind0[Pind]-1].push_back(anum);
+     489             :       }
+     490             :     }
+     491             :     // Output Lists
+     492          24 :     log << "  Groups of type  " << j << ": " << Plist[j].size() << " \n";
+     493             :     string gname;
+     494             :     unsigned gsize;
+     495          24 :     if(com) {
+     496           0 :       gname=mypdb.getResidueName(comatm[Pind0[oind]-1][0]);
+     497           0 :       gsize=comatm[Pind0[oind]-1].size();
+     498             :     } else {
+     499          48 :       gname=mypdb.getAtomName(comatm[Pind0[oind]-1][0]);
+     500             :       gsize=1;
+     501             :     }
+     502          24 :     log.printf("    %6s %3s %13s %10i %6s\n", "type  ", gname.c_str(),"   containing ",gsize," atoms");
+     503             :   }
+     504             : 
+     505             :   // This is to build the list with all the atoms
+     506             :   std:: vector<AtomNumber> listall;
+     507       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     508       19392 :     listall.push_back(mypdb.getAtomNumbers()[i]);
+     509             :   }
+     510             : 
+     511             :   // PIV blocks and Neighbour Lists
+     512          12 :   Nlist=0;
+     513             :   // Direct adds the A-A ad B-B blocks (N)
+     514          12 :   if(direct) {
+     515           8 :     Nlist=Nlist+unsigned(Natm);
+     516             :   }
+     517             :   // Cross adds the A-B blocks (N*(N-1)/2)
+     518          12 :   if(cross) {
+     519           8 :     Nlist=Nlist+unsigned(double(Natm*(Natm-1))/2.);
+     520             :   }
+     521             :   // Resize vectors according to Nlist
+     522          12 :   rPIV.resize(Nlist);
+     523             : 
+     524             :   // PIV scaled option
+     525          12 :   scaling.resize(Nlist);
+     526          36 :   for(unsigned j=0; j<Nlist; j++) {
+     527          24 :     scaling[j]=1.;
+     528             :   }
+     529          24 :   if(keywords.exists("SFACTOR")) {
+     530          24 :     parseVector("SFACTOR",scaling);
+     531             :     //if(scaling.size()!=getNumberOfArguments() && scaling.size()!=0) error("not enough values for SFACTOR");
+     532             :   }
+     533             :   // Neighbour Lists option
+     534          12 :   parseFlag("NLIST",doneigh);
+     535          12 :   nl.resize(Nlist);
+     536          12 :   nl_skin.resize(Nlist);
+     537          12 :   if(doneigh) {
+     538          12 :     std:: vector<double> nl_cut(Nlist,0.);
+     539          12 :     std:: vector<int> nl_st(Nlist,0);
+     540          12 :     parseVector("NL_CUTOFF",nl_cut);
+     541             :     //if(nl_cut.size()!=getNumberOfArguments() && nl_cut.size()!=0) error("not enough values for NL_CUTOFF");
+     542          12 :     parseVector("NL_STRIDE",nl_st);
+     543             :     //if(nl_st.size()!=getNumberOfArguments() && nl_st.size()!=0) error("not enough values for NL_STRIDE");
+     544          12 :     parseVector("NL_SKIN",nl_skin);
+     545             :     //if(nl_skin.size()!=getNumberOfArguments() && nl_skin.size()!=0) error("not enough values for NL_SKIN");
+     546          36 :     for (unsigned j=0; j<Nlist; j++) {
+     547          24 :       if(nl_cut[j]<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     548          24 :       if(nl_st[j]<=0) error("NL_STRIDE should be explicitly specified and positive");
+     549          24 :       if(nl_skin[j]<=0.) error("NL_SKIN should be explicitly specified and positive");
+     550          24 :       nl_cut[j]=nl_cut[j]+nl_skin[j];
+     551             :     }
+     552          12 :     log << "Creating Neighbor Lists \n";
+     553             :     // WARNING: is nl_cut meaningful here?
+     554          24 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     555          12 :     if(com) {
+     556             :       //Build lists of Atoms for every COM
+     557           0 :       for (unsigned i=0; i<compos.size(); i++) {
+     558             :         // WARNING: is nl_cut meaningful here?
+     559           0 :         nlcom[i] = Tools::make_unique<NeighborList>(comatm[i],true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     560             :       }
+     561             :     }
+     562             :     unsigned ncnt=0;
+     563             :     // Direct blocks AA, BB, CC, ...
+     564          12 :     if(direct) {
+     565          24 :       for (unsigned j=0; j<Natm; j++) {
+     566          16 :         nl[ncnt]= Tools::make_unique<NeighborList>(Plist[j],true,pbc,getPbc(),comm,nl_cut[j],nl_st[j]);
+     567          16 :         ncnt+=1;
+     568             :       }
+     569             :     }
+     570             :     // Cross blocks AB, AC, BC, ...
+     571          12 :     if(cross) {
+     572          24 :       for (unsigned j=0; j<Natm; j++) {
+     573          24 :         for (unsigned i=j+1; i<Natm; i++) {
+     574          16 :           nl[ncnt]= Tools::make_unique<NeighborList>(Plist[i],Plist[j],true,false,pbc,getPbc(),comm,nl_cut[ncnt],nl_st[ncnt]);
+     575           8 :           ncnt+=1;
+     576             :         }
+     577             :       }
+     578             :     }
+     579             :   } else {
+     580           0 :     log << "WARNING: Neighbor List not activated this has not been tested!!  \n";
+     581           0 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm);
+     582           0 :     for (unsigned j=0; j<Nlist; j++) {
+     583           0 :       nl[j]= Tools::make_unique<NeighborList>(Plist[j],Plist[j],true,true,pbc,getPbc(),comm);
+     584             :     }
+     585             :   }
+     586             :   // Output Nlist
+     587          12 :   log << "Total Nlists: " << Nlist << " \n";
+     588          36 :   for (unsigned j=0; j<Nlist; j++) {
+     589          24 :     log << "  list " << j+1 << "   size " << nl[j]->size() << " \n";
+     590             :   }
+     591             :   // Calculate COM masses once and for all from lists
+     592          12 :   if(com) {
+     593           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     594             :       double commass=0.;
+     595           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     596           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     597           0 :         commass+=mypdb.getOccupancy()[andx];
+     598             :       }
+     599           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     600           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     601           0 :         if(commass>0.) {
+     602           0 :           fmass[andx]=mypdb.getOccupancy()[andx]/commass;
+     603             :         } else {
+     604           0 :           fmass[andx]=1.;
+     605             :         }
+     606             :       }
+     607             :     }
+     608             :   }
+     609             : 
+     610             :   // Sorting
+     611          12 :   dosort.resize(Nlist);
+     612          12 :   std:: vector<int> ynsort(Nlist);
+     613          12 :   parseVector("SORT",ynsort);
+     614          36 :   for (unsigned i=0; i<Nlist; i++) {
+     615          24 :     if(ynsort[i]==0||CompDer) {
+     616             :       dosort[i]=false;
+     617             :     } else {
+     618             :       dosort[i]=true;
+     619             :     }
+     620             :   }
+     621             : 
+     622             :   //build box vectors and correct for pbc
+     623          12 :   log << "Building the box from PDB data ... \n";
+     624          12 :   Tensor Box=mypdb.getBoxVec();
+     625          12 :   log << "  Done! A,B,C vectors in Cartesian space:  \n";
+     626          12 :   log.printf("  A:  %12.6f%12.6f%12.6f\n", Box[0][0],Box[0][1],Box[0][2]);
+     627          12 :   log.printf("  B:  %12.6f%12.6f%12.6f\n", Box[1][0],Box[1][1],Box[1][2]);
+     628          12 :   log.printf("  C:  %12.6f%12.6f%12.6f\n", Box[2][0],Box[2][1],Box[2][2]);
+     629          12 :   log << "Changing the PBC according to the new box \n";
+     630          12 :   Pbc mypbc;
+     631          12 :   mypbc.setBox(Box);
+     632          12 :   log << "The box volume is " << mypbc.getBox().determinant() << " \n";
+     633             : 
+     634             :   //Compute scaling factor
+     635          12 :   if(Svol) {
+     636          12 :     Fvol=cbrt(Vol0/mypbc.getBox().determinant());
+     637          12 :     log << "Scaling atom distances by  " << Fvol << " \n";
+     638             :   } else {
+     639           0 :     log << "Using unscaled atom distances \n";
+     640             :   }
+     641             : 
+     642          12 :   r00.resize(Nlist);
+     643          12 :   sw.resize(Nlist);
+     644          36 :   for (unsigned j=0; j<Nlist; j++) {
+     645          48 :     if( !parseNumbered( "SWITCH", j+1, sw[j] ) ) break;
+     646             :   }
+     647          12 :   if(CompDer) {
+     648             :     // Set switching function parameters here only if computing derivatives
+     649             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     650           6 :     log << "Switching Function Parameters \n";
+     651           6 :     sfs.resize(Nlist);
+     652             :     std::string errors;
+     653          18 :     for (unsigned j=0; j<Nlist; j++) {
+     654          12 :       if(Svol) {
+     655             :         double r0;
+     656             :         std::string old_r0;
+     657          12 :         vector<string> data=Tools::getWords(sw[j]);
+     658             :         data.erase(data.begin());
+     659          12 :         Tools::parse(data,"R_0",old_r0);
+     660          12 :         Tools::convert(old_r0,r0);
+     661          12 :         r0*=Fvol;
+     662          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     663          12 :         std::size_t pos = sw[j].find("R_0");
+     664          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     665          12 :       }
+     666          12 :       sfs[j].set(sw[j],errors);
+     667             :       std::string num;
+     668          12 :       Tools::convert(j+1, num);
+     669          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     670          12 :       r00[j]=sfs[j].get_r0();
+     671          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     672             :     }
+     673             :   }
+     674             : 
+     675             :   // build COMs from positions if requested
+     676          12 :   if(com) {
+     677           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     678           0 :       compos[j][0]=0.;
+     679           0 :       compos[j][1]=0.;
+     680           0 :       compos[j][2]=0.;
+     681           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     682           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     683           0 :         compos[j]+=fmass[andx]*mypdb.getPositions()[andx];
+     684             :       }
+     685             :     }
+     686             :   }
+     687             :   // build the rPIV distances (transformation and sorting is done afterwards)
+     688          12 :   if(CompDer) {
+     689           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     690             :   }
+     691          36 :   for(unsigned j=0; j<Nlist; j++) {
+     692    11516328 :     for(unsigned i=0; i<nl[j]->size(); i++) {
+     693    11516304 :       unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     694    11516304 :       unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     695             :       //calculate/get COM position of centers i0 and i1
+     696    11516304 :       Vector Pos0,Pos1;
+     697    11516304 :       if(com) {
+     698             :         //if(pbc) makeWhole();
+     699           0 :         Pos0=compos[i0];
+     700           0 :         Pos1=compos[i1];
+     701             :       } else {
+     702    11516304 :         Pos0=mypdb.getPositions()[i0];
+     703    11516304 :         Pos1=mypdb.getPositions()[i1];
+     704             :       }
+     705    11516304 :       Vector ddist;
+     706    11516304 :       if(pbc) {
+     707    11516304 :         ddist=mypbc.distance(Pos0,Pos1);
+     708             :       } else {
+     709           0 :         ddist=delta(Pos0,Pos1);
+     710             :       }
+     711    11516304 :       double df=0.;
+     712             :       // Transformation and sorting done at the first timestep to solve the r0 definition issue
+     713    11516304 :       if(CompDer) {
+     714        1104 :         rPIV[j].push_back(sfs[j].calculate(ddist.modulo()*Fvol, df));
+     715             :       } else {
+     716    11515200 :         rPIV[j].push_back(ddist.modulo()*Fvol);
+     717             :       }
+     718             :     }
+     719          24 :     if(CompDer) {
+     720          12 :       if(dosort[j]) {
+     721           0 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     722             :       }
+     723             :       int lmt0=0;
+     724             :       int lmt1=0;
+     725        1116 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     726        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     727           0 :           lmt0+=1;
+     728             :         }
+     729        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     730           0 :           lmt1+=1;
+     731             :         }
+     732             :       }
+     733          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     734             :     }
+     735             :   }
+     736             : 
+     737          12 :   checkRead();
+     738             :   // From the plumed manual on how to build-up a new Colvar
+     739          12 :   addValueWithDerivatives();
+     740          12 :   requestAtoms(nlall->getFullAtomList());
+     741          12 :   setNotPeriodic();
+     742             :   // getValue()->setPeridodicity(false);
+     743             :   // set size of derivative vector
+     744          12 :   m_deriv.resize(getNumberOfAtoms());
+     745          12 : }
+     746             : 
+     747         327 : void PIV::calculate()
+     748             : {
+     749             : 
+     750             :   // Local variables
+     751             : 
+     752         327 :   if(sharedData_unique) {
+     753             :     // This is executed by the first PIV instance.
+     754             :     // We initialize variables with the correct Nlist.
+     755         321 :     sharedData_unique->prev_pos.resize(Nlist);
+     756         321 :     sharedData_unique->cPIV.resize(Nlist);
+     757         321 :     sharedData_unique->Atom0.resize(Nlist);
+     758         321 :     sharedData_unique->Atom1.resize(Nlist);
+     759             :   }
+     760             : 
+     761             :   // create references to minimize the impact of the code below
+     762         327 :   auto & prev_stp(sharedData->prev_stp);
+     763             :   auto & init_stp(sharedData->init_stp);
+     764             :   auto & prev_pos(sharedData->prev_pos);
+     765             :   auto & cPIV(sharedData->cPIV);
+     766             :   auto & Atom0(sharedData->Atom0);
+     767             :   auto & Atom1(sharedData->Atom1);
+     768             : 
+     769         327 :   std:: vector<std:: vector<int> > A0(Nprec);
+     770         327 :   std:: vector<std:: vector<int> > A1(Nprec);
+     771             :   size_t stride=1;
+     772             :   unsigned rank=0;
+     773             : 
+     774         327 :   if(!serial) {
+     775         327 :     stride=comm.Get_size();
+     776         327 :     rank=comm.Get_rank();
+     777             :   } else {
+     778             :     stride=1;
+     779             :     rank=0;
+     780             :   }
+     781             : 
+     782             :   // Transform (and sort) the rPIV before starting the dynamics
+     783         327 :   if (((prev_stp==-1) || (init_stp==1)) &&!CompDer) {
+     784           6 :     if(prev_stp!=-1) {init_stp=0;}
+     785             :     // Calculate the volume scaling factor
+     786           6 :     if(Svol) {
+     787           6 :       Fvol=cbrt(Vol0/getBox().determinant());
+     788             :     }
+     789             :     //Set switching function parameters
+     790           6 :     log << "\n";
+     791           6 :     log << "REFERENCE PDB # " << prev_stp+2 << " \n";
+     792             :     // Set switching function parameters here only if computing derivatives
+     793             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     794           6 :     log << "Switching Function Parameters \n";
+     795           6 :     sfs.resize(Nlist);
+     796             :     std::string errors;
+     797          18 :     for (unsigned j=0; j<Nlist; j++) {
+     798          12 :       if(Svol) {
+     799             :         double r0;
+     800             :         std::string old_r0;
+     801          12 :         vector<string> data=Tools::getWords(sw[j]);
+     802             :         data.erase(data.begin());
+     803          12 :         Tools::parse(data,"R_0",old_r0);
+     804          12 :         Tools::convert(old_r0,r0);
+     805          12 :         r0*=Fvol;
+     806          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     807          12 :         std::size_t pos = sw[j].find("R_0");
+     808          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     809          12 :       }
+     810          12 :       sfs[j].set(sw[j],errors);
+     811             :       std::string num;
+     812          12 :       Tools::convert(j+1, num);
+     813          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     814          12 :       r00[j]=sfs[j].get_r0();
+     815          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     816             :     }
+     817             :     //Transform and sort
+     818           6 :     log << "Building Reference PIV Vector \n";
+     819           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     820           6 :     double df=0.;
+     821          18 :     for (unsigned j=0; j<Nlist; j++) {
+     822    11515212 :       for (unsigned i=0; i<rPIV[j].size(); i++) {
+     823    11515200 :         rPIV[j][i]=sfs[j].calculate(rPIV[j][i], df);
+     824             :       }
+     825          12 :       if(dosort[j]) {
+     826          12 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     827             :       }
+     828             :       int lmt0=0;
+     829             :       int lmt1=0;
+     830    11515212 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     831    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     832          26 :           lmt0+=1;
+     833             :         }
+     834    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     835       63358 :           lmt1+=1;
+     836             :         }
+     837             :       }
+     838          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     839             :     }
+     840           6 :     log << "\n";
+     841             :   }
+     842             :   // Do the sorting only once per timestep to avoid building the PIV N times for N rPIV PDB structures!
+     843         327 :   if ((getStep()>prev_stp&&getStep()%updatePIV==0)||CompDer) {
+     844         324 :     if (CompDer) log << " Step " << getStep() << "  Computing Derivatives NON-SORTED PIV \n";
+     845             :     //
+     846             :     // build COMs from positions if requested
+     847         324 :     if(com) {
+     848           0 :       if(pbc) makeWhole();
+     849           0 :       for(unsigned j=0; j<compos.size(); j++) {
+     850           0 :         compos[j][0]=0.;
+     851           0 :         compos[j][1]=0.;
+     852           0 :         compos[j][2]=0.;
+     853           0 :         for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     854           0 :           unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     855           0 :           compos[j]+=fmass[andx]*getPosition(andx);
+     856             :         }
+     857             :       }
+     858             :     }
+     859             :     // update neighbor lists when an atom moves out of the Neighbor list skin
+     860         324 :     if (doneigh) {
+     861             :       bool doupdate=false;
+     862             :       // For the first step build previous positions = actual positions
+     863         324 :       if (prev_stp==-1) {
+     864           6 :         bool docom=com;
+     865          18 :         for (unsigned j=0; j<Nlist; j++) {
+     866        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     867        9696 :             Vector Pos;
+     868        9696 :             if(docom) {
+     869           0 :               Pos=compos[i];
+     870             :             } else {
+     871        9696 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     872             :             }
+     873        9696 :             prev_pos[j].push_back(Pos);
+     874             :           }
+     875             :         }
+     876             :         doupdate=true;
+     877             :       }
+     878             :       // Decide whether to update lists based on atom displacement, every stride
+     879         324 :       std:: vector<std:: vector<Vector> > tmp_pos(Nlist);
+     880         324 :       if (getStep() % nlall->getStride() ==0) {
+     881         324 :         bool docom=com;
+     882         972 :         for (unsigned j=0; j<Nlist; j++) {
+     883       20520 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     884       19872 :             Vector Pos;
+     885       19872 :             if(docom) {
+     886           0 :               Pos=compos[i];
+     887             :             } else {
+     888       19872 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     889             :             }
+     890       19872 :             tmp_pos[j].push_back(Pos);
+     891       19872 :             if (pbcDistance(tmp_pos[j][i],prev_pos[j][i]).modulo()>=nl_skin[j]) {
+     892             :               doupdate=true;
+     893             :             }
+     894             :           }
+     895             :         }
+     896             :       }
+     897             :       // Update Nlists if needed
+     898         324 :       if (doupdate==true) {
+     899          18 :         for (unsigned j=0; j<Nlist; j++) {
+     900        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     901        9696 :             prev_pos[j][i]=tmp_pos[j][i];
+     902             :           }
+     903          12 :           nl[j]->update(prev_pos[j]);
+     904          12 :           log << " Step " << getStep() << "  Neighbour lists updated " << nl[j]->size() << " \n";
+     905             :         }
+     906             :       }
+     907         324 :     }
+     908             :     // Calculate the volume scaling factor
+     909         324 :     if(Svol) {
+     910         324 :       Fvol=cbrt(Vol0/getBox().determinant());
+     911             :     }
+     912         324 :     Vector ddist;
+     913             :     // Global to local variables
+     914         324 :     bool doserial=serial;
+     915             :     // Build "Nlist" PIV blocks
+     916         972 :     for(unsigned j=0; j<Nlist; j++) {
+     917         648 :       if(dosort[j]) {
+     918             :         // from global to local variables to speedup the for loop with if statements
+     919           6 :         bool docom=com;
+     920           6 :         bool dopbc=pbc;
+     921             :         // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     922           6 :         std:: vector<int> OrdVec(Nprec,0);
+     923           6 :         cPIV[j].resize(0);
+     924           6 :         Atom0[j].resize(0);
+     925           6 :         Atom1[j].resize(0);
+     926             :         // Building distances for the PIV vector at time t
+     927           9 :         if(timer) stopwatch.start("1 Build cPIV");
+     928     5757606 :         for(unsigned i=rank; i<nl[j]->size(); i+=stride) {
+     929     5757600 :           unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     930     5757600 :           unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     931     5757600 :           Vector Pos0,Pos1;
+     932     5757600 :           if(docom) {
+     933           0 :             Pos0=compos[i0];
+     934           0 :             Pos1=compos[i1];
+     935             :           } else {
+     936     5757600 :             Pos0=getPosition(i0);
+     937     5757600 :             Pos1=getPosition(i1);
+     938             :           }
+     939     5757600 :           if(dopbc) {
+     940     5757600 :             ddist=pbcDistance(Pos0,Pos1);
+     941             :           } else {
+     942           0 :             ddist=delta(Pos0,Pos1);
+     943             :           }
+     944     5757600 :           double df=0.;
+     945             :           //Integer sorting ... faster!
+     946             :           //Transforming distances with the Switching function + real to integer transformation
+     947     5757600 :           int Vint=int(sfs[j].calculate(ddist.modulo()*Fvol, df)*double(Nprec-1)+0.5);
+     948             :           //Integer transformed distance values as index of the Ordering Vector OrdVec
+     949     5757600 :           OrdVec[Vint]+=1;
+     950             :           //Keeps track of atom indices for force and virial calculations
+     951     5757600 :           A0[Vint].push_back(i0);
+     952     5757600 :           A1[Vint].push_back(i1);
+     953             :         }
+     954           9 :         if(timer) stopwatch.stop("1 Build cPIV");
+     955           9 :         if(timer) stopwatch.start("2 Sort cPIV");
+     956           6 :         if(!doserial && comm.initialized()) {
+     957             :           // Vectors keeping track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     958           0 :           std:: vector<int> Vdim(stride,0);
+     959           0 :           std:: vector<int> Vpos(stride,0);
+     960             :           // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     961           0 :           std:: vector<int> OrdVecAll(stride*Nprec);
+     962             :           // Big vectors containing all Atom indexes for every occupancy (Atom0O(Nprec,n) and Atom1O(Nprec,n) matrices in one vector)
+     963             :           std:: vector<int> Atom0F;
+     964             :           std:: vector<int> Atom1F;
+     965             :           // Vector used to reconstruct arrays
+     966           0 :           std:: vector<unsigned> k(stride,0);
+     967             :           // Zeros might be many, this slows down a lot due to MPI communication
+     968             :           // Avoid passing the zeros (i=1) for atom indices
+     969           0 :           for(unsigned i=1; i<Nprec; i++) {
+     970             :             // Building long vectors with all atom indexes for occupancies ordered from i=1 to i=Nprec-1
+     971             :             // Can this be avoided ???
+     972           0 :             Atom0F.insert(Atom0F.end(),A0[i].begin(),A0[i].end());
+     973           0 :             Atom1F.insert(Atom1F.end(),A1[i].begin(),A1[i].end());
+     974           0 :             A0[i].resize(0);
+     975           0 :             A1[i].resize(0);
+     976             :           }
+     977             :           // Resize partial arrays to fill up for the next PIV block
+     978           0 :           A0[0].resize(0);
+     979           0 :           A1[0].resize(0);
+     980           0 :           A0[Nprec-1].resize(0);
+     981           0 :           A1[Nprec-1].resize(0);
+     982             :           // Avoid passing the zeros (i=1) for atom indices
+     983           0 :           OrdVec[0]=0;
+     984           0 :           OrdVec[Nprec-1]=0;
+     985             : 
+     986             :           // Wait for all ranks before communication of Vectors
+     987           0 :           comm.Barrier();
+     988             : 
+     989             :           // pass the array sizes before passing the arrays
+     990           0 :           int dim=Atom0F.size();
+     991             :           // Vdim and Vpos keep track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     992           0 :           comm.Allgather(&dim,1,&Vdim[0],1);
+     993             : 
+     994             :           // TO BE IMPROVED: the following may be done by the rank 0 (now every rank does it)
+     995             :           int Fdim=0;
+     996           0 :           for(unsigned i=1; i<stride; i++) {
+     997           0 :             Vpos[i]=Vpos[i-1]+Vdim[i-1];
+     998           0 :             Fdim+=Vdim[i];
+     999             :           }
+    1000           0 :           Fdim+=Vdim[0];
+    1001             :           // build big vectors for atom pairs on all ranks for all ranks
+    1002           0 :           std:: vector<int> Atom0FAll(Fdim);
+    1003           0 :           std:: vector<int> Atom1FAll(Fdim);
+    1004             :           // TO BE IMPROVED: Allgathers may be substituted by gathers by proc 0
+    1005             :           //   Moreover vectors are gathered head-to-tail and assembled later-on in a serial step.
+    1006             :           // Gather the full Ordering Vector (occupancies). This is what we need to build the PIV
+    1007           0 :           comm.Allgather(&OrdVec[0],Nprec,&OrdVecAll[0],Nprec);
+    1008             :           // Gather the vectors of atom pairs to keep track of the idexes for the forces
+    1009           0 :           comm.Allgatherv(Atom0F.data(),Atom0F.size(),&Atom0FAll[0],&Vdim[0],&Vpos[0]);
+    1010           0 :           comm.Allgatherv(Atom1F.data(),Atom1F.size(),&Atom1FAll[0],&Vdim[0],&Vpos[0]);
+    1011             : 
+    1012             :           // Reconstruct the full vectors from collections of Allgathered parts (this is a serial step)
+    1013             :           // This is the tricky serial step, to assemble together PIV and atom-pair info from head-tail big vectors
+    1014             :           // Loop before on l and then on i would be better but the allgather should be modified
+    1015             :           // Loop on blocks
+    1016             :           //for(unsigned m=0;m<Nlist;m++) {
+    1017             :           // Loop on Ordering Vector size excluding zeros (i=1)
+    1018           0 :           if(timer) stopwatch.stop("2 Sort cPIV");
+    1019           0 :           if(timer) stopwatch.start("3 Reconstruct cPIV");
+    1020           0 :           for(unsigned i=1; i<Nprec; i++) {
+    1021             :             // Loop on the ranks
+    1022           0 :             for(unsigned l=0; l<stride; l++) {
+    1023             :               // Loop on the number of head-to-tail pieces
+    1024           0 :               for(unsigned m=0; m<OrdVecAll[i+l*Nprec]; m++) {
+    1025             :                 // cPIV is the current PIV at time t
+    1026           0 :                 cPIV[j].push_back(double(i)/double(Nprec-1));
+    1027           0 :                 Atom0[j].push_back(Atom0FAll[k[l]+Vpos[l]]);
+    1028           0 :                 Atom1[j].push_back(Atom1FAll[k[l]+Vpos[l]]);
+    1029           0 :                 k[l]+=1;
+    1030             :               }
+    1031             :             }
+    1032             :           }
+    1033           0 :           if(timer) stopwatch.stop("3 Reconstruct cPIV");
+    1034             :         } else {
+    1035     6000000 :           for(unsigned i=1; i<Nprec; i++) {
+    1036    11757594 :             for(unsigned m=0; m<OrdVec[i]; m++) {
+    1037     5757600 :               cPIV[j].push_back(double(i)/double(Nprec-1));
+    1038     5757600 :               Atom0[j].push_back(A0[i][m]);
+    1039     5757600 :               Atom1[j].push_back(A1[i][m]);
+    1040             :             }
+    1041             :           }
+    1042             :         }
+    1043             :       }
+    1044             :     }
+    1045             :   }
+    1046         327 :   Vector distance;
+    1047         327 :   double dfunc=0.;
+    1048             :   // Calculate volume scaling factor
+    1049         327 :   if(Svol) {
+    1050         327 :     Fvol=cbrt(Vol0/getBox().determinant());
+    1051             :   }
+    1052             : 
+    1053             :   // This test may be run by specifying the TEST keyword as input, it pritnts rPIV and cPIV and quits
+    1054         327 :   if(test) {
+    1055             :     unsigned limit=0;
+    1056           0 :     for(unsigned j=0; j<Nlist; j++) {
+    1057           0 :       if(dosort[j]) {
+    1058           0 :         limit = cPIV[j].size();
+    1059             :       } else {
+    1060           0 :         limit = rPIV[j].size();
+    1061             :       }
+    1062           0 :       log.printf("PIV Block:  %6i %12s %6i \n", j, "      Size:", limit);
+    1063           0 :       log.printf("%6s%6s%12s%12s%36s\n","     i","     j", "    c-PIV   ","    r-PIV   ","   i-j distance vector       ");
+    1064           0 :       for(unsigned i=0; i<limit; i++) {
+    1065             :         unsigned i0=0;
+    1066             :         unsigned i1=0;
+    1067           0 :         if(dosort[j]) {
+    1068           0 :           i0=Atom0[j][i];
+    1069           0 :           i1=Atom1[j][i];
+    1070             :         } else {
+    1071           0 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1072           0 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1073             :         }
+    1074           0 :         Vector Pos0,Pos1;
+    1075           0 :         if(com) {
+    1076           0 :           Pos0=compos[i0];
+    1077           0 :           Pos1=compos[i1];
+    1078             :         } else {
+    1079           0 :           Pos0=getPosition(i0);
+    1080           0 :           Pos1=getPosition(i1);
+    1081             :         }
+    1082           0 :         if(pbc) {
+    1083           0 :           distance=pbcDistance(Pos0,Pos1);
+    1084             :         } else {
+    1085           0 :           distance=delta(Pos0,Pos1);
+    1086             :         }
+    1087           0 :         dfunc=0.;
+    1088             :         double cP,rP;
+    1089           0 :         if(dosort[j]) {
+    1090           0 :           cP = cPIV[j][i];
+    1091           0 :           rP = rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1092             :         } else {
+    1093           0 :           double dm=distance.modulo();
+    1094           0 :           cP = sfs[j].calculate(dm*Fvol, dfunc);
+    1095           0 :           rP = rPIV[j][i];
+    1096             :         }
+    1097           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]);
+    1098             :       }
+    1099             :     }
+    1100           0 :     log.printf("This was a test, now exit \n");
+    1101           0 :     exit();
+    1102             :   }
+    1103             : 
+    1104         328 :   if(timer) stopwatch.start("4 Build For Derivatives");
+    1105             :   // non-global variables Nder and Scalevol defined to speedup if structures in cycles
+    1106         327 :   bool Nder=CompDer;
+    1107         327 :   bool Scalevol=Svol;
+    1108         327 :   if(getStep()%updatePIV==0) {
+    1109             :     // set to zero PIVdistance, derivatives and virial when they are calculated
+    1110       29799 :     for(unsigned j=0; j<m_deriv.size(); j++) {
+    1111      117888 :       for(unsigned k=0; k<3; k++) {m_deriv[j][k]=0.;}
+    1112             :     }
+    1113        1308 :     for(unsigned j=0; j<3; j++) {
+    1114        3924 :       for(unsigned k=0; k<3; k++) {
+    1115        2943 :         m_virial[j][k]=0.;
+    1116             :       }
+    1117             :     }
+    1118         327 :     m_PIVdistance=0.;
+    1119             :     // Re-compute atomic distances for derivatives and compute PIV-PIV distance
+    1120         981 :     for(unsigned j=0; j<Nlist; j++) {
+    1121             :       unsigned limit=0;
+    1122             :       // dosorting definition is to speedup if structure in cycles with non-global variables
+    1123         654 :       bool dosorting=dosort[j];
+    1124         654 :       bool docom=com;
+    1125         654 :       bool dopbc=pbc;
+    1126         654 :       if(dosorting) {
+    1127          12 :         limit = cPIV[j].size();
+    1128             :       } else {
+    1129         642 :         limit = rPIV[j].size();
+    1130             :       }
+    1131    11574918 :       for(unsigned i=rank; i<limit; i+=stride) {
+    1132             :         unsigned i0=0;
+    1133             :         unsigned i1=0;
+    1134    11574264 :         if(dosorting) {
+    1135    11515200 :           i0=Atom0[j][i];
+    1136    11515200 :           i1=Atom1[j][i];
+    1137             :         } else {
+    1138       59064 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1139       59064 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1140             :         }
+    1141    11574264 :         Vector Pos0,Pos1;
+    1142    11574264 :         if(docom) {
+    1143           0 :           Pos0=compos[i0];
+    1144           0 :           Pos1=compos[i1];
+    1145             :         } else {
+    1146    11574264 :           Pos0=getPosition(i0);
+    1147    11574264 :           Pos1=getPosition(i1);
+    1148             :         }
+    1149    11574264 :         if(dopbc) {
+    1150    11574264 :           distance=pbcDistance(Pos0,Pos1);
+    1151             :         } else {
+    1152           0 :           distance=delta(Pos0,Pos1);
+    1153             :         }
+    1154    11574264 :         dfunc=0.;
+    1155             :         // this is needed for dfunc and dervatives
+    1156    11574264 :         double dm=distance.modulo();
+    1157    11574264 :         double tPIV = sfs[j].calculate(dm*Fvol, dfunc);
+    1158             :         // PIV distance
+    1159             :         double coord=0.;
+    1160    11574264 :         if(!dosorting||Nder) {
+    1161       59064 :           coord = tPIV - rPIV[j][i];
+    1162             :         } else {
+    1163    11515200 :           coord = cPIV[j][i] - rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1164             :         }
+    1165             :         // Calculate derivatives, virial, and variable=sum_j (scaling[j] *(cPIV-rPIV)_j^2)
+    1166             :         // WARNING: dfunc=dswf/(Fvol*dm)  (this may change in future Plumed versions)
+    1167    11574264 :         double tmp = 2.*scaling[j]*coord*Fvol*Fvol*dfunc;
+    1168    11574264 :         Vector tmpder = tmp*distance;
+    1169             :         // 0.5*(x_i-x_k)*f_ik         (force on atom k due to atom i)
+    1170    11574264 :         if(docom) {
+    1171           0 :           Vector dist;
+    1172           0 :           for(unsigned k=0; k<nlcom[i0]->getFullAtomList().size(); k++) {
+    1173           0 :             unsigned x0=nlcom[i0]->getFullAtomList()[k].index();
+    1174           0 :             m_deriv[x0] -= tmpder*fmass[x0];
+    1175           0 :             for(unsigned l=0; l<3; l++) {
+    1176           0 :               dist[l]=0.;
+    1177             :             }
+    1178           0 :             Vector P0=getPosition(x0);
+    1179           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1180           0 :               unsigned x1=nlcom[i0]->getFullAtomList()[l].index();
+    1181           0 :               Vector P1=getPosition(x1);
+    1182           0 :               if(dopbc) {
+    1183           0 :                 dist+=pbcDistance(P0,P1);
+    1184             :               } else {
+    1185           0 :                 dist+=delta(P0,P1);
+    1186             :               }
+    1187             :             }
+    1188           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1189           0 :               unsigned x1=nlcom[i1]->getFullAtomList()[l].index();
+    1190           0 :               Vector P1=getPosition(x1);
+    1191           0 :               if(dopbc) {
+    1192           0 :                 dist+=pbcDistance(P0,P1);
+    1193             :               } else {
+    1194           0 :                 dist+=delta(P0,P1);
+    1195             :               }
+    1196             :             }
+    1197           0 :             m_virial    -= 0.25*fmass[x0]*Tensor(dist,tmpder);
+    1198             :           }
+    1199           0 :           for(unsigned k=0; k<nlcom[i1]->getFullAtomList().size(); k++) {
+    1200           0 :             unsigned x1=nlcom[i1]->getFullAtomList()[k].index();
+    1201           0 :             m_deriv[x1] += tmpder*fmass[x1];
+    1202           0 :             for(unsigned l=0; l<3; l++) {
+    1203           0 :               dist[l]=0.;
+    1204             :             }
+    1205           0 :             Vector P1=getPosition(x1);
+    1206           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1207           0 :               unsigned x0=nlcom[i1]->getFullAtomList()[l].index();
+    1208           0 :               Vector P0=getPosition(x0);
+    1209           0 :               if(dopbc) {
+    1210           0 :                 dist+=pbcDistance(P1,P0);
+    1211             :               } else {
+    1212           0 :                 dist+=delta(P1,P0);
+    1213             :               }
+    1214             :             }
+    1215           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1216           0 :               unsigned x0=nlcom[i0]->getFullAtomList()[l].index();
+    1217           0 :               Vector P0=getPosition(x0);
+    1218           0 :               if(dopbc) {
+    1219           0 :                 dist+=pbcDistance(P1,P0);
+    1220             :               } else {
+    1221           0 :                 dist+=delta(P1,P0);
+    1222             :               }
+    1223             :             }
+    1224           0 :             m_virial    += 0.25*fmass[x1]*Tensor(dist,tmpder);
+    1225             :           }
+    1226             :         } else {
+    1227    11574264 :           m_deriv[i0] -= tmpder;
+    1228    11574264 :           m_deriv[i1] += tmpder;
+    1229    11574264 :           m_virial    -= tmp*Tensor(distance,distance);
+    1230             :         }
+    1231    11574264 :         if(Scalevol) {
+    1232    11574264 :           m_virial+=1./3.*tmp*dm*dm*Tensor::identity();
+    1233             :         }
+    1234    11574264 :         m_PIVdistance    += scaling[j]*coord*coord;
+    1235             :       }
+    1236             :     }
+    1237             : 
+    1238         327 :     if (!serial && comm.initialized()) {
+    1239           0 :       comm.Barrier();
+    1240           0 :       comm.Sum(&m_PIVdistance,1);
+    1241           0 :       if(!m_deriv.empty()) comm.Sum(&m_deriv[0][0],3*m_deriv.size());
+    1242           0 :       comm.Sum(&m_virial[0][0],9);
+    1243             :     }
+    1244             :   }
+    1245         327 :   prev_stp=getStep();
+    1246             : 
+    1247             :   //Timing
+    1248         328 :   if(timer) stopwatch.stop("4 Build For Derivatives");
+    1249         327 :   if(timer) {
+    1250           1 :     log.printf("Timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+    1251           1 :     log<<stopwatch;
+    1252             :   }
+    1253             : 
+    1254             :   // Update derivatives, virial, and variable (PIV-distance^2)
+    1255       29799 :   for(unsigned i=0; i<m_deriv.size(); ++i) setAtomsDerivatives(i,m_deriv[i]);
+    1256         327 :   setValue           (m_PIVdistance);
+    1257         327 :   setBoxDerivatives  (m_virial);
+    1258         327 : }
+    1259             : //Close Namespaces at the very beginning
+    1260             : }
+    1261             : }
+    1262             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-f.html b/coverage/piv/index-sort-f.html new file mode 100644 index 0000000000..d9299de741 --- /dev/null +++ b/coverage/piv/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59675.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-l.html b/coverage/piv/index-sort-l.html new file mode 100644 index 0000000000..d8827e55f8 --- /dev/null +++ b/coverage/piv/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59675.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index.html b/coverage/piv/index.html new file mode 100644 index 0000000000..8d39a9d97c --- /dev/null +++ b/coverage/piv/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42859671.8 %
Date:2024-05-27 13:05:14Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %428 / 59675.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func-sort-c.html b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html new file mode 100644 index 0000000000..fb59f7f14e --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe806createERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe80C2Ev4168
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe80D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func.html b/coverage/pytorch/PytorchModel.cpp.func.html new file mode 100644 index 0000000000..6f3ec984d7 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe806createERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe80C2Ev4168
_ZN4PLMD8function7pytorch12_GLOBAL__N_124PytorchModelRegisterMe80D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.gcov.html b/coverage/pytorch/PytorchModel.cpp.gcov.html new file mode 100644 index 0000000000..b33d9c15d3 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022-2023 of Luigi Bonati.
+       3             : 
+       4             : The pytorch module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The pytorch module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : 
+      18             : #ifdef __PLUMED_HAS_LIBTORCH
+      19             : // convert LibTorch version to string
+      20             : //#define STRINGIFY(x) #x
+      21             : //#define TOSTR(x) STRINGIFY(x)
+      22             : //#define LIBTORCH_VERSION TO_STR(TORCH_VERSION_MAJOR) "." TO_STR(TORCH_VERSION_MINOR) "." TO_STR(TORCH_VERSION_PATCH)
+      23             : 
+      24             : #include "core/PlumedMain.h"
+      25             : #include "function/Function.h"
+      26             : #include "function/ActionRegister.h"
+      27             : 
+      28             : #include <torch/torch.h>
+      29             : #include <torch/script.h>
+      30             : 
+      31             : #include <fstream>
+      32             : #include <cmath>
+      33             : 
+      34             : using namespace std;
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace function {
+      38             : namespace pytorch {
+      39             : 
+      40             : //+PLUMEDOC PYTORCH_FUNCTION PYTORCH_MODEL
+      41             : /*
+      42             : Load a PyTorch model compiled with TorchScript.
+      43             : 
+      44             : This can be a function defined in Python or a more complex model, such as a neural network optimized on a set of data. In both cases the derivatives of the outputs with respect to the inputs are computed using the automatic differentiation (autograd) feature of Pytorch.
+      45             : 
+      46             : By default it is assumed that the model is saved as: `model.ptc`, unless otherwise indicated by the `FILE` keyword. The function automatically checks for the number of output dimensions and creates a component for each of them. The outputs are called node-i with i between 0 and N-1 for N outputs.
+      47             : 
+      48             : Note that this function is active only if LibTorch is correctly linked against PLUMED. Please check the instructions in the \ref PYTORCH page.
+      49             : 
+      50             : \par Examples
+      51             : Load a model called `torch_model.ptc` that takes as input two dihedral angles and returns two outputs.
+      52             : 
+      53             : \plumedfile
+      54             : #SETTINGS AUXFILE=regtest/pytorch/rt-pytorch_model_2d/torch_model.ptc
+      55             : phi: TORSION ATOMS=5,7,9,15
+      56             : psi: TORSION ATOMS=7,9,15,17
+      57             : model: PYTORCH_MODEL FILE=torch_model.ptc ARG=phi,psi
+      58             : PRINT FILE=COLVAR ARG=model.node-0,model.node-1
+      59             : \endplumedfile
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : 
+      65             : class PytorchModel :
+      66             :   public Function
+      67             : {
+      68             :   unsigned _n_in;
+      69             :   unsigned _n_out;
+      70             :   torch::jit::script::Module _model;
+      71             : 
+      72             : public:
+      73             :   explicit PytorchModel(const ActionOptions&);
+      74             :   void calculate();
+      75             :   static void registerKeywords(Keywords& keys);
+      76             : 
+      77             :   std::vector<float> tensor_to_vector(const torch::Tensor& x);
+      78             : };
+      79             : 
+      80       12512 : PLUMED_REGISTER_ACTION(PytorchModel,"PYTORCH_MODEL")
+      81             : 
+      82           6 : void PytorchModel::registerKeywords(Keywords& keys) {
+      83           6 :   Function::registerKeywords(keys);
+      84           6 :   keys.use("ARG");
+      85          12 :   keys.add("optional","FILE","Filename of the PyTorch compiled model");
+      86          12 :   keys.addOutputComponent("node", "default", "Model outputs");
+      87           6 : }
+      88             : 
+      89             : // Auxiliary function to transform torch tensors in std vectors
+      90         103 : std::vector<float> PytorchModel::tensor_to_vector(const torch::Tensor& x) {
+      91         206 :   return std::vector<float>(x.data_ptr<float>(), x.data_ptr<float>() + x.numel());
+      92             : }
+      93             : 
+      94           4 : PytorchModel::PytorchModel(const ActionOptions&ao):
+      95             :   Action(ao),
+      96           4 :   Function(ao)
+      97             : { //print pytorch version
+      98             : 
+      99             :   //number of inputs of the model
+     100           4 :   _n_in=getNumberOfArguments();
+     101             : 
+     102             :   //parse model name
+     103           4 :   std::string fname="model.ptc";
+     104           8 :   parse("FILE",fname);
+     105             : 
+     106             :   //deserialize the model from file
+     107             :   try {
+     108           4 :     _model = torch::jit::load(fname);
+     109             :   }
+     110             :   //if an error is thrown check if the file exists or not
+     111           0 :   catch (const c10::Error& e) {
+     112           0 :     std::ifstream infile(fname);
+     113             :     bool exist = infile.good();
+     114           0 :     infile.close();
+     115           0 :     if (exist) {
+     116             :       // print libtorch version
+     117           0 :       std::stringstream ss;
+     118           0 :       ss << TORCH_VERSION_MAJOR << "." << TORCH_VERSION_MINOR << "." << TORCH_VERSION_PATCH;
+     119             :       std::string version;
+     120           0 :       ss >> version; // extract into the string.
+     121           0 :       plumed_merror("Cannot load FILE: '"+fname+"'. Please check that it is a Pytorch compiled model (exported with 'torch.jit.trace' or 'torch.jit.script') and that the Pytorch version matches the LibTorch one ("+version+").");
+     122           0 :     }
+     123             :     else {
+     124           0 :       plumed_merror("The FILE: '"+fname+"' does not exist.");
+     125             :     }
+     126           0 :   }
+     127             : 
+     128           4 :   checkRead();
+     129             : 
+     130             :   //check the dimension of the output
+     131           4 :   log.printf("Checking output dimension:\n");
+     132           4 :   std::vector<float> input_test (_n_in);
+     133           4 :   torch::Tensor single_input = torch::tensor(input_test).view({1,_n_in});
+     134             :   std::vector<torch::jit::IValue> inputs;
+     135           4 :   inputs.push_back( single_input );
+     136           8 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     137           4 :   vector<float> cvs = this->tensor_to_vector (output);
+     138           4 :   _n_out=cvs.size();
+     139             : 
+     140             :   //create components
+     141           9 :   for(unsigned j=0; j<_n_out; j++) {
+     142           5 :     string name_comp = "node-"+std::to_string(j);
+     143           5 :     addComponentWithDerivatives( name_comp );
+     144           5 :     componentIsNotPeriodic( name_comp );
+     145             :   }
+     146             : 
+     147             :   //print log
+     148             :   //log.printf("Pytorch Model Loaded: %s \n",fname);
+     149           4 :   log.printf("Number of input: %d \n",_n_in);
+     150           4 :   log.printf("Number of outputs: %d \n",_n_out);
+     151           4 :   log.printf("  Bibliography: ");
+     152           8 :   log<<plumed.cite("Bonati, Rizzi and Parrinello, J. Phys. Chem. Lett. 11, 2998-3004 (2020)");
+     153           4 :   log.printf("\n");
+     154             : 
+     155           8 : }
+     156             : 
+     157          44 : void PytorchModel::calculate() {
+     158             : 
+     159             :   //retrieve arguments
+     160          44 :   vector<float> current_S(_n_in);
+     161          99 :   for(unsigned i=0; i<_n_in; i++)
+     162          55 :     current_S[i]=getArgument(i);
+     163             :   //convert to tensor
+     164          44 :   torch::Tensor input_S = torch::tensor(current_S).view({1,_n_in});
+     165             :   input_S.set_requires_grad(true);
+     166             :   //convert to Ivalue
+     167             :   std::vector<torch::jit::IValue> inputs;
+     168          44 :   inputs.push_back( input_S );
+     169             :   //calculate output
+     170          88 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     171             :   //set CV values
+     172          44 :   vector<float> cvs = this->tensor_to_vector (output);
+     173          99 :   for(unsigned j=0; j<_n_out; j++) {
+     174          55 :     string name_comp = "node-"+std::to_string(j);
+     175          55 :     getPntrToComponent(name_comp)->set(cvs[j]);
+     176             :   }
+     177             :   //derivatives
+     178          99 :   for(unsigned j=0; j<_n_out; j++) {
+     179             :     // expand dim to have shape (1,_n_out)
+     180             :     int batch_size = 1;
+     181          55 :     auto grad_output = torch::ones({1}).expand({batch_size, 1});
+     182             :     // calculate derivatives with automatic differentiation
+     183         220 :     auto gradient = torch::autograd::grad({output.slice(/*dim=*/1, /*start=*/j, /*end=*/j+1)},
+     184             :     {input_S},
+     185             :     /*grad_outputs=*/ {grad_output},
+     186             :     /*retain_graph=*/true,
+     187         330 :     /*create_graph=*/false);
+     188             :     // add dimension
+     189             :     auto grad = gradient[0].unsqueeze(/*dim=*/1);
+     190             :     //convert to vector
+     191          55 :     vector<float> der = this->tensor_to_vector ( grad );
+     192             : 
+     193          55 :     string name_comp = "node-"+std::to_string(j);
+     194             :     //set derivatives of component j
+     195         132 :     for(unsigned i=0; i<_n_in; i++)
+     196          77 :       setDerivative( getPntrToComponent(name_comp),i, der[i] );
+     197          55 :   }
+     198          88 : }
+     199             : }
+     200             : }
+     201             : }
+     202             : 
+     203             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-f.html b/coverage/pytorch/index-sort-f.html new file mode 100644 index 0000000000..234fb910c1 --- /dev/null +++ b/coverage/pytorch/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
83.1%83.1%
+
83.1 %54 / 6587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-l.html b/coverage/pytorch/index-sort-l.html new file mode 100644 index 0000000000..4a72bf1b88 --- /dev/null +++ b/coverage/pytorch/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
83.1%83.1%
+
83.1 %54 / 6587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index.html b/coverage/pytorch/index.html new file mode 100644 index 0000000000..beb75651d7 --- /dev/null +++ b/coverage/pytorch/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:546583.1 %
Date:2024-05-27 13:05:14Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
83.1%83.1%
+
83.1 %54 / 6587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html b/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html new file mode 100644 index 0000000000..88b966b753 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.func.html b/coverage/reference/ArgumentOnlyDistance.cpp.func.html new file mode 100644 index 0000000000..8718fa83ff --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html b/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html new file mode 100644 index 0000000000..93dd76cfb1 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html b/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html new file mode 100644 index 0000000000..10751a69af --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.func.html b/coverage/reference/ArgumentOnlyDistance.h.func.html new file mode 100644 index 0000000000..fd41d2b2f8 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.gcov.html b/coverage/reference/ArgumentOnlyDistance.h.gcov.html new file mode 100644 index 0000000000..d9e16441ff --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.gcov.html @@ -0,0 +1,121 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.func-sort-c.html b/coverage/reference/DRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..c59e0c6463 --- /dev/null +++ b/coverage/reference/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_115DRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev4168
_ZNK4PLMD5DRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb20378
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.func.html b/coverage/reference/DRMSD.cpp.func.html new file mode 100644 index 0000000000..7586bbe18f --- /dev/null +++ b/coverage/reference/DRMSD.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev4168
_ZN4PLMD5DRMSD10readBoundsERKNS_3PDBE11
_ZN4PLMD5DRMSD13setup_targetsEv26
_ZN4PLMD5DRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_17
_ZN4PLMD5DRMSD20setBoundsOnDistancesEbdd28
_ZN4PLMD5DRMSD4readERKNS_3PDBE9
_ZN4PLMD5DRMSDC1ERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD5DRMSDC2ERKNS_29ReferenceConfigurationOptionsE2
_ZNK4PLMD5DRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb20378
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.gcov.html b/coverage/reference/DRMSD.cpp.gcov.html new file mode 100644 index 0000000000..a40ddbfac1 --- /dev/null +++ b/coverage/reference/DRMSD.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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-05-27 13:05: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       12556 : PLUMED_REGISTER_METRIC(DRMSD,"DRMSD")
+      29             : 
+      30          28 : DRMSD::DRMSD( const ReferenceConfigurationOptions& ro ):
+      31             :   ReferenceConfiguration( ro ),
+      32             :   SingleDomainRMSD( ro ),
+      33          28 :   nopbc(true),
+      34          28 :   bounds_were_set(false),
+      35          28 :   lower(0),
+      36          28 :   upper(std::numeric_limits<double>::max( ))
+      37             : {
+      38          28 : }
+      39             : 
+      40          28 : void DRMSD::setBoundsOnDistances( bool dopbc, double lbound, double ubound ) {
+      41          28 :   bounds_were_set=true; nopbc=!dopbc;
+      42          28 :   lower=lbound; upper=ubound;
+      43          28 : }
+      44             : 
+      45          11 : void DRMSD::readBounds( const PDB& pdb ) {
+      46          11 :   if( bounds_were_set ) return;
+      47           0 :   double tmp; nopbc=pdb.hasFlag("NOPBC");
+      48           0 :   if( pdb.getArgumentValue("LOWER_CUTOFF",tmp) ) lower=tmp;
+      49           0 :   if( pdb.getArgumentValue("UPPER_CUTOFF",tmp) ) upper=tmp;
+      50           0 :   bounds_were_set=true;
+      51             : }
+      52             : 
+      53           9 : void DRMSD::read( const PDB& pdb ) {
+      54           9 :   readAtomsFromPDB( pdb ); readBounds( pdb ); setup_targets();
+      55           9 : }
+      56             : 
+      57          17 : void DRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      58          17 :   SingleDomainRMSD::setReferenceAtoms( conf, align_in, displace_in );
+      59          17 :   setup_targets();
+      60          17 : }
+      61             : 
+      62          26 : void DRMSD::setup_targets() {
+      63          26 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      64             : 
+      65          26 :   unsigned natoms = getNumberOfReferencePositions();
+      66         569 :   for(unsigned i=0; i<natoms-1; ++i) {
+      67        7779 :     for(unsigned j=i+1; j<natoms; ++j) {
+      68        7236 :       double distance = delta( getReferencePosition(i), getReferencePosition(j) ).modulo();
+      69        7236 :       if(distance < upper && distance > lower ) {
+      70        6620 :         targets[std::make_pair(i,j)] = distance;
+      71             :       }
+      72             :     }
+      73             :   }
+      74          26 :   if( targets.empty() ) error("drmsd will compare no distances - check upper and lower bounds are sensible");
+      75          26 : }
+      76             : 
+      77       20378 : double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      78             :   plumed_dbg_assert(!targets.empty());
+      79             : 
+      80       20378 :   Vector distance;
+      81       20378 :   myder.clear();
+      82             :   double drmsd=0.;
+      83     8126088 :   for(const auto & it : targets) {
+      84             : 
+      85     8105710 :     const unsigned i=getAtomIndex( it.first.first );
+      86     8105710 :     const unsigned j=getAtomIndex( it.first.second );
+      87             : 
+      88     8105710 :     if(nopbc) distance=delta( pos[i], pos[j] );
+      89     8076310 :     else      distance=pbc.distance( pos[i], pos[j] );
+      90             : 
+      91     8105710 :     const double len = distance.modulo();
+      92     8105710 :     const double diff = len - it.second;
+      93     8105710 :     const double der = diff / len;
+      94             : 
+      95     8105710 :     drmsd += diff * diff;
+      96     8105710 :     myder.addAtomDerivatives( i, -der * distance );
+      97     8105710 :     myder.addAtomDerivatives( j,  der * distance );
+      98     8105710 :     myder.addBoxDerivatives( - der * Tensor(distance,distance) );
+      99             :   }
+     100             : 
+     101       20378 :   const double inpairs = 1./static_cast<double>(targets.size());
+     102             :   double idrmsd;
+     103             : 
+     104       20378 :   if(squared) {
+     105          10 :     drmsd = drmsd * inpairs;
+     106          10 :     idrmsd = 2.0 * inpairs;
+     107             :   } else {
+     108       20368 :     drmsd = std::sqrt( drmsd * inpairs );
+     109       20368 :     idrmsd = inpairs / drmsd ;
+     110             :   }
+     111             : 
+     112       20378 :   myder.scaleAllDerivatives( idrmsd );
+     113             : 
+     114       20378 :   return drmsd;
+     115             : }
+     116             : 
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.func-sort-c.html b/coverage/reference/Direction.cpp.func-sort-c.html new file mode 100644 index 0000000000..6f9f831316 --- /dev/null +++ b/coverage/reference/Direction.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_119DirectionRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.func.html b/coverage/reference/Direction.cpp.func.html new file mode 100644 index 0000000000..432140722f --- /dev/null +++ b/coverage/reference/Direction.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMe6createERKNS_29ReferenceConfigurationOptionsE10
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev4168
_ZN4PLMD9Direction12addDirectionERKdRKS0_303
_ZN4PLMD9Direction12setDirectionERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE494
_ZN4PLMD9Direction13zeroDirectionEv12
_ZN4PLMD9Direction4readERKNS_3PDBE219
_ZN4PLMD9DirectionC1ERKNS_29ReferenceConfigurationOptionsE219
_ZN4PLMD9DirectionC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD9Direction25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_10
_ZNK4PLMD9Direction27extractArgumentDisplacementERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERS9_10
_ZNK4PLMD9Direction4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.gcov.html b/coverage/reference/Direction.cpp.gcov.html new file mode 100644 index 0000000000..0d76c1c0a3 --- /dev/null +++ b/coverage/reference/Direction.cpp.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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       12524 : PLUMED_REGISTER_METRIC(Direction,"DIRECTION")
+      28             : 
+      29         219 : Direction::Direction( const ReferenceConfigurationOptions& ro ):
+      30             :   ReferenceConfiguration(ro),
+      31             :   ReferenceAtoms(ro),
+      32             :   ReferenceArguments(ro),
+      33         219 :   normalized(false)
+      34             : {
+      35         219 : }
+      36             : 
+      37         219 : void Direction::read( const PDB& pdb ) {
+      38         219 :   readAtomsFromPDB( pdb, true );
+      39         219 :   readArgumentsFromPDB( pdb );
+      40         219 : }
+      41             : 
+      42         494 : void Direction::setDirection( const std::vector<Vector>& conf, const std::vector<double>& args ) {
+      43         494 :   std::vector<double> sigma( args.size(), 1.0 ); setReferenceArguments( args, sigma );
+      44             : 
+      45         494 :   reference_atoms.resize( conf.size() ); align.resize( conf.size() );
+      46         494 :   displace.resize( conf.size() ); atom_der_index.resize( conf.size() );
+      47         715 :   for(unsigned i=0; i<conf.size(); ++i) { align[i]=1.0; displace[i]=1.0; atom_der_index[i]=i; reference_atoms[i]=conf[i]; }
+      48         494 : }
+      49             : 
+      50         303 : void Direction::addDirection( const double& weight, const Direction& dir ) {
+      51             :   plumed_dbg_assert( dir.getNumberOfReferenceArguments()==getNumberOfReferenceArguments() && dir.reference_atoms.size()==reference_atoms.size() );
+      52         909 :   for(unsigned i=0; i<reference_args.size(); ++i) reference_args[i] += weight*dir.reference_args[i];
+      53         303 :   for(unsigned i=0; i<reference_atoms.size(); ++i) reference_atoms[i] += weight*reference_atoms.size()*dir.reference_atoms[i];
+      54         303 : }
+      55             : 
+      56          12 : void Direction::zeroDirection() {
+      57          32 :   for(unsigned i=0; i<reference_args.size(); ++i) reference_args[i] = 0.;
+      58          38 :   for(unsigned i=0; i<reference_atoms.size(); ++i) reference_atoms[i].zero();
+      59          12 : }
+      60             : 
+      61           0 : double Direction::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args,
+      62             :                         ReferenceValuePack& myder, const bool& squared ) const {
+      63           0 :   plumed_merror("You should never be calling calc for a direction");
+      64             : }
+      65             : 
+      66          10 : void Direction::extractArgumentDisplacement( const std::vector<Value*>& vals, const std::vector<double>& arg, std::vector<double>& dirout ) const {
+      67          10 :   for(unsigned i=0; i<getNumberOfReferenceArguments(); ++i) dirout[i]=getReferenceArgument(i);
+      68          10 : }
+      69             : 
+      70          10 : void Direction::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& dirout ) const {
+      71          80 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) dirout[i]=getReferencePosition(i);
+      72          10 : }
+      73             : 
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.func-sort-c.html b/coverage/reference/Direction.h.func-sort-c.html new file mode 100644 index 0000000000..4f76668b09 --- /dev/null +++ b/coverage/reference/Direction.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.func.html b/coverage/reference/Direction.h.func.html new file mode 100644 index 0000000000..7de2cf758e --- /dev/null +++ b/coverage/reference/Direction.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.gcov.html b/coverage/reference/Direction.h.gcov.html new file mode 100644 index 0000000000..f3fa802cf3 --- /dev/null +++ b/coverage/reference/Direction.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.func-sort-c.html b/coverage/reference/DotProductDistance.cpp.func-sort-c.html new file mode 100644 index 0000000000..b773ca33c7 --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_128DotProductDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.func.html b/coverage/reference/DotProductDistance.cpp.func.html new file mode 100644 index 0000000000..2c0127bb77 --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev4168
_ZN4PLMD18DotProductDistance4readERKNS_3PDBE0
_ZN4PLMD18DotProductDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18DotProductDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD18DotProductDistance25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.gcov.html b/coverage/reference/DotProductDistance.cpp.gcov.html new file mode 100644 index 0000000000..8b3218c0c9 --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_METRIC(DotProductDistance,"DOTPRODUCT")
+      37             : 
+      38           0 : DotProductDistance::DotProductDistance( const ReferenceConfigurationOptions& ro ):
+      39             :   ReferenceConfiguration(ro),
+      40           0 :   ArgumentOnlyDistance(ro)
+      41             : {
+      42           0 : }
+      43             : 
+      44           0 : void DotProductDistance::read( const PDB& pdb ) {
+      45           0 :   readArgumentsFromPDB( pdb );
+      46           0 : }
+      47             : 
+      48           0 : double DotProductDistance::calculateArgumentDistance( const std::vector<Value*> & vals, const std::vector<double>& arg,
+      49             :     ReferenceValuePack& myder, const bool& squared ) const {
+      50             :   double dot=0.0;
+      51           0 :   for (std::size_t i=0; i<vals.size(); ++i) dot+=getReferenceArgument(i)*arg[i];
+      52           0 :   for (std::size_t i=0; i<vals.size(); ++i) myder.setArgumentDerivatives( i, -getReferenceArgument(i)/dot );
+      53           0 :   if(dot==0.0) dot=std::numeric_limits<double>::min();
+      54           0 :   return -log(dot);
+      55             : }
+      56             : 
+      57             : 
+      58             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.func-sort-c.html b/coverage/reference/EuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 0000000000..920abd3d45 --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev4168
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.func.html b/coverage/reference/EuclideanDistance.cpp.func.html new file mode 100644 index 0000000000..ff79df507a --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev4168
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.gcov.html b/coverage/reference/EuclideanDistance.cpp.gcov.html new file mode 100644 index 0000000000..daee8f7357 --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.gcov.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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     1049232 : PLUMED_REGISTER_METRIC(EuclideanDistance,"EUCLIDEAN")
+      33             : 
+      34      518364 : EuclideanDistance::EuclideanDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36      518364 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38      518364 : }
+      39             : 
+      40             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html b/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..432ae65432 --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_129IntermolecularDRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.func.html b/coverage/reference/IntermolecularDRMSD.cpp.func.html new file mode 100644 index 0000000000..f5ddff4f11 --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev4168
_ZN4PLMD19IntermolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntermolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntermolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntermolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.gcov.html b/coverage/reference/IntermolecularDRMSD.cpp.gcov.html new file mode 100644 index 0000000000..33db7405f1 --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.gcov.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_METRIC(IntermolecularDRMSD,"INTER-DRMSD")
+      38             : 
+      39           1 : IntermolecularDRMSD::IntermolecularDRMSD( const ReferenceConfigurationOptions& ro ):
+      40             :   ReferenceConfiguration( ro ),
+      41             :   DRMSD( ro ),
+      42           1 :   nblocks(0)
+      43             : {
+      44           1 : }
+      45             : 
+      46           1 : void IntermolecularDRMSD::read( const PDB& pdb ) {
+      47           1 :   readAtomsFromPDB( pdb, true ); nblocks = pdb.getNumberOfAtomBlocks(); blocks.resize( nblocks+1 );
+      48           1 :   if( nblocks==1 ) error("Trying to compute intermolecular rmsd but found no TERs in input PDB");
+      49           3 :   blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      50           1 :   readBounds( pdb ); setup_targets();
+      51           1 : }
+      52             : 
+      53           1 : void IntermolecularDRMSD::setup_targets() {
+      54           1 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      55             : 
+      56           2 :   for(unsigned i=1; i<nblocks; ++i) {
+      57           2 :     for(unsigned j=0; j<i; ++j) {
+      58           4 :       for(unsigned iatom=blocks[i]; iatom<blocks[i+1]; ++iatom) {
+      59          15 :         for(unsigned jatom=blocks[j]; jatom<blocks[j+1]; ++jatom) {
+      60          12 :           double distance = delta( getReferencePosition(iatom), getReferencePosition(jatom) ).modulo();
+      61          12 :           if(distance < upper && distance > lower ) targets[std::make_pair(iatom,jatom)] = distance;
+      62             :         }
+      63             :       }
+      64             :     }
+      65             :   }
+      66           1 : }
+      67             : 
+      68             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html b/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..fb01cf7a58 --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_129IntramolecularDRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.func.html b/coverage/reference/IntramolecularDRMSD.cpp.func.html new file mode 100644 index 0000000000..01874af7d2 --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev4168
_ZN4PLMD19IntramolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntramolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntramolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntramolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.gcov.html b/coverage/reference/IntramolecularDRMSD.cpp.gcov.html new file mode 100644 index 0000000000..295b25d83d --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_METRIC(IntramolecularDRMSD,"INTRA-DRMSD")
+      38             : 
+      39           1 : IntramolecularDRMSD::IntramolecularDRMSD( const ReferenceConfigurationOptions& ro ):
+      40             :   ReferenceConfiguration( ro ),
+      41             :   DRMSD( ro ),
+      42           1 :   nblocks(0)
+      43             : {
+      44           1 : }
+      45             : 
+      46           1 : void IntramolecularDRMSD::read( const PDB& pdb ) {
+      47           1 :   readAtomsFromPDB( pdb, true ); nblocks = pdb.getNumberOfAtomBlocks(); blocks.resize( nblocks+1 );
+      48           1 :   if( nblocks==1 ) error("Trying to compute intramolecular rmsd but found no TERs in input PDB");
+      49           3 :   blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      50           1 :   readBounds( pdb ); setup_targets();
+      51           1 : }
+      52             : 
+      53           1 : void IntramolecularDRMSD::setup_targets() {
+      54           1 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      55             : 
+      56           3 :   for(unsigned i=0; i<nblocks; ++i) {
+      57           7 :     for(unsigned iatom=blocks[i]+1; iatom<blocks[i+1]; ++iatom) {
+      58          14 :       for(unsigned jatom=blocks[i]; jatom<iatom; ++jatom) {
+      59           9 :         double distance = delta( getReferencePosition(iatom), getReferencePosition(jatom) ).modulo();
+      60           9 :         if(distance < upper && distance > lower ) targets[std::make_pair(iatom,jatom)] = distance;
+      61             :       }
+      62             :     }
+      63             :   }
+      64           1 : }
+      65             : 
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html b/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html new file mode 100644 index 0000000000..4363d83543 --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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_129MahalanobisDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.func.html b/coverage/reference/MahalanobisDistance.cpp.func.html new file mode 100644 index 0000000000..58bfa81ea2 --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev4168
_ZN4PLMD19MahalanobisDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD19MahalanobisDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.gcov.html b/coverage/reference/MahalanobisDistance.cpp.gcov.html new file mode 100644 index 0000000000..95b3626b05 --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.gcov.html @@ -0,0 +1,117 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_METRIC(MahalanobisDistance,"MAHALANOBIS")
+      33             : 
+      34           0 : MahalanobisDistance::MahalanobisDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36           0 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38           0 :   hasmetric=true;
+      39           0 : }
+      40             : 
+      41             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.func-sort-c.html b/coverage/reference/MetricRegister.cpp.func-sort-c.html new file mode 100644 index 0000000000..bd8d15746b --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegisterD2Ev4168
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE45848
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE45848
_ZN4PLMD14MetricRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518879
_ZN4PLMD14metricRegisterEv610575
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.func.html b/coverage/reference/MetricRegister.cpp.func.html new file mode 100644 index 0000000000..a2efd04986 --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE45848
_ZN4PLMD14MetricRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518879
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE45848
_ZN4PLMD14MetricRegisterD2Ev4168
_ZN4PLMD14metricRegisterEv610575
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.gcov.html b/coverage/reference/MetricRegister.cpp.gcov.html new file mode 100644 index 0000000000..8471b546b8 --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.gcov.html @@ -0,0 +1,134 @@ + + + + + + + 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-05-27 13:05: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        4168 : MetricRegister::~MetricRegister() {
+      28        4168 :   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        4168 : }
+      34             : 
+      35      610575 : MetricRegister& metricRegister() {
+      36      610575 :   static MetricRegister ans;
+      37      610575 :   return ans;
+      38             : }
+      39             : 
+      40       45848 : void MetricRegister::remove(creator_pointer f) {
+      41      266752 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      42      266752 :     if((*p).second==f) {
+      43       45848 :       m.erase(p); break;
+      44             :     }
+      45             :   }
+      46       45848 : }
+      47             : 
+      48       45848 : void MetricRegister::add( std::string type, creator_pointer f ) {
+      49           0 :   plumed_massert(m.count(type)==0,"type has already been registered");
+      50       45848 :   m.insert(std::pair<std::string,creator_pointer>(type,f));
+      51       45848 : }
+      52             : 
+      53      518879 : bool MetricRegister::check(const std::string & type) {
+      54      518879 :   if( m.count(type)>0 ) return true;
+      55             :   return false;
+      56             : }
+      57             : 
+      58             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.func-sort-c.html b/coverage/reference/MetricRegister.h.func-sort-c.html new file mode 100644 index 0000000000..338867aa42 --- /dev/null +++ b/coverage/reference/MetricRegister.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_traitsIcESaIcEEE77
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE77
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518743
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE518743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.func.html b/coverage/reference/MetricRegister.h.func.html new file mode 100644 index 0000000000..a18b1cda8e --- /dev/null +++ b/coverage/reference/MetricRegister.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_traitsIcESaIcEEE77
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE77
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.gcov.html b/coverage/reference/MetricRegister.h.gcov.html new file mode 100644 index 0000000000..91f17e5856 --- /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-05-27 13:05: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(const std::string & type);
+      53             : /// Create a reference configuration and don't set a point of reference
+      54             :   template <class T>
+      55             :   std::unique_ptr<T> create( const std::string& type );
+      56             : /// Create a reference configuration and set the point of reference from the pdb
+      57             :   template <class T>
+      58             :   std::unique_ptr<T> create( const std::string& type, const PDB& pdb );
+      59             : };
+      60             : 
+      61             : MetricRegister& metricRegister();
+      62             : 
+      63             : #define PLUMED_REGISTER_METRIC(classname,type) \
+      64             :   namespace { class classname##RegisterMe{ \
+      65             :     static std::unique_ptr<ReferenceConfiguration> create(const PLMD::ReferenceConfigurationOptions&ro){return PLMD::Tools::make_unique<classname>(ro);} \
+      66             :   public: \
+      67             :     classname##RegisterMe(){PLMD::metricRegister().add(type,create);}; \
+      68             :     ~classname##RegisterMe(){PLMD::metricRegister().remove(create);}; \
+      69             :   } classname##RegisterMeObject; }
+      70             : 
+      71             : template <class T>
+      72      518879 : std::unique_ptr<T> MetricRegister::create( const std::string& type ) {
+      73             :   std::string ftype;
+      74      518879 :   if( type.find("MULTI-")!=std::string::npos ) {
+      75             :     ftype="MULTI";
+      76             :   } else {
+      77      518874 :     std::size_t dash=type.find("-FAST"); // We must remove the fast label
+      78     1037748 :     ftype=type.substr(0,dash);
+      79             :   }
+      80      518879 :   plumed_massert( check(ftype), "metric " + ftype + " does not exist" );
+      81      518879 :   ReferenceConfigurationOptions ro( type );
+      82             : // put immediately the result in a safe pointer
+      83      518879 :   std::unique_ptr<ReferenceConfiguration> conf( m[ftype]( ro ) );
+      84             : // try conversion
+      85         136 :   T*ptr=dynamic_cast<T*>( conf.get() );
+      86             : // if this throws, the unique_ptr conf is deleted.
+      87             : // Notice that with the original version of the code (2.4) an error here
+      88             : // would have lead to a memory leak.
+      89      518879 :   if(!ptr ) plumed_merror( type + " metric is not valid in this context");
+      90             : // release ownership in order to transfer it to returned pointer
+      91             :   conf.release();
+      92             : // notice that I should pass ptr here rather than conf.release(),
+      93             : // since the type is different
+      94             : // cppcheck-suppress returnDanglingLifetime
+      95      518879 :   return std::unique_ptr<T>(ptr);
+      96      518879 : }
+      97             : 
+      98             : template <class T>
+      99      518823 : std::unique_ptr<T> MetricRegister::create( const std::string& type, const PDB& pdb ) {
+     100             :   std::string rtype;
+     101      518823 :   if( type.length()==0 ) {
+     102          20 :     rtype=pdb.getMtype();
+     103          10 :     plumed_massert(rtype.length()>0, "TYPE not specified in pdb input file");
+     104             :   } else {
+     105             :     rtype=type;
+     106             :   }
+     107      518823 :   std::unique_ptr<T> confout( create<T>( rtype ) );
+     108      518823 :   confout->read( pdb );
+     109      518823 :   return confout;
+     110           0 : }
+     111             : 
+     112             : }
+     113             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html b/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..b00f281144 --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_125MultiDomainRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.func.html b/coverage/reference/MultiDomainRMSD.cpp.func.html new file mode 100644 index 0000000000..0a79c418a4 --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev4168
_ZN4PLMD15MultiDomainRMSD15setupPCAStorageERNS_18ReferenceValuePackE2
_ZN4PLMD15MultiDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
_ZN4PLMD15MultiDomainRMSD28pcaIsEnabledForThisReferenceEv2
_ZN4PLMD15MultiDomainRMSD4readERKNS_3PDBE5
_ZN4PLMD15MultiDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD15MultiDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD15MultiDomainRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD15MultiDomainRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE44
_ZNK4PLMD15MultiDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb22
_ZNK4PLMD15MultiDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb37
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.gcov.html b/coverage/reference/MultiDomainRMSD.cpp.gcov.html new file mode 100644 index 0000000000..c97d9b40b0 --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.gcov.html @@ -0,0 +1,285 @@ + + + + + + + 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-05-27 13:05: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       12514 : PLUMED_REGISTER_METRIC(MultiDomainRMSD,"MULTI")
+      30             : 
+      31           5 : MultiDomainRMSD::MultiDomainRMSD( const ReferenceConfigurationOptions& ro ):
+      32             :   ReferenceConfiguration(ro),
+      33             :   ReferenceAtoms(ro),
+      34           5 :   ftype(ro.getMultiRMSDType())
+      35             : {
+      36           5 : }
+      37             : 
+      38           5 : void MultiDomainRMSD::read( const PDB& pdb ) {
+      39           5 :   unsigned nblocks =  pdb.getNumberOfAtomBlocks();
+      40           5 :   if( nblocks<2 ) error("multidomain RMSD only has one block of atoms");
+      41             : 
+      42             :   std::vector<Vector> positions; std::vector<double> align, displace;
+      43           5 :   std::string num; blocks.resize( nblocks+1 ); blocks[0]=0;
+      44          15 :   for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      45             : 
+      46             :   double tmp, lower=0.0, upper=std::numeric_limits<double>::max( );
+      47          10 :   if( pdb.getArgumentValue("LOWER_CUTOFF",tmp) ) lower=tmp;
+      48          10 :   if( pdb.getArgumentValue("UPPER_CUTOFF",tmp) ) upper=tmp;
+      49           5 :   bool nopbc=pdb.hasFlag("NOPBC");
+      50             : 
+      51           5 :   domains.resize(0); weights.resize(0);
+      52          15 :   for(unsigned i=1; i<=nblocks; ++i) {
+      53          10 :     Tools::convert(i,num);
+      54          10 :     if( ftype=="RMSD" ) {
+      55             :       // parse("TYPE"+num, ftype );
+      56             :       lower=0.0; upper=std::numeric_limits<double>::max( );
+      57           0 :       if( pdb.getArgumentValue("LOWER_CUTOFF"+num,tmp) ) lower=tmp;
+      58           0 :       if( pdb.getArgumentValue("UPPER_CUTOFF"+num,tmp) ) upper=tmp;
+      59           0 :       nopbc=pdb.hasFlag("NOPBC");
+      60             :     }
+      61          10 :     domains.emplace_back( metricRegister().create<SingleDomainRMSD>( ftype ) );
+      62          10 :     positions.resize( blocks[i] - blocks[i-1] );
+      63          10 :     align.resize( blocks[i] - blocks[i-1] );
+      64          10 :     displace.resize( blocks[i] - blocks[i-1] );
+      65             :     unsigned n=0;
+      66          69 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) {
+      67          59 :       positions[n]=pdb.getPositions()[j];
+      68          59 :       align[n]=pdb.getOccupancy()[j];
+      69          59 :       displace[n]=pdb.getBeta()[j];
+      70          59 :       n++;
+      71             :     }
+      72          10 :     domains[i-1]->setBoundsOnDistances( !nopbc, lower, upper );
+      73          10 :     domains[i-1]->setReferenceAtoms( positions, align, displace );
+      74          10 :     domains[i-1]->setupRMSDObject();
+      75             : 
+      76          10 :     double ww=0;
+      77          20 :     if( !pdb.getArgumentValue("WEIGHT"+num,ww) ) weights.push_back( 1.0 );
+      78           0 :     else weights.push_back( ww );
+      79             :   }
+      80             :   // And set the atom numbers for this object
+      81           5 :   indices.resize(0); atom_der_index.resize(0);
+      82          64 :   for(unsigned i=0; i<pdb.size(); ++i) { indices.push_back( pdb.getAtomNumbers()[i] ); atom_der_index.push_back(i); }
+      83             :   // setAtomNumbers( pdb.getAtomNumbers() );
+      84           5 : }
+      85             : 
+      86           0 : void MultiDomainRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      87           0 :   plumed_error();
+      88             : }
+      89             : 
+      90          37 : double MultiDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      91          37 :   double totd=0.; Tensor tvirial; std::vector<Vector> mypos; MultiValue tvals( 1, 3*pos.size()+9 );
+      92          37 :   ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals ); myder.clear();
+      93             : 
+      94         111 :   for(unsigned i=0; i<domains.size(); ++i) {
+      95             :     // Must extract appropriate positions here
+      96          74 :     mypos.resize( blocks[i+1] - blocks[i] );
+      97          74 :     if( myder.calcUsingPCAOption() ) domains[i]->setupPCAStorage( tder );
+      98         453 :     unsigned n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { tder.setAtomIndex(n,j); mypos[n]=pos[j]; n++; }
+      99         453 :     for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*pos.size()+10);
+     100             :     // This actually does the calculation
+     101          74 :     totd += weights[i]*domains[i]->calculate( mypos, pbc, tder, true );
+     102             :     // Now merge the derivative
+     103          74 :     myder.copyScaledDerivatives( 0, weights[i], tvals );
+     104             :     // If PCA copy PCA stuff
+     105          74 :     if( myder.calcUsingPCAOption() ) {
+     106             :       unsigned n=0;
+     107          44 :       if( tder.centeredpos.size()>0 ) myder.rot[i]=tder.rot[0];
+     108         198 :       for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
+     109         154 :         myder.displacement[j]=weights[i]*tder.displacement[n];  // Multiplication by weights here ensures that normalisation is done correctly
+     110         154 :         if( tder.centeredpos.size()>0 ) {
+     111          77 :           myder.centeredpos[j]=tder.centeredpos[n];
+     112        1001 :           for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) myder.DRotDPos(p,q)[j]=tder.DRotDPos(p,q)[n];
+     113             :         }
+     114         154 :         n++;
+     115             :       }
+     116             :     }
+     117             :     // Make sure virial status is set correctly in output derivative pack
+     118             :     // This is only done here so I do this by using class friendship
+     119          74 :     if( tder.virialWasSet() ) myder.boxWasSet=true;
+     120             :   }
+     121          37 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+     122             : 
+     123          37 :   if( !squared ) {
+     124          15 :     totd=std::sqrt(totd); double xx=0.5/totd;
+     125          15 :     myder.scaleAllDerivatives( xx );
+     126             :   }
+     127          37 :   return totd;
+     128          37 : }
+     129             : 
+     130          22 : double MultiDomainRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg,
+     131             :                               ReferenceValuePack& myder, const bool& squared ) const {
+     132             :   plumed_dbg_assert( vals.size()==0 && pos.size()==getNumberOfAtoms() && arg.size()==0 );
+     133          22 :   return calculate( pos, pbc, myder, squared );
+     134             : }
+     135             : 
+     136           2 : bool MultiDomainRMSD::pcaIsEnabledForThisReference() {
+     137             :   bool enabled=true;
+     138           6 :   for(unsigned i=0; i<domains.size(); ++i) {
+     139           4 :     if( !domains[i]->pcaIsEnabledForThisReference() ) enabled=false;
+     140             :   }
+     141           2 :   return enabled;
+     142             : }
+     143             : 
+     144           2 : void MultiDomainRMSD::setupPCAStorage( ReferenceValuePack& mypack ) {
+     145             :   plumed_dbg_assert( pcaIsEnabledForThisReference() );
+     146             :   mypack.switchOnPCAOption();
+     147           2 :   mypack.displacement.resize( getNumberOfAtoms() );
+     148           2 :   mypack.centeredpos.resize( getNumberOfAtoms() );
+     149           2 :   mypack.DRotDPos.resize(3,3); mypack.rot.resize( domains.size() );
+     150          26 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) mypack.DRotDPos(i,j).resize( getNumberOfAtoms() );
+     151           2 : }
+     152             : 
+     153             : // Vector MultiDomainRMSD::getAtomicDisplacement( const unsigned& iatom ){
+     154             : //   for(unsigned i=0;i<domains.size();++i){
+     155             : //       unsigned n=0;
+     156             : //       for(unsigned j=blocks[i];j<blocks[i+1];++j){
+     157             : //           if( j==iatom ) return weights[i]*domains[i]->getAtomicDisplacement(n);
+     158             : //           n++;
+     159             : //       }
+     160             : //   }
+     161             : // }
+     162             : 
+     163           0 : void MultiDomainRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+     164             :   std::vector<Vector> mypos, mydir;
+     165           0 :   for(unsigned i=0; i<domains.size(); ++i) {
+     166             :     // Must extract appropriate positions here
+     167           0 :     mypos.resize( blocks[i+1] - blocks[i] ); mydir.resize( blocks[i+1] - blocks[i] );
+     168           0 :     unsigned n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { mypos[n]=pos[j]; n++; }
+     169             :     // Do the calculation
+     170           0 :     domains[i]->extractAtomicDisplacement( mypos, mydir );
+     171             :     // Extract the direction
+     172           0 :     n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { direction[j]=weights[i]*mydir[n];  n++; }
+     173             :   }
+     174           0 : }
+     175             : 
+     176          44 : double MultiDomainRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+     177          44 :   double totd=0.; std::vector<Vector> tvecs; mypack.clear();
+     178          44 :   MultiValue tvals( 1, mypack.getNumberOfDerivatives() ); ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals );
+     179         132 :   for(unsigned i=0; i<domains.size(); ++i) {
+     180             :     // Must extract appropriate positions here
+     181          88 :     tvecs.resize( blocks[i+1] - blocks[i] ); domains[i]->setupPCAStorage( tder );
+     182          88 :     if( tder.centeredpos.size()>0 ) {
+     183         572 :       for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q).resize( tvecs.size() );
+     184             :     }
+     185             :     // Extract information from storage pack and put in local pack
+     186          88 :     if( tder.centeredpos.size()>0 ) tder.rot[0]=mypack.rot[i];
+     187             :     unsigned n=0;
+     188         396 :     for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
+     189         308 :       tder.setAtomIndex(n,j); tvecs[n] = vecs[j]; tder.displacement[n]=mypack.displacement[j] / weights[i];
+     190         308 :       if( tder.centeredpos.size()>0 ) {
+     191         154 :         tder.centeredpos[n]=mypack.centeredpos[j];
+     192        2002 :         for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q)[n]=mypack.DRotDPos(p,q)[j];
+     193             :       }
+     194         308 :       n++;
+     195             :     }
+     196         396 :     for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*vecs.size()+10);
+     197             : 
+     198             :     // Do the calculations
+     199          88 :     totd += weights[i]*domains[i]->projectAtomicDisplacementOnVector( normalized, tvecs, tder );
+     200             : 
+     201             :     // And derivatives
+     202          88 :     mypack.copyScaledDerivatives( 0, weights[i], tvals );
+     203             :   }
+     204          44 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+     205             : 
+     206          44 :   return totd;
+     207          44 : }
+     208             : 
+     209             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html b/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 0000000000..bb5f3f38ae --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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_137NormalizedEuclideanDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.func.html b/coverage/reference/NormalizedEuclideanDistance.cpp.func.html new file mode 100644 index 0000000000..b9ecd3b59d --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev4168
_ZN4PLMD27NormalizedEuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD27NormalizedEuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html b/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html new file mode 100644 index 0000000000..f4fabd3d26 --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html @@ -0,0 +1,117 @@ + + + + + + + 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-05-27 13:05: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       12504 : PLUMED_REGISTER_METRIC(NormalizedEuclideanDistance,"NORM-EUCLIDEAN")
+      33             : 
+      34           0 : NormalizedEuclideanDistance::NormalizedEuclideanDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36           0 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38           0 :   hasweights=true;
+      39           0 : }
+      40             : 
+      41             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.func-sort-c.html b/coverage/reference/OptimalRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..279c3c7884 --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_121OptimalRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev4168
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.func.html b/coverage/reference/OptimalRMSD.cpp.func.html new file mode 100644 index 0000000000..3db2789779 --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_121OptimalRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev4168
_ZNK4PLMD11OptimalRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_1107
_ZNK4PLMD11OptimalRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE1158
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.gcov.html b/coverage/reference/OptimalRMSD.cpp.gcov.html new file mode 100644 index 0000000000..d03d70c38b --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + 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-05-27 13:05: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       13378 : PLUMED_REGISTER_METRIC(OptimalRMSD,"OPTIMAL")
+      50             : 
+      51         437 : OptimalRMSD::OptimalRMSD(const ReferenceConfigurationOptions& ro ):
+      52             :   ReferenceConfiguration(ro),
+      53         437 :   RMSDBase(ro)
+      54             : {
+      55         437 :   fast=ro.usingFastOption();
+      56         437 : }
+      57             : 
+      58         427 : void OptimalRMSD::read( const PDB& pdb ) {
+      59         427 :   readReference( pdb ); setupRMSDObject();
+      60         427 : }
+      61             : 
+      62      218933 : double OptimalRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      63             :   double d;
+      64      218933 :   if( myder.calcUsingPCAOption() ) {
+      65        2786 :     std::vector<Vector> centeredreference( getNumberOfAtoms () );
+      66        2786 :     d=myrmsd.calc_PCAelements(pos,myder.getAtomVector(),myder.rot[0],myder.DRotDPos,myder.getAtomsDisplacementVector(),myder.centeredpos,centeredreference,squared);
+      67        2786 :     unsigned nat = pos.size();
+      68       48548 :     for(unsigned i=0; i<nat; ++i) { myder.getAtomsDisplacementVector()[i] -= getReferencePosition(i); myder.getAtomsDisplacementVector()[i] *= getDisplace()[i]; }
+      69      216147 :   } else if( fast ) {
+      70      192640 :     if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<false,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      71           2 :     else d=myrmsd.optimalAlignment<false,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      72             :   } else {
+      73       23507 :     if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<true,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      74         111 :     else d=myrmsd.optimalAlignment<true,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      75             :   }
+      76    17762561 :   myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
+      77      218933 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      78      218933 :   return d;
+      79             : }
+      80             : 
+      81        1107 : void OptimalRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+      82        1107 :   std::vector<Tensor> rot(1);  Matrix<std::vector<Vector> > DRotDPos( 3, 3 );
+      83        1107 :   std::vector<Vector> centeredreference( getNumberOfAtoms() ), centeredpos( getNumberOfAtoms() ), avector( getNumberOfAtoms() );
+      84        1107 :   myrmsd.calc_PCAelements(pos,avector,rot[0],DRotDPos,direction,centeredpos,centeredreference,true);
+      85       15498 :   unsigned nat = pos.size(); for(unsigned i=0; i<nat; ++i) direction[i] = getDisplace()[i]*( direction[i] - getReferencePosition(i) );
+      86        1107 : }
+      87             : 
+      88        1158 : double OptimalRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+      89             :   plumed_dbg_assert( mypack.calcUsingPCAOption() );
+      90             : 
+      91        1158 :   double proj=0.0; mypack.clear();
+      92       15662 :   for(unsigned i=0; i<vecs.size(); ++i) {
+      93       14504 :     proj += dotProduct( mypack.getAtomsDisplacementVector()[i], vecs[i] );
+      94             :   }
+      95        4632 :   for(unsigned a=0; a<3; a++) {
+      96       13896 :     for(unsigned b=0; b<3; b++) {
+      97      140958 :       double tmp1=0.; for(unsigned n=0; n<getNumberOfAtoms(); n++) tmp1+=mypack.centeredpos[n][b]*vecs[n][a];
+      98             : 
+      99      140958 :       for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     100      130536 :         if( normalized ) mypack.addAtomDerivatives( iat, getDisplace()[iat]*mypack.DRotDPos[a][b][iat]*tmp1 );
+     101      127764 :         else mypack.addAtomDerivatives( iat, mypack.DRotDPos[a][b][iat]*tmp1 );
+     102             :       }
+     103             :     }
+     104             :   }
+     105        1158 :   Tensor trot=mypack.rot[0].transpose();
+     106        1158 :   Vector v1; v1.zero(); double prefactor = 1. / static_cast<double>( getNumberOfAtoms() );
+     107       15662 :   for(unsigned n=0; n<getNumberOfAtoms(); n++) v1+=prefactor*matmul(trot,vecs[n]);
+     108        1158 :   if( normalized ) {
+     109         374 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, getDisplace()[iat]*(matmul(trot,vecs[iat]) - v1) );
+     110             :   } else {
+     111       15288 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, (matmul(trot,vecs[iat]) - v1) );
+     112             :   }
+     113        1158 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+     114             : 
+     115        1158 :   return proj;
+     116             : }
+     117             : 
+     118             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.func-sort-c.html b/coverage/reference/RMSDBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..45bf62c6bc --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE472
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40496
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.func.html b/coverage/reference/RMSDBase.cpp.func.html new file mode 100644 index 0000000000..56ab980b8c --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE472
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40496
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.gcov.html b/coverage/reference/RMSDBase.cpp.gcov.html new file mode 100644 index 0000000000..071dc90f6f --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + 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-05-27 13:05: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         472 : RMSDBase::RMSDBase( const ReferenceConfigurationOptions& ro ):
+      27             :   ReferenceConfiguration(ro),
+      28         472 :   SingleDomainRMSD(ro)
+      29             : {
+      30         472 : }
+      31             : 
+      32       40496 : double RMSDBase::calculate( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      33             : //  clearDerivatives();
+      34       40496 :   return calc( pos, myder, squared );
+      35             : }
+      36             : 
+      37      178609 : double RMSDBase::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      38             :   plumed_dbg_assert( pos.size()==getNumberOfAtoms() );
+      39      178609 :   return calc( pos, myder, squared );
+      40             : }
+      41             : 
+      42             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.func-sort-c.html b/coverage/reference/ReferenceArguments.cpp.func-sort-c.html new file mode 100644 index 0000000000..0c93019e32 --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.func.html b/coverage/reference/ReferenceArguments.cpp.func.html new file mode 100644 index 0000000000..6801030d42 --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.gcov.html b/coverage/reference/ReferenceArguments.cpp.gcov.html new file mode 100644 index 0000000000..8826d9f6d8 --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.gcov.html @@ -0,0 +1,280 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.func-sort-c.html b/coverage/reference/ReferenceArguments.h.func-sort-c.html new file mode 100644 index 0000000000..e35c399aff --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.func.html b/coverage/reference/ReferenceArguments.h.func.html new file mode 100644 index 0000000000..cfb7a41934 --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.gcov.html b/coverage/reference/ReferenceArguments.h.gcov.html new file mode 100644 index 0000000000..565a744d61 --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html b/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html new file mode 100644 index 0000000000..7448dd90e4 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb688
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE724
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.func.html b/coverage/reference/ReferenceAtoms.cpp.func.html new file mode 100644 index 0000000000..8d73f356e7 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb688
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE724
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.gcov.html b/coverage/reference/ReferenceAtoms.cpp.gcov.html new file mode 100644 index 0000000000..419e0c970d --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05: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         724 : ReferenceAtoms::ReferenceAtoms( const ReferenceConfigurationOptions& ro ):
+      30             :   ReferenceConfiguration(ro),
+      31         724 :   checks_were_disabled(false)
+      32             : {
+      33         724 : }
+      34             : 
+      35         688 : void ReferenceAtoms::readAtomsFromPDB( const PDB& pdb, const bool allowblocks  ) {
+      36         688 :   if( !allowblocks && pdb.getNumberOfAtomBlocks()!=1 ) error("found multi-atom-block pdb format but expecting only one block of atoms");
+      37             : 
+      38         688 :   indices.resize(0); reference_atoms.resize(0); align.resize(0); displace.resize(0); atom_der_index.resize(0);
+      39       10045 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      40        9357 :     indices.push_back( pdb.getAtomNumbers()[i] ); reference_atoms.push_back( pdb.getPositions()[i] );
+      41        9357 :     align.push_back( pdb.getOccupancy()[i] ); displace.push_back( pdb.getBeta()[i] ); atom_der_index.push_back(i);
+      42             :   }
+      43         688 : }
+      44             : 
+      45             : // void ReferenceAtoms::setAtomNumbers( const std::vector<AtomNumber>& numbers ) {
+      46             : //   reference_atoms.resize( numbers.size() ); align.resize( numbers.size() );
+      47             : //   displace.resize( numbers.size() ); atom_der_index.resize( numbers.size() );
+      48             : //   indices.resize( numbers.size() );
+      49             : //   for(unsigned i=0; i<numbers.size(); ++i) {
+      50             : //     indices[i]=numbers[i]; atom_der_index[i]=i;
+      51             : //   }
+      52             : // }
+      53             : 
+      54             : // void ReferenceAtoms::printAtoms( OFile& ofile, const double& lunits ) const {
+      55             : //   plumed_assert( indices.size()==reference_atoms.size() && align.size()==reference_atoms.size() && displace.size()==reference_atoms.size() );
+      56             : //   for(unsigned i=0; i<reference_atoms.size(); ++i) {
+      57             : //     ofile.printf("ATOM  %5d  X   RES  %4u    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+      58             : //                  indices[i].serial(), i,
+      59             : //                  lunits*reference_atoms[i][0], lunits*reference_atoms[i][1], lunits*reference_atoms[i][2],
+      60             : //                  align[i], displace[i] );
+      61             : //   }
+      62             : // }
+      63             : 
+      64             : // bool ReferenceAtoms::parseAtomList( const std::string& key, std::vector<unsigned>& numbers ) {
+      65             : //   plumed_assert( numbers.size()==0 );
+      66             : //
+      67             : //   std::vector<std::string> strings;
+      68             : //   if( !parseVector(key,strings,true) ) return false;
+      69             : //   Tools::interpretRanges(strings);
+      70             : //
+      71             : //   numbers.resize( strings.size() );
+      72             : //   for(unsigned i=0; i<strings.size(); ++i) {
+      73             : //     AtomNumber atom;
+      74             : //     if( !Tools::convert(strings[i],atom ) ) error("could not convert " + strings[i] + " into atom number");
+      75             : //
+      76             : //     bool found=false;
+      77             : //     for(unsigned j=0; j<indices.size(); ++j) {
+      78             : //       if( atom==indices[j] ) { found=true; numbers[i]=j; break; }
+      79             : //     }
+      80             : //     if(!found) error("atom labelled " + strings[i] + " is not present in pdb input file");
+      81             : //   }
+      82             : //   return true;
+      83             : // }
+      84             : 
+      85         455 : void ReferenceAtoms::getAtomRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      86         455 :   singleDomainRequests(numbers,disable_checks);
+      87         455 : }
+      88             : 
+      89         455 : void ReferenceAtoms::singleDomainRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      90         455 :   checks_were_disabled=disable_checks;
+      91         455 :   atom_der_index.resize( indices.size() );
+      92             : 
+      93         455 :   if( numbers.size()==0 ) {
+      94        4220 :     for(unsigned i=0; i<indices.size(); ++i) {
+      95        4113 :       numbers.push_back( indices[i] );
+      96        4113 :       atom_der_index[i]=i;
+      97             :     }
+      98             :   } else {
+      99         348 :     if(!disable_checks) {
+     100         348 :       if( numbers.size()!=indices.size() ) error("mismatched numbers of atoms in pdb frames");
+     101             :     }
+     102             : 
+     103        4812 :     for(unsigned i=0; i<indices.size(); ++i) {
+     104             :       bool found=false;
+     105        4464 :       if(!disable_checks) {
+     106        4464 :         if( indices[i]!=numbers[i] ) error("found mismatched reference atoms in pdb frames");
+     107        4464 :         atom_der_index[i]=i;
+     108             :       } else {
+     109           0 :         for(unsigned j=0; j<numbers.size(); ++j) {
+     110           0 :           if( indices[i]==numbers[j] ) { found=true; atom_der_index[i]=j; break; }
+     111             :         }
+     112             :         if( !found ) {
+     113           0 :           atom_der_index[i]=numbers.size(); numbers.push_back( indices[i] );
+     114             :         }
+     115             :       }
+     116             :     }
+     117             :   }
+     118         455 : }
+     119             : 
+     120         494 : void ReferenceAtoms::displaceReferenceAtoms( const double& weight, const std::vector<Vector>& dir ) {
+     121             :   plumed_dbg_assert( dir.size()==reference_atoms.size() );
+     122         715 :   for(unsigned i=0; i<dir.size(); ++i) reference_atoms[i] += weight*dir.size()*dir[i];
+     123         494 : }
+     124             : 
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.func-sort-c.html b/coverage/reference/ReferenceAtoms.h.func-sort-c.html new file mode 100644 index 0000000000..1b57a77258 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636058
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.func.html b/coverage/reference/ReferenceAtoms.h.func.html new file mode 100644 index 0000000000..0dcdb892db --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636058
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.gcov.html b/coverage/reference/ReferenceAtoms.h.gcov.html new file mode 100644 index 0000000000..582bb4b9fe --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.gcov.html @@ -0,0 +1,239 @@ + + + + + + + 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-05-27 13:05: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      216774 :   return align;
+     119             : }
+     120             : 
+     121             : inline
+     122             : const std::vector<double> & ReferenceAtoms::getDisplace() const {
+     123      216775 :   return displace;
+     124             : }
+     125             : 
+     126             : inline
+     127      150276 : unsigned ReferenceAtoms::getNumberOfReferencePositions() const {
+     128             :   plumed_dbg_assert( atom_der_index.size()==reference_atoms.size() );
+     129      150276 :   return reference_atoms.size();
+     130             : }
+     131             : 
+     132             : inline
+     133             : unsigned ReferenceAtoms::getNumberOfAtoms() const {
+     134      314250 :   return atom_der_index.size(); // reference_atoms.size();
+     135             : }
+     136             : 
+     137             : inline
+     138             : unsigned ReferenceAtoms::getAtomIndex( const unsigned& iatom ) const {
+     139             :   plumed_dbg_assert( iatom<atom_der_index.size() );
+     140             :   plumed_dbg_assert( atom_der_index[iatom]<reference_atoms.size() );
+     141     9894406 :   return atom_der_index[iatom];
+     142             : }
+     143             : 
+     144             : inline
+     145             : Vector ReferenceAtoms::getReferencePosition( const unsigned& iatom ) const {
+     146             :   plumed_dbg_assert( iatom<reference_atoms.size() );
+     147       67480 :   return reference_atoms[iatom];
+     148             : }
+     149             : 
+     150             : inline
+     151     2636058 : const std::vector<Vector> & ReferenceAtoms::getReferencePositions() const {
+     152     2636058 :   return reference_atoms;
+     153             : }
+     154             : 
+     155             : inline
+     156           4 : const std::vector<AtomNumber>& ReferenceAtoms::getAbsoluteIndexes() {
+     157           4 :   return indices;
+     158             : }
+     159             : 
+     160             : 
+     161             : }
+     162             : #endif
+     163             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html b/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html new file mode 100644 index 0000000000..4834471969 --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_29ReferenceConfigurationOptionsE519088
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519088
_ZN4PLMD22ReferenceConfigurationD2Ev519569
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.func.html b/coverage/reference/ReferenceConfiguration.cpp.func.html new file mode 100644 index 0000000000..0717331b6c --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration30displaceReferenceConfigurationERKdRNS_9DirectionE500
_ZN4PLMD22ReferenceConfiguration5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD22ReferenceConfigurationC2ERKNS_29ReferenceConfigurationOptionsE519088
_ZN4PLMD22ReferenceConfigurationD0Ev0
_ZN4PLMD22ReferenceConfigurationD2Ev519569
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519088
_ZN4PLMD8distanceERKNS_3PbcERKSt6vectorIPNS_5ValueESaIS5_EEPNS_22ReferenceConfigurationESB_RKb259099
_ZNK4PLMD22ReferenceConfiguration25extractDisplacementVectorERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IPNS_5ValueESaIS9_EERKS1_IdSaIdEERKbRNS_9DirectionE3081
_ZNK4PLMD22ReferenceConfiguration27projectDisplacementOnVectorERKNS_9DirectionERKSt6vectorIPNS_5ValueESaIS6_EERKS4_IdSaIdEERNS_18ReferenceValuePackE3588
_ZNK4PLMD22ReferenceConfiguration7getNameB5cxx11Ev284
_ZNK4PLMD22ReferenceConfiguration9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERNS_18ReferenceValuePackERKb175359
_ZNK4PLMD29ReferenceConfigurationOptions15usingFastOptionEv437
_ZNK4PLMD29ReferenceConfigurationOptions16getMultiRMSDTypeB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.gcov.html b/coverage/reference/ReferenceConfiguration.cpp.gcov.html new file mode 100644 index 0000000000..0864e87c04 --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.gcov.html @@ -0,0 +1,207 @@ + + + + + + + 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-05-27 13:05: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      519088 : ReferenceConfigurationOptions::ReferenceConfigurationOptions( const std::string& type ):
+      34      519088 :   tt(type)
+      35             : {
+      36      519088 : }
+      37             : 
+      38         437 : bool ReferenceConfigurationOptions::usingFastOption() const {
+      39         437 :   return (tt.find("-FAST")!=std::string::npos);
+      40             : }
+      41             : 
+      42           5 : std::string ReferenceConfigurationOptions::getMultiRMSDType() const {
+      43           5 :   plumed_assert( tt.find("MULTI-")!=std::string::npos );
+      44           5 :   std::size_t dot=tt.find_first_of("MULTI-");
+      45           5 :   return tt.substr(dot+6);
+      46             : }
+      47             : 
+      48      519088 : ReferenceConfiguration::ReferenceConfiguration( const ReferenceConfigurationOptions& ro ):
+      49      519088 :   name(ro.tt)
+      50             : {
+      51      519088 : }
+      52             : 
+      53      519569 : ReferenceConfiguration::~ReferenceConfiguration()
+      54             : {
+      55     1039138 : }
+      56             : 
+      57         284 : std::string ReferenceConfiguration::getName() const {
+      58         284 :   return name;
+      59             : }
+      60             : 
+      61           0 : [[noreturn]] void ReferenceConfiguration::error(const std::string& msg) {
+      62           0 :   plumed_merror("error reading reference configuration of type " + name + " : " + msg );
+      63             : }
+      64             : 
+      65      175359 : double ReferenceConfiguration::calculate( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals,
+      66             :     ReferenceValuePack& myder, const bool& squared ) const {
+      67      175359 :   std::vector<double> tmparg( vals.size() );
+      68      248599 :   for(unsigned i=0; i<vals.size(); ++i) tmparg[i]=vals[i]->get();
+      69      350718 :   return calc( pos, pbc, vals, tmparg, myder, squared );
+      70             : }
+      71             : 
+      72         500 : void ReferenceConfiguration::displaceReferenceConfiguration( const double& weight, Direction& dir ) {
+      73         500 :   ReferenceArguments* args=dynamic_cast<ReferenceArguments*>(this);
+      74         500 :   if( args ) args->displaceReferenceArguments( weight, dir.getReferenceArguments() );
+      75         500 :   ReferenceAtoms* atoms=dynamic_cast<ReferenceAtoms*>(this);
+      76         500 :   if( atoms ) atoms->displaceReferenceAtoms( weight, dir.getReferencePositions() );
+      77         500 : }
+      78             : 
+      79        3081 : void ReferenceConfiguration::extractDisplacementVector( const std::vector<Vector>& pos, const std::vector<Value*>& vals,
+      80             :     const std::vector<double>& arg, const bool& nflag,
+      81             :     Direction& mydir ) const {
+      82        3081 :   const ReferenceAtoms* atoms=dynamic_cast<const ReferenceAtoms*>( this );
+      83        3081 :   if( atoms ) atoms->extractAtomicDisplacement( pos, mydir.reference_atoms );
+      84        3081 :   const ReferenceArguments* args=dynamic_cast<const ReferenceArguments*>( this );
+      85        3081 :   if( args ) args->extractArgumentDisplacement( vals, arg, mydir.reference_args );
+      86             : 
+      87             :   // Normalize direction if required
+      88        3081 :   if( nflag ) {
+      89             :     // Calculate length of vector
+      90          10 :     double tmp, norm=0; mydir.normalized = true;
+      91          80 :     for(unsigned i=0; i<mydir.getReferencePositions().size(); ++i) {
+      92         280 :       for(unsigned k=0; k<3; ++k) { tmp=mydir.getReferencePositions()[i][k]; norm+=tmp*tmp; }
+      93             :     }
+      94          10 :     for(unsigned i=0; i<mydir.getReferenceArguments().size(); ++i) { tmp=mydir.getReferenceArguments()[i]; norm+=tmp*tmp; }
+      95          10 :     norm = std::sqrt( norm );
+      96             :     // And normalize
+      97          80 :     for(unsigned i=0; i<mydir.getReferencePositions().size(); ++i) {
+      98         280 :       for(unsigned k=0; k<3; ++k) { mydir.reference_atoms[i][k] /=norm; }
+      99             :     }
+     100          10 :     for(unsigned i=0; i<mydir.getReferenceArguments().size(); ++i) { mydir.reference_args[i] /= norm; }
+     101             :   }
+     102        3081 : }
+     103             : 
+     104        3588 : double ReferenceConfiguration::projectDisplacementOnVector( const Direction& mydir,
+     105             :     const std::vector<Value*>& vals, const std::vector<double>& arg,
+     106             :     ReferenceValuePack& mypack ) const {
+     107             :   double proj=0;
+     108        3588 :   const ReferenceAtoms* atoms=dynamic_cast<const ReferenceAtoms*>( this );
+     109        3588 :   if( atoms ) proj += atoms->projectAtomicDisplacementOnVector( mydir.normalized, mydir.getReferencePositions(), mypack );
+     110        3588 :   const ReferenceArguments* args=dynamic_cast<const ReferenceArguments*>( this );
+     111        3588 :   if( args ) proj += args->projectArgDisplacementOnVector( mydir.getReferenceArguments(), vals, arg, mypack );
+     112        3588 :   return proj;
+     113             : }
+     114             : 
+     115      259099 : double distance( const Pbc& pbc, const std::vector<Value*> & vals, ReferenceConfiguration* ref1, ReferenceConfiguration* ref2, const bool& squared ) {
+     116             :   unsigned nder;
+     117      259099 :   if( ref1->getReferencePositions().size()>0 ) nder=ref1->getReferenceArguments().size() + 3*ref1->getReferencePositions().size() + 9;
+     118      259092 :   else nder=ref1->getReferenceArguments().size();
+     119             : 
+     120      259099 :   MultiValue myvals( 1, nder ); ReferenceValuePack myder( ref1->getReferenceArguments().size(), ref1->getReferencePositions().size(), myvals );
+     121      259099 :   double dist1=ref1->calc( ref2->getReferencePositions(), pbc, vals, ref2->getReferenceArguments(), myder, squared );
+     122             : #ifndef NDEBUG
+     123             :   // Check that A - B = B - A
+     124             :   double dist2=ref2->calc( ref1->getReferencePositions(), pbc, vals, ref1->getReferenceArguments(), myder, squared );
+     125             :   plumed_dbg_assert( std::fabs(dist1-dist2)<epsilon );
+     126             : #endif
+     127      259099 :   return dist1;
+     128      259099 : }
+     129             : 
+     130             : 
+     131             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.func-sort-c.html b/coverage/reference/ReferenceConfiguration.h.func-sort-c.html new file mode 100644 index 0000000000..8f27ef752c --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.func.html b/coverage/reference/ReferenceConfiguration.h.func.html new file mode 100644 index 0000000000..577c34af51 --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.gcov.html b/coverage/reference/ReferenceConfiguration.h.gcov.html new file mode 100644 index 0000000000..3f2dcb2313 --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.gcov.html @@ -0,0 +1,249 @@ + + + + + + + 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-05-27 13:05: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      519088 : class ReferenceConfigurationOptions {
+      53             :   friend class ReferenceConfiguration;
+      54             : private:
+      55             :   std::string tt;
+      56             : public:
+      57             :   explicit ReferenceConfigurationOptions( const std::string& type );
+      58             :   bool usingFastOption() const ;
+      59             :   std::string getMultiRMSDType() const ;
+      60             : };
+      61             : 
+      62             : /// \ingroup INHERIT
+      63             : /// Abstract base class for calculating the distance from a reference configuration.
+      64             : /// A reference configuration can either have a particular set of atoms in a particular
+      65             : /// given configuration or it can be that a particular set of colvars have a particular
+      66             : /// set of values.  It could also be a combination of both.  To allow all the posible
+      67             : /// permutations and in order make it easy to add new ways of calculating the distance
+      68             : /// we have implemented this using polymorphism and multiple inheritance.  The following
+      69             : /// provides \ref AddingAMetric "information" on how to implement a new method for
+      70             : /// calculating the distance between a pair of configurations
+      71             : 
+      72             : class ReferenceConfiguration {
+      73             :   friend class SingleDomainRMSD;
+      74             :   friend double distance( const Pbc& pbc, const std::vector<Value*> & vals, ReferenceConfiguration*, ReferenceConfiguration*, const bool& squared );
+      75             : private:
+      76             : /// The name of this particular config
+      77             :   std::string name;
+      78             : /// A vector containing all the remarks from the pdb input
+      79             :   std::vector<std::string> line;
+      80             : /// These are used to do fake things when we copy frames
+      81             :   std::vector<AtomNumber> fake_atom_numbers;
+      82             :   std::vector<std::string> fake_arg_names;
+      83             : /// These are use by the distance function above
+      84             :   std::vector<Vector> fake_refatoms;
+      85             :   std::vector<double> fake_refargs;
+      86             :   std::vector<double> fake_metric;
+      87             : protected:
+      88             : /// Crash with an error
+      89             :   [[noreturn]] void error(const std::string& msg);
+      90             : public:
+      91             :   explicit ReferenceConfiguration( const ReferenceConfigurationOptions& ro );
+      92             : /// Destructor
+      93             :   virtual ~ReferenceConfiguration();
+      94             : /// Return the name of this metric
+      95             :   std::string getName() const ;
+      96             : ///
+      97             :   virtual unsigned getNumberOfReferencePositions() const ;
+      98             :   virtual unsigned getNumberOfReferenceArguments() const ;
+      99             : /// Retrieve the atoms that are required for this guy
+     100         177 :   virtual void getAtomRequests( std::vector<AtomNumber>&, bool disable_checks=false ) {}
+     101             : /// Retrieve the arguments that are required for this guy
+     102         354 :   virtual void getArgumentRequests( std::vector<std::string>&, bool disable_checks=false ) {}
+     103             : /// Do all local business for setting the configuration
+     104             :   virtual void read( const PDB& )=0;
+     105             : /// Calculate the distance from the reference configuration
+     106             :   double calculate( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, ReferenceValuePack& myder, const bool& squared=false ) const ;
+     107             : /// Calculate the distance from the reference configuration
+     108             :   virtual double calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args,
+     109             :                        ReferenceValuePack& myder, const bool& squared ) const=0;
+     110             : /// Parse something from the pdb remarks
+     111             : /// Copy derivatives from one frame to this frame
+     112             :   void copyDerivatives( const ReferenceConfiguration* );
+     113             : /// Get one of the referene arguments
+     114           0 :   virtual double getReferenceArgument( const unsigned& i ) const { plumed_error(); }
+     115             : /// These are overwritten in ReferenceArguments and ReferenceAtoms but are required here
+     116             : /// to make PLMD::distance work
+     117             :   virtual const std::vector<Vector>& getReferencePositions() const ;
+     118             :   virtual const std::vector<double>& getReferenceArguments() const ;
+     119             :   virtual const std::vector<double>& getReferenceMetric();
+     120             : /// These are overwritten in ReferenceArguments and ReferenceAtoms to make frame copying work
+     121             :   virtual const std::vector<AtomNumber>& getAbsoluteIndexes();
+     122             :   virtual const std::vector<std::string>& getArgumentNames();
+     123             : /// Extract a Direction giving you the displacement from some position
+     124             :   void extractDisplacementVector( const std::vector<Vector>& pos, const std::vector<Value*>& vals,
+     125             :                                   const std::vector<double>& arg, const bool& nflag,
+     126             :                                   Direction& mydir ) const ;
+     127             : /// Stuff for pca
+     128           0 :   virtual bool pcaIsEnabledForThisReference() { return false; }
+     129             :   double projectDisplacementOnVector( const Direction& mydir, const std::vector<Value*>& vals,
+     130             :                                       const std::vector<double>& arg, ReferenceValuePack& mypack ) const ;
+     131             : /// Stuff to setup pca
+     132           0 :   virtual void setupPCAStorage( ReferenceValuePack& mypack ) { plumed_error(); }
+     133             : /// Move the reference configuration by an amount specified using a Direction
+     134             :   void displaceReferenceConfiguration( const double& weight, Direction& dir );
+     135             : };
+     136             : 
+     137             : inline
+     138      781533 : const std::vector<Vector>& ReferenceConfiguration::getReferencePositions() const {
+     139      781533 :   return fake_refatoms;
+     140             : }
+     141             : 
+     142             : inline
+     143        2281 : const std::vector<double>& ReferenceConfiguration::getReferenceArguments() const {
+     144        2281 :   return fake_refargs;
+     145             : }
+     146             : 
+     147             : inline
+     148           0 : const std::vector<double>& ReferenceConfiguration::getReferenceMetric() {
+     149           0 :   return fake_metric;
+     150             : }
+     151             : 
+     152             : inline
+     153           8 : const std::vector<AtomNumber>& ReferenceConfiguration::getAbsoluteIndexes() {
+     154           8 :   return fake_atom_numbers;
+     155             : }
+     156             : 
+     157             : inline
+     158           2 : const std::vector<std::string>& ReferenceConfiguration::getArgumentNames() {
+     159           2 :   return fake_arg_names;
+     160             : }
+     161             : 
+     162             : inline
+     163       35978 : unsigned ReferenceConfiguration::getNumberOfReferencePositions() const {
+     164       35978 :   return 0;
+     165             : }
+     166             : 
+     167             : inline
+     168      138192 : unsigned ReferenceConfiguration::getNumberOfReferenceArguments() const {
+     169      138192 :   return 0;
+     170             : }
+     171             : 
+     172             : }
+     173             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html b/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html new file mode 100644 index 0000000000..d1b7976510 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_104
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack5clearEv241460
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452950
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471334
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.func.html b/coverage/reference/ReferenceValuePack.cpp.func.html new file mode 100644 index 0000000000..c39d1c88e9 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452950
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack5clearEv241460
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_104
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471334
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.gcov.html b/coverage/reference/ReferenceValuePack.cpp.gcov.html new file mode 100644 index 0000000000..6f32c0d1d3 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + 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-05-27 13:05: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      471334 : ReferenceValuePack::ReferenceValuePack( const unsigned& nargs, const unsigned& natoms, MultiValue& vals ):
+      27      471334 :   boxWasSet(false),
+      28      471334 :   numberOfArgs(nargs),
+      29      471334 :   oind_set(false),
+      30      471334 :   myvals(vals),
+      31      471334 :   atom_indices(myvals.getIndices()),
+      32      471334 :   pca(false)
+      33             : {
+      34      471334 :   if( atom_indices.size()!=natoms ) { atom_indices.resize( natoms ); myvals.getAtomVector().resize( natoms ); }
+      35      471334 :   if( vals.getNumberOfValues()==1 ) { oind=0; oind_set=true; }
+      36      471334 : }
+      37             : 
+      38         104 : void ReferenceValuePack::resize( const unsigned& nargs, const unsigned& natoms ) {
+      39         104 :   numberOfArgs=nargs; atom_indices.resize( natoms );
+      40         104 :   myvals.getAtomVector().resize( natoms );
+      41         104 : }
+      42             : 
+      43      452950 : void ReferenceValuePack::updateDynamicLists() {
+      44      452950 :   myvals.emptyActiveMembers();
+      45      522510 :   for(unsigned i=0; i<numberOfArgs; ++i) myvals.putIndexInActiveArray( i );
+      46    21590009 :   for(unsigned i=0; i<atom_indices.size(); ++i) {
+      47    21137059 :     unsigned nbase = numberOfArgs + 3*atom_indices[i];
+      48    21137059 :     if( atom_indices[i]<myvals.getNumberOfDerivatives() && myvals.isActive( nbase ) ) {
+      49    18164986 :       myvals.putIndexInActiveArray( nbase+0 ); myvals.putIndexInActiveArray( nbase+1 ); myvals.putIndexInActiveArray( nbase+2 );
+      50             :     }
+      51             :   }
+      52      452950 :   unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+      53             :   // zero is added to all virial components to ensure that these are active in the dynamic list
+      54             :   // if this is not done there is a problem with secondary structure variables
+      55      452950 :   if( atom_indices.size()>0 ) {
+      56     4181700 :     for(unsigned i=0; i<9; ++i) {
+      57     3763530 :       myvals.addDerivative( oind, nbase+i, 0.0 );
+      58     3763530 :       myvals.putIndexInActiveArray( nbase+i );
+      59             :     }
+      60             :   }
+      61      452950 :   myvals.completeUpdate();
+      62      452950 : }
+      63             : 
+      64      241460 : void ReferenceValuePack::clear() {
+      65      241460 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      66      241460 :   myvals.clearAll(); boxWasSet=false;
+      67      241460 : }
+      68             : 
+      69      192765 : void ReferenceValuePack::scaleAllDerivatives( const double& scalef ) {
+      70      192765 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      71             : 
+      72     8856593 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+      73     8663828 :     unsigned ider=myvals.getActiveIndex(i);
+      74     8663828 :     myvals.setDerivative( oind, ider, scalef*myvals.getDerivative( oind, ider ) );
+      75             :   }
+      76      192765 : }
+      77             : 
+      78         162 : void ReferenceValuePack::copyScaledDerivatives( const unsigned& from, const double& scalef, const MultiValue& tvals ) {
+      79             :   plumed_dbg_assert( tvals.getNumberOfDerivatives()==myvals.getNumberOfDerivatives() );
+      80        3681 :   for(unsigned i=0; i<tvals.getNumberActive(); ++i) {
+      81        3519 :     unsigned ider=tvals.getActiveIndex(i);
+      82        3519 :     myvals.addDerivative( oind, ider, scalef*tvals.getDerivative( from, ider ) );
+      83             :   }
+      84         162 : }
+      85             : 
+      86        8662 : void ReferenceValuePack::moveDerivatives( const unsigned& from, const unsigned& to ) {
+      87        8662 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      88             : 
+      89      866200 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+      90      857538 :     unsigned ider=myvals.getActiveIndex(i);
+      91      857538 :     myvals.setDerivative( to, ider, myvals.getDerivative( from, ider ) );
+      92             :   }
+      93        8662 : }
+      94             : 
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.func-sort-c.html b/coverage/reference/ReferenceValuePack.h.func-sort-c.html new file mode 100644 index 0000000000..b637866653 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17175932
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17547915
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.func.html b/coverage/reference/ReferenceValuePack.h.func.html new file mode 100644 index 0000000000..2c0ab8cd21 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17547915
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17175932
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.gcov.html b/coverage/reference/ReferenceValuePack.h.gcov.html new file mode 100644 index 0000000000..458b409fde --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.gcov.html @@ -0,0 +1,304 @@ + + + + + + + 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-05-27 13:05: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     2967600 :   plumed_dbg_assert( iatom<atom_indices.size() ); atom_indices[iatom]=jindex;
+     128             : }
+     129             : 
+     130             : inline
+     131             : unsigned ReferenceValuePack::getAtomIndex( const unsigned& iatom ) const {
+     132             :   plumed_dbg_assert( iatom<atom_indices.size() );
+     133     1788696 :   return atom_indices[iatom];
+     134             : }
+     135             : 
+     136             : inline
+     137             : void ReferenceValuePack::addArgumentDerivatives( const unsigned& iarg, const double& der ) {
+     138             :   plumed_dbg_assert( iarg<numberOfArgs && oind_set ); myvals.addDerivative( oind, iarg, der );
+     139             : }
+     140             : 
+     141             : inline
+     142             : void ReferenceValuePack::setArgumentDerivatives( const unsigned& iarg, const double& der ) {
+     143      833432 :   plumed_dbg_assert( iarg<numberOfArgs && oind_set ); myvals.setDerivative( oind, iarg, der );
+     144             : }
+     145             : 
+     146             : inline
+     147             : bool ReferenceValuePack::updateComplete() const {
+     148      520192 :   return myvals.updateComplete();
+     149             : }
+     150             : 
+     151             : inline
+     152    17547915 : void ReferenceValuePack::setAtomDerivatives( const unsigned& jder, const Vector& der ) {
+     153             :   plumed_dbg_assert( oind_set && jder<atom_indices.size() );
+     154    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 0, der[0] );
+     155    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 1, der[1] );
+     156    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 2, der[2] );
+     157    17547915 : }
+     158             : 
+     159             : inline
+     160    16356460 : void ReferenceValuePack::addAtomDerivatives( const unsigned& jder, const Vector& der ) {
+     161             :   plumed_dbg_assert( oind_set && jder<atom_indices.size() );
+     162    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 0, der[0] );
+     163    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 1, der[1] );
+     164    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 2, der[2] );
+     165    16356460 : }
+     166             : 
+     167             : inline
+     168     8268786 : void ReferenceValuePack::addBoxDerivatives( const Tensor& vir ) {
+     169             :   plumed_dbg_assert( oind_set && atom_indices.size()>0 );
+     170     8268786 :   boxWasSet=true; unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     171   107494218 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addDerivative( oind, nbase + 3*i + j, vir(i,j) );
+     172     8268786 : }
+     173             : 
+     174             : inline
+     175             : void ReferenceValuePack::setValIndex( const unsigned& ind ) {
+     176      255233 :   oind=ind; oind_set=true;
+     177             : }
+     178             : 
+     179             : inline
+     180             : bool ReferenceValuePack::virialWasSet() const {
+     181      176799 :   return boxWasSet;
+     182             : }
+     183             : 
+     184             : inline
+     185    17175932 : Vector ReferenceValuePack::getAtomDerivative( const unsigned& iatom ) const {
+     186    17175932 :   Vector tmp; plumed_dbg_assert( oind_set && iatom<atom_indices.size() );
+     187    17175932 :   tmp[0]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 0 );
+     188    17175932 :   tmp[1]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 1 );
+     189    17175932 :   tmp[2]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 2 );
+     190    17175932 :   return tmp;
+     191             : }
+     192             : 
+     193             : inline
+     194             : double ReferenceValuePack::getArgumentDerivative( const unsigned& ival ) const {
+     195             :   plumed_dbg_assert( oind_set && ival<numberOfArgs );
+     196       12614 :   return myvals.getDerivative( oind, ival );
+     197             : }
+     198             : 
+     199             : inline
+     200         600 : Tensor ReferenceValuePack::getBoxDerivatives() const {
+     201         600 :   plumed_dbg_assert( oind_set && boxWasSet ); Tensor tvir; unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     202        7800 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) tvir(i,j)=myvals.getDerivative( oind, nbase + 3*i + j );
+     203         600 :   return tvir;
+     204             : }
+     205             : 
+     206             : inline
+     207             : bool ReferenceValuePack::calcUsingPCAOption() const {
+     208      219081 :   return pca;
+     209             : }
+     210             : 
+     211             : inline
+     212             : void ReferenceValuePack::switchOnPCAOption() {
+     213         698 :   pca=true;
+     214             : }
+     215             : 
+     216             : inline
+     217             : std::vector<Vector>& ReferenceValuePack::getAtomVector() {
+     218    17766386 :   return myvals.getAtomVector();
+     219             : }
+     220             : 
+     221             : inline
+     222             : std::vector<Vector>& ReferenceValuePack::getAtomsDisplacementVector() {
+     223        3026 :   return displacement;
+     224             : }
+     225             : 
+     226             : }
+     227             : 
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.func-sort-c.html b/coverage/reference/SimpleRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..20d83c51de --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE31
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb172
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.func.html b/coverage/reference/SimpleRMSD.cpp.func.html new file mode 100644 index 0000000000..01d09d3ac8 --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE31
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev4168
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev4168
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb172
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.gcov.html b/coverage/reference/SimpleRMSD.cpp.gcov.html new file mode 100644 index 0000000000..1c905f33d1 --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + 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-05-27 13:05: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       12574 : PLUMED_REGISTER_METRIC(SimpleRMSD,"SIMPLE")
+      44             : 
+      45          35 : SimpleRMSD::SimpleRMSD( const ReferenceConfigurationOptions& ro ):
+      46             :   ReferenceConfiguration( ro ),
+      47          35 :   RMSDBase( ro )
+      48             : {
+      49          35 : }
+      50             : 
+      51          31 : void SimpleRMSD::read( const PDB& pdb ) {
+      52          31 :   readReference( pdb );
+      53          31 : }
+      54             : 
+      55         172 : double SimpleRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      56         172 :   if( myder.getAtomsDisplacementVector().size()!=pos.size() ) myder.getAtomsDisplacementVector().resize( pos.size() );
+      57         172 :   double d=myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), myder.getAtomVector(), myder.getAtomsDisplacementVector(), squared );
+      58        3997 :   myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
+      59         172 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      60         172 :   return d;
+      61             : }
+      62             : 
+      63           0 : void SimpleRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+      64           0 :   std::vector<Vector> tder( getNumberOfAtoms() );
+      65           0 :   myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), tder, direction, true );
+      66           0 :   for(unsigned i=0; i<pos.size(); ++i) direction[i] = getDisplace()[i]*direction[i];
+      67           0 : }
+      68             : 
+      69          88 : double SimpleRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+      70          88 :   plumed_dbg_assert( mypack.calcUsingPCAOption() ); Vector comder; comder.zero();
+      71         550 :   for(unsigned j=0; j<vecs.size(); ++j) {
+      72        1848 :     for(unsigned k=0; k<3; ++k) comder[k] += getAlign()[j]*vecs[j][k];
+      73             :   }
+      74             : 
+      75          88 :   double proj=0; mypack.clear();
+      76         550 :   for(unsigned j=0; j<vecs.size(); ++j) {
+      77        1848 :     for(unsigned k=0; k<3; ++k) {
+      78        1386 :       proj += vecs[j][k]*mypack.getAtomsDisplacementVector()[j][k];
+      79             :     }
+      80         462 :     mypack.setAtomDerivatives( j, vecs[j] - comder );
+      81             :   }
+      82          88 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+      83          88 :   return proj;
+      84             : }
+      85             : 
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html b/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..00f7cf80a0 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE458
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE500
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.func.html b/coverage/reference/SingleDomainRMSD.cpp.func.html new file mode 100644 index 0000000000..9dc168ec1c --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE458
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE500
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.gcov.html b/coverage/reference/SingleDomainRMSD.cpp.gcov.html new file mode 100644 index 0000000000..40a9a0ed52 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + 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-05-27 13:05: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         500 : SingleDomainRMSD::SingleDomainRMSD( const ReferenceConfigurationOptions& ro ):
+      29             :   ReferenceConfiguration(ro),
+      30         500 :   ReferenceAtoms(ro)
+      31             : {
+      32         500 : }
+      33             : 
+      34         458 : void SingleDomainRMSD::readReference( const PDB& pdb ) {
+      35         458 :   readAtomsFromPDB( pdb );
+      36             :   double wa=0, wd=0;
+      37        9071 :   for(unsigned i=0; i<pdb.size(); ++i) { wa+=align[i]; wd+=displace[i]; }
+      38             : 
+      39         458 :   if(wa>epsilon) {
+      40         456 :     double w=1.0/wa;
+      41        9039 :     for(unsigned i=0; i<pdb.size(); ++i) align[i] *= w;
+      42             :   } else {
+      43           2 :     double w=1.0/pdb.size();
+      44          32 :     for(unsigned i=0; i<pdb.size(); ++i) align[i] = w;
+      45             :   }
+      46             : 
+      47         458 :   if(wd>epsilon) {
+      48         456 :     double w=1.0/wd;
+      49        9039 :     for(unsigned i=0; i<pdb.size(); ++i) displace[i] *= w;
+      50             :   } else {
+      51           2 :     double w=1.0/pdb.size();
+      52          32 :     for(unsigned i=0; i<pdb.size(); ++i) displace[i] = w;
+      53             :   }
+      54             : 
+      55         458 :   Vector center;
+      56        9071 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      57        8613 :     center+=reference_atoms[i]*align[i];
+      58             :   }
+      59        9071 :   for(unsigned i=0; i<pdb.size(); ++i) reference_atoms[i]-=center;
+      60         458 : }
+      61             : 
+      62          45 : void SingleDomainRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      63          45 :   reference_atoms.resize( conf.size() ); align.resize( conf.size() );
+      64          45 :   displace.resize( conf.size() ); atom_der_index.resize( conf.size() );
+      65             :   double wa=0, wd=0;
+      66        1154 :   for(unsigned i=0; i<conf.size(); ++i) { wa+=align_in[i]; wd+=displace_in[i]; }
+      67             : 
+      68          45 :   if(wa>epsilon) {
+      69          44 :     double w=1.0/wa;
+      70        1145 :     for(unsigned i=0; i<conf.size(); ++i) align[i] = align_in[i] * w;
+      71             :   } else {
+      72           1 :     double w=1.0/conf.size();
+      73           9 :     for(unsigned i=0; i<conf.size(); ++i) align[i] = w;
+      74             :   }
+      75             : 
+      76          45 :   if(wd>epsilon) {
+      77          44 :     double w=1.0/wd;
+      78        1146 :     for(unsigned i=0; i<conf.size(); ++i) displace[i] = displace_in[i] * w;
+      79             :   } else {
+      80           1 :     double w=1.0/conf.size();
+      81           8 :     for(unsigned i=0; i<conf.size(); ++i) displace[i] = w;
+      82             :   }
+      83             : 
+      84          45 :   Vector center;
+      85        1154 :   for(unsigned i=0; i<conf.size(); ++i) {
+      86        1109 :     center+=conf[i]*align[i]; atom_der_index[i]=i;
+      87             :   }
+      88        1154 :   for(unsigned i=0; i<conf.size(); ++i) reference_atoms[i]=conf[i]-center;
+      89          45 :   setupRMSDObject();
+      90          45 : }
+      91             : 
+      92       58046 : double SingleDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      93       58046 :   return calc( pos, pbc, myder, squared );
+      94             : }
+      95             : 
+      96      140941 : double SingleDomainRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg,
+      97             :                                ReferenceValuePack& myder, const bool& squared ) const {
+      98             :   plumed_dbg_assert( vals.size()==0 && pos.size()==getNumberOfAtoms() && arg.size()==0 );
+      99      140941 :   return calc( pos, pbc, myder, squared );
+     100             : }
+     101             : 
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.func-sort-c.html b/coverage/reference/SingleDomainRMSD.h.func-sort-c.html new file mode 100644 index 0000000000..2e5df624d3 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.func.html b/coverage/reference/SingleDomainRMSD.h.func.html new file mode 100644 index 0000000000..2bcfe23121 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.gcov.html b/coverage/reference/SingleDomainRMSD.h.gcov.html new file mode 100644 index 0000000000..c9af28622e --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/reference/index-sort-f.html b/coverage/reference/index-sort-f.html new file mode 100644 index 0000000000..2ab7352f9b --- /dev/null +++ b/coverage/reference/index-sort-f.html @@ -0,0 +1,353 @@ + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-05-27 13:05: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
MahalanobisDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
NormalizedEuclideanDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
ReferenceAtoms.h +
73.3%73.3%
+
73.3 %11 / 1560.0 %3 / 5
ArgumentOnlyDistance.cpp +
62.5%62.5%
+
62.5 %10 / 1660.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.16
+
+ + + diff --git a/coverage/reference/index-sort-l.html b/coverage/reference/index-sort-l.html new file mode 100644 index 0000000000..29692bb471 --- /dev/null +++ b/coverage/reference/index-sort-l.html @@ -0,0 +1,353 @@ + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-05-27 13:05: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
MahalanobisDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
NormalizedEuclideanDistance.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.16
+
+ + + diff --git a/coverage/reference/index.html b/coverage/reference/index.html new file mode 100644 index 0000000000..f7b2e99405 --- /dev/null +++ b/coverage/reference/index.html @@ -0,0 +1,353 @@ + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ruby.png b/coverage/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html new file mode 100644 index 0000000000..71f1faa49e --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe816createERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe81C2Ev4168
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe81D2Ev4168
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.func.html b/coverage/s2cm/S2ContactModel.cpp.func.html new file mode 100644 index 0000000000..ca351901bd --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe816createERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe81C2Ev4168
_ZN4PLMD4s2cm12_GLOBAL__N_126S2ContactModelRegisterMe81D2Ev4168
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.gcov.html b/coverage/s2cm/S2ContactModel.cpp.gcov.html new file mode 100644 index 0000000000..ca0987dae8 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.gcov.html @@ -0,0 +1,401 @@ + + + + + + + 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-05-27 13:05: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.
+      39             : 
+      40             : This CV was used in \cite Palazzesi_s2_2017, based on NH order parameter from \cite Zhang_s2_2002 and methyl order parameter from \cite Ming_s2_2004. Input parameters can be found in the relevant papers.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : 
+      48             : 
+      49             : 
+      50             : 
+      51             : 
+      52             : 
+      53             : 
+      54             : class S2ContactModel : public Colvar {
+      55             :   bool pbc_;
+      56             :   bool serial_;
+      57             :   std::unique_ptr<NeighborList> nl;
+      58             :   bool invalidateList;
+      59             :   bool firsttime;
+      60             :   //
+      61             :   double r_eff_;
+      62             :   double inv_r_eff_;
+      63             :   double prefactor_a_;
+      64             :   double exp_b_;
+      65             :   double offset_c_;
+      66             :   double n_i_;
+      67             :   double total_prefactor_;
+      68             :   double r_globalshift_;
+      69             : 
+      70             :   enum ModelType {methyl,nh} modeltype_;
+      71             : 
+      72             :   //
+      73             : public:
+      74             :   explicit S2ContactModel(const ActionOptions&);
+      75             :   ~S2ContactModel();
+      76             :   virtual void calculate();
+      77             :   virtual void prepare();
+      78             :   static void registerKeywords( Keywords& keys );
+      79             : };
+      80             : 
+      81       12552 : PLUMED_REGISTER_ACTION(S2ContactModel,"S2CM")
+      82             : 
+      83          26 : void S2ContactModel::registerKeywords( Keywords& keys ) {
+      84          26 :   Colvar::registerKeywords(keys);
+      85          52 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      86          52 :   keys.addFlag("NLIST",false,"Use a neighbour list to speed up the calculation");
+      87          52 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbour list");
+      88          52 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbour list");
+      89          52 :   keys.add("atoms","METHYL_ATOM","the methyl carbon atom of the residue (i)");
+      90          52 :   keys.add("atoms","NH_ATOMS","the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+      91          52 :   keys.add("atoms","HEAVY_ATOMS","the heavy atoms to be included in the calculation");
+      92             :   //
+      93          52 :   keys.add("compulsory","R_EFF","the effective distance, r_eff in the equation, given in nm.");
+      94          52 :   keys.add("compulsory","PREFACTOR_A","the prefactor, a in the equation");
+      95          52 :   keys.add("compulsory","EXPONENT_B","the exponent, b in the equation");
+      96          52 :   keys.add("compulsory","OFFSET_C","the offset, c in the equation");
+      97          52 :   keys.add("compulsory","N_I"," n_i in the equation");
+      98          52 :   keys.add("optional","R_SHIFT","shift all distances by given amount");
+      99          26 : }
+     100             : 
+     101          24 : S2ContactModel::S2ContactModel(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          24 :   pbc_(true),
+     104          24 :   serial_(false),
+     105          24 :   invalidateList(true),
+     106          24 :   firsttime(true),
+     107          24 :   r_eff_(0.0),
+     108          24 :   inv_r_eff_(0.0),
+     109          24 :   prefactor_a_(0.0),
+     110          24 :   exp_b_(0.0),
+     111          24 :   offset_c_(0.0),
+     112          24 :   n_i_(0.0),
+     113          24 :   total_prefactor_(0.0),
+     114          24 :   r_globalshift_(0.0),
+     115          24 :   modeltype_(methyl)
+     116             : {
+     117             : 
+     118          48 :   parseFlag("SERIAL",serial_);
+     119             : 
+     120             :   std::vector<AtomNumber> methyl_atom;
+     121          48 :   parseAtomList("METHYL_ATOM",methyl_atom);
+     122             :   std::vector<AtomNumber> nh_atoms;
+     123          48 :   parseAtomList("NH_ATOMS",nh_atoms);
+     124             : 
+     125          24 :   if(methyl_atom.size()==0 && nh_atoms.size()==0) {
+     126           0 :     error("you have to give either METHYL_ATOM or NH_ATOMS");
+     127             :   }
+     128          24 :   if(methyl_atom.size()>0 && nh_atoms.size()>0) {
+     129           0 :     error("you cannot give both METHYL_ATOM or NH_ATOMS");
+     130             :   }
+     131          24 :   if(methyl_atom.size()>0 && methyl_atom.size()!=1) {
+     132           0 :     error("you should give one atom in METHYL_ATOM, the methyl carbon atom of the residue");
+     133             :   }
+     134          24 :   if(nh_atoms.size()>0 && nh_atoms.size()!=2) {
+     135           0 :     error("you should give two atoms in NH_ATOMS, the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+     136             :   }
+     137             : 
+     138             :   std::vector<AtomNumber> heavy_atoms;
+     139          48 :   parseAtomList("HEAVY_ATOMS",heavy_atoms);
+     140          24 :   if(heavy_atoms.size()==0) {
+     141           0 :     error("HEAVY_ATOMS is not given");
+     142             :   }
+     143             : 
+     144             :   std::vector<AtomNumber> main_atoms;
+     145          24 :   if(methyl_atom.size()>0) {
+     146           0 :     modeltype_= methyl;
+     147           0 :     main_atoms = methyl_atom;
+     148          24 :   } else if(nh_atoms.size()>0) {
+     149          24 :     modeltype_= nh;
+     150          24 :     main_atoms = nh_atoms;
+     151             :   }
+     152             : 
+     153          24 :   bool nopbc=!pbc_;
+     154          24 :   parseFlag("NOPBC",nopbc);
+     155          24 :   pbc_=!nopbc;
+     156             : 
+     157             :   // neighbor list stuff
+     158          24 :   bool doneigh=false;
+     159          24 :   double nl_cut=0.0;
+     160          24 :   int nl_st=0;
+     161          24 :   parseFlag("NLIST",doneigh);
+     162          24 :   if(doneigh) {
+     163          12 :     parse("NL_CUTOFF",nl_cut);
+     164          12 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     165          12 :     parse("NL_STRIDE",nl_st);
+     166          12 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+     167             :   }
+     168             : 
+     169          24 :   parse("R_EFF",r_eff_);
+     170          24 :   inv_r_eff_ = 1.0/r_eff_;
+     171          24 :   parse("PREFACTOR_A",prefactor_a_);
+     172          24 :   parse("EXPONENT_B",exp_b_);
+     173          24 :   parse("OFFSET_C",offset_c_);
+     174             :   unsigned int n_i_int;
+     175          24 :   parse("N_I",n_i_int);
+     176          24 :   n_i_ = static_cast<double>(n_i_int);
+     177          24 :   total_prefactor_ = prefactor_a_/pow(n_i_,exp_b_);
+     178             :   //
+     179          24 :   parse("R_SHIFT",r_globalshift_);
+     180             : 
+     181          24 :   checkRead();
+     182             : 
+     183          24 :   addValueWithDerivatives();
+     184          24 :   setNotPeriodic();
+     185             : 
+     186          24 :   bool dopair=false;
+     187          24 :   if(doneigh) {
+     188          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm,nl_cut,nl_st);
+     189             :   }
+     190             :   else {
+     191          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm);
+     192             :   }
+     193             : 
+     194          24 :   requestAtoms(nl->getFullAtomList());
+     195             : 
+     196             : 
+     197          24 :   log.printf("  NMR S2 contact model CV, please read and cite ");
+     198          48 :   log << plumed.cite("Palazzesi, Valsson, and Parrinello, J. Phys. Chem. Lett. 8, 4752 (2017) - DOI:10.1021/acs.jpclett.7b01770");
+     199             : 
+     200          24 :   if(modeltype_==methyl) {
+     201           0 :     log << plumed.cite("Ming and Bruschweiler, J. Biomol. NMR, 29, 363 (2004) - DOI:10.1023/B:JNMR.0000032612.70767.35");
+     202           0 :     log.printf("\n");
+     203           0 :     log.printf("  calculation of methyl order parameter using atom %d \n",methyl_atom[0].serial());
+     204             :   }
+     205          24 :   else if(modeltype_==nh) {
+     206          48 :     log << plumed.cite("Zhang and Bruschweiler, J. Am. Chem. Soc. 124, 12654 (2002) - DOI:10.1021/ja027847a");
+     207          24 :     log.printf("\n");
+     208          24 :     log.printf("  calculation of NH order parameter using atoms %d and %d\n",nh_atoms[0].serial(),nh_atoms[1].serial());
+     209             :   }
+     210          24 :   log.printf("  heavy atoms used in the calculation (%u in total):\n",static_cast<unsigned int>(heavy_atoms.size()));
+     211        1872 :   for(unsigned int i=0; i<heavy_atoms.size(); ++i) {
+     212        1848 :     if( (i+1) % 25 == 0 ) {log.printf("  \n");}
+     213        1848 :     log.printf("  %d", heavy_atoms[i].serial());
+     214             :   }
+     215          24 :   log.printf("  \n");
+     216          24 :   log.printf("  total number of distances: %u\n",nl->size());
+     217             :   //
+     218          24 :   log.printf("  using parameters");
+     219          24 :   log.printf(" r_eff=%f,",r_eff_);
+     220          24 :   log.printf(" a=%f,",prefactor_a_);
+     221          24 :   log.printf(" b=%f,",exp_b_);
+     222          24 :   log.printf(" c=%f,",offset_c_);
+     223          24 :   log.printf(" n_i=%u",n_i_int);
+     224          24 :   if(r_globalshift_!=0.0) {
+     225           4 :     log.printf(", r_shift=%f",r_globalshift_);
+     226             :   }
+     227          24 :   log.printf("\n");
+     228          24 :   if(pbc_) {
+     229          12 :     log.printf("  using periodic boundary conditions\n");
+     230             :   } else {
+     231          12 :     log.printf("  without periodic boundary conditions\n");
+     232             :   }
+     233          24 :   if(doneigh) {
+     234          12 :     log.printf("  using neighbor lists with\n");
+     235          12 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     236             :   }
+     237          24 :   if(serial_) {
+     238           0 :     log.printf("  calculation done in serial\n");
+     239             :   }
+     240          24 : }
+     241             : 
+     242          48 : S2ContactModel::~S2ContactModel() {
+     243          48 : }
+     244             : 
+     245          48 : void S2ContactModel::prepare() {
+     246          48 :   if(nl->getStride()>0) {
+     247          24 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     248          24 :       requestAtoms(nl->getFullAtomList());
+     249          24 :       invalidateList=true;
+     250          24 :       firsttime=false;
+     251             :     } else {
+     252           0 :       requestAtoms(nl->getReducedAtomList());
+     253           0 :       invalidateList=false;
+     254           0 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     255             :     }
+     256          24 :     if(getExchangeStep()) firsttime=true;
+     257             :   }
+     258          48 : }
+     259             : 
+     260             : // calculator
+     261        5952 : void S2ContactModel::calculate() {
+     262             : 
+     263        5952 :   Tensor virial;
+     264        5952 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     265             : 
+     266        5952 :   if(nl->getStride()>0 && invalidateList) {
+     267        2976 :     nl->update(getPositions());
+     268             :   }
+     269             : 
+     270        5952 :   unsigned int stride=comm.Get_size();
+     271        5952 :   unsigned int rank=comm.Get_rank();
+     272        5952 :   if(serial_) {
+     273             :     stride=1;
+     274             :     rank=0;
+     275             :   }
+     276             : 
+     277        5952 :   double contact_sum = 0.0;
+     278             : 
+     279        5952 :   const unsigned int nn=nl->size();
+     280             : 
+     281      321408 :   for(unsigned int i=rank; i<nn; i+=stride) {
+     282      315456 :     Vector distance;
+     283      315456 :     unsigned int i0=nl->getClosePair(i).first;
+     284      315456 :     unsigned int i1=nl->getClosePair(i).second;
+     285      315456 :     if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) {continue;}
+     286             : 
+     287      315456 :     if(pbc_) {
+     288       86304 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     289             :     } else {
+     290      229152 :       distance=delta(getPosition(i0),getPosition(i1));
+     291             :     }
+     292             : 
+     293      315456 :     double exp_arg = exp(-(distance.modulo()-r_globalshift_)*inv_r_eff_);
+     294      315456 :     contact_sum += exp_arg;
+     295             : 
+     296      315456 :     exp_arg /= distance.modulo();
+     297      315456 :     Vector dd(exp_arg*distance);
+     298      315456 :     Tensor vv(dd,distance);
+     299      315456 :     deriv[i0]-=dd;
+     300      315456 :     deriv[i1]+=dd;
+     301      315456 :     virial-=vv;
+     302             :   }
+     303             : 
+     304        5952 :   if(!serial_) {
+     305        5952 :     comm.Sum(contact_sum);
+     306        5952 :     if(!deriv.empty()) {
+     307        5952 :       comm.Sum(&deriv[0][0],3*deriv.size());
+     308             :     }
+     309        5952 :     comm.Sum(virial);
+     310             :   }
+     311             : 
+     312        5952 :   double value = tanh(total_prefactor_*contact_sum);
+     313             :   // using that d/dx[tanh(x)]= 1-[tanh(x)]^2
+     314        5952 :   double deriv_f = -inv_r_eff_*total_prefactor_*(1.0-value*value);
+     315        5952 :   value -= offset_c_;
+     316             : 
+     317      476160 :   for(unsigned int i=0; i<deriv.size(); ++i) {
+     318      470208 :     setAtomsDerivatives(i,deriv_f*deriv[i]);
+     319             :   }
+     320        5952 :   setValue(value);
+     321        5952 :   setBoxDerivatives(deriv_f*virial);
+     322             : 
+     323        5952 : }
+     324             : }
+     325             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index-sort-f.html b/coverage/s2cm/index-sort-f.html new file mode 100644 index 0000000000..7b2cbaac82 --- /dev/null +++ b/coverage/s2cm/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/s2cm/index-sort-l.html b/coverage/s2cm/index-sort-l.html new file mode 100644 index 0000000000..e946cc7235 --- /dev/null +++ b/coverage/s2cm/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/s2cm/index.html b/coverage/s2cm/index.html new file mode 100644 index 0000000000..e800ab980a --- /dev/null +++ b/coverage/s2cm/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15216691.6 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/sasa/index-sort-f.html b/coverage/sasa/index-sort-f.html new file mode 100644 index 0000000000..59396291ec --- /dev/null +++ b/coverage/sasa/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:998121782.0 %
Date:2024-05-27 13:05: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 %519 / 63181.2 %13 / 16
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58687.5 %14 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index-sort-l.html b/coverage/sasa/index-sort-l.html new file mode 100644 index 0000000000..a6556e72e6 --- /dev/null +++ b/coverage/sasa/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:998121782.0 %
Date:2024-05-27 13:05:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58687.5 %14 / 16
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %519 / 63181.2 %13 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index.html b/coverage/sasa/index.html new file mode 100644 index 0000000000..fd12f25984 --- /dev/null +++ b/coverage/sasa/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:998121782.0 %
Date:2024-05-27 13:05:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %479 / 58687.5 %14 / 16
sasa_LCPO.cpp +
82.3%82.3%
+
82.3 %519 / 63181.2 %13 / 16
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html new file mode 100644 index 0000000000..cb92fcc490 --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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:47958681.7 %
Date:2024-05-27 13:05: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_HASELRegisterMe1656createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe165C2Ev4168
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe165D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func.html b/coverage/sasa/sasa_HASEL.cpp.func.html new file mode 100644 index 0000000000..8719601381 --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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:47958681.7 %
Date:2024-05-27 13:05: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_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe1656createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe165C2Ev4168
_ZN4PLMD4sasa12_GLOBAL__N_123SASA_HASELRegisterMe165D2Ev4168
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.gcov.html b/coverage/sasa/sasa_HASEL.cpp.gcov.html new file mode 100644 index 0000000000..85dc9f551c --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.gcov.html @@ -0,0 +1,1088 @@ + + + + + + + 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:47958681.7 %
Date:2024-05-27 13:05: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.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The algorithm described in \cite Hasel1988 is used for the calculation. The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : 
+      58             : ----------------Sample DeltaG.dat file---------------------
+      59             : ALA     0.711019999999962
+      60             : ARG     -2.24832799999996
+      61             : ASN     -2.74838799999999
+      62             : ASP     -2.5626376
+      63             : CYS     3.89864000000006
+      64             : GLN     -1.76192
+      65             : GLU     -2.38664400000002
+      66             : GLY     0
+      67             : HIS     -3.58152799999999
+      68             : ILE     2.42634399999986
+      69             : LEU     1.77233599999988
+      70             : LYS     -1.92576400000002
+      71             : MET     -0.262827999999956
+      72             : PHE     1.62028800000007
+      73             : PRO     -2.15598800000001
+      74             : SER     -1.60934800000004
+      75             : THR     -0.591559999999987
+      76             : TRP     1.22936000000027
+      77             : TYR     0.775547999999958
+      78             : VAL     2.12779200000011
+      79             : BACKBONE        1.00066920000002
+      80             : -----------------------------------------------------------
+      81             : \endverbatim
+      82             : 
+      83             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      84             : 
+      85             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      86             : 
+      87             : 
+      88             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      89             : 
+      90             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      91             : 
+      92             : In case you want to recover the old behavior you should use the NOPBC flag.
+      93             : In that case you need to take care that atoms are in the correct periodic image.
+      94             : 
+      95             : The SASA may also be computed using the SASA_LCPO collective variable, which makes use of the LCPO algorithm \cite Weiser1999. SASA_LCPO is more accurate then SASA_HASEL, but the computation is slower.
+      96             : 
+      97             : 
+      98             : \par Examples
+      99             : 
+     100             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     101             : \plumedfile
+     102             : SASA_HASEL TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     103             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     104             : \endplumedfile
+     105             : 
+     106             : 
+     107             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     108             : 
+     109             : \plumedfile
+     110             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     111             : 
+     112             : bias: BIASVALUE ARG=sasa
+     113             : 
+     114             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     115             : \endplumedfile
+     116             : 
+     117             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     118             : 
+     119             : \plumedfile
+     120             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     121             : 
+     122             : bias: BIASVALUE ARG=sasa
+     123             : 
+     124             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     125             : \endplumedfile
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : class SASA_HASEL : public Colvar {
+     131             : private:
+     132             :   enum CV_TYPE {TOTAL, TRANSFER};
+     133             :   int sasa_type;
+     134             :   bool nopbc;
+     135             :   double rs;
+     136             :   string DeltaGValues;
+     137             :   int approach;
+     138             :   unsigned stride;
+     139             :   unsigned nl_update;
+     140             :   int firstStepFlag;
+     141             :   double Ti;
+     142             :   // cppcheck-suppress duplInheritedMember
+     143             :   std::vector<AtomNumber> atoms;
+     144             :   vector < vector < std::string > > AtomResidueName;
+     145             :   vector < vector < double > > SASAparam;
+     146             :   vector < vector < std::string > > CONNECTparam;
+     147             :   unsigned natoms;
+     148             :   vector < vector < double > > MaxSurf;
+     149             :   vector < vector < double > > DeltaG;
+     150             :   vector < vector < int > > Nlist;
+     151             : public:
+     152             :   static void registerKeywords(Keywords& keys);
+     153             :   explicit SASA_HASEL(const ActionOptions&);
+     154             :   void readPDB();
+     155             :   map<string, vector<std::string> > setupHASELparam();
+     156             :   void readSASAparam();
+     157             :   void calcNlist();
+     158             :   map<string, vector<double> > setupMaxSurfMap();
+     159             :   void readMaxSurf();
+     160             :   void readDeltaG();
+     161             :   void computeDeltaG();
+     162             :   virtual void calculate();
+     163             : };
+     164             : 
+     165       12508 : PLUMED_REGISTER_ACTION(SASA_HASEL,"SASA_HASEL")
+     166             : 
+     167           4 : void SASA_HASEL::registerKeywords(Keywords& keys) {
+     168           4 :   Colvar::registerKeywords(keys);
+     169           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     170           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     171           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list for the calculation of SASA is updated.");
+     172           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy of transfer values for backbone and sidechains atoms. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     173           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     174           4 : }
+     175             : 
+     176             : 
+     177           2 : SASA_HASEL::SASA_HASEL(const ActionOptions&ao):
+     178             :   PLUMED_COLVAR_INIT(ao),
+     179           2 :   nopbc(false),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           4 :   DeltaGValues("absent"),
+     183           2 :   Ti(0),
+     184           2 :   firstStepFlag(0)
+     185             : {
+     186           2 :   rs = 0.14;
+     187           2 :   parse("DELTAGFILE",DeltaGValues);
+     188           2 :   parse("APPROACH", approach);
+     189           4 :   parseAtomList("ATOMS",atoms);
+     190           2 :   if(atoms.size()==0) error("no atoms specified");
+     191             :   std::string Type;
+     192           2 :   parse("TYPE",Type);
+     193           2 :   parse("NL_STRIDE", stride);
+     194           2 :   parseFlag("NOPBC",nopbc);
+     195           2 :   checkRead();
+     196             : 
+     197           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     198           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     199           0 :   else error("Unknown SASA type");
+     200             : 
+     201           2 :   switch(sasa_type)
+     202             :   {
+     203           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     204           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     205             :   }
+     206             : 
+     207           2 :   log.printf("  atoms involved : ");
+     208         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     209         240 :     if(i%25==0) log<<"\n";
+     210         240 :     log.printf("%d ",atoms[i].serial());
+     211             :   }
+     212           2 :   log.printf("\n");
+     213             : 
+     214           2 :   if(nopbc) {
+     215           0 :     log<<"  PBC will be ignored\n";
+     216             :   } else {
+     217           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     218             :   }
+     219             : 
+     220             : 
+     221           2 :   addValueWithDerivatives(); setNotPeriodic();
+     222           2 :   requestAtoms(atoms);
+     223             : 
+     224           2 :   natoms = getNumberOfAtoms();
+     225           2 :   AtomResidueName.resize(2);
+     226           2 :   SASAparam.resize(natoms);
+     227           2 :   CONNECTparam.resize(natoms);
+     228           2 :   MaxSurf.resize(natoms);
+     229           2 :   DeltaG.resize(natoms+1);
+     230           2 :   Nlist.resize(natoms);
+     231             : 
+     232             : 
+     233           2 : }
+     234             : 
+     235             : 
+     236             : //splits strings into tokens. Used to read into SASA parameters file and into reference pdb file
+     237             : template <class Container>
+     238          42 : void split(const std::string& str, Container& cont)
+     239             : {
+     240          42 :   std::istringstream iss(str);
+     241          84 :   std::copy(std::istream_iterator<std::string>(iss),
+     242          42 :             std::istream_iterator<std::string>(),
+     243             :             std::back_inserter(cont));
+     244          42 : }
+     245             : 
+     246             : 
+     247             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     248             : 
+     249           2 : void SASA_HASEL::readPDB() {
+     250           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     251           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     252             :   AtomResidueName[0].clear();
+     253             :   AtomResidueName[1].clear();
+     254             : 
+     255         242 :   for(unsigned i=0; i<natoms; i++) {
+     256         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     257         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     258         240 :     AtomResidueName[0].push_back (Aname);
+     259         240 :     AtomResidueName[1].push_back (Rname);
+     260             :   }
+     261             : 
+     262           2 : }
+     263             : 
+     264             : 
+     265             : //Hasel et al. parameters database
+     266           2 : map<string, vector<std::string> > SASA_HASEL::setupHASELparam() {
+     267             :   map<string, vector<std::string> > haselmap;
+     268          16 :   haselmap["ALA_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     269          16 :   haselmap["ALA_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     270          16 :   haselmap["ALA_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     271          16 :   haselmap["ALA_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     272          16 :   haselmap["ALA_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     273          16 :   haselmap["ALA_CB"] = { "2.0",  "0.88",  "CA",  "Z",  "Z",  "Z", };
+     274          16 :   haselmap["ASP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     275          16 :   haselmap["ASP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     276          16 :   haselmap["ASP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     277          16 :   haselmap["ASP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     278          16 :   haselmap["ASP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     279          16 :   haselmap["ASP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     280          16 :   haselmap["ASP_CG"] = { "1.72",  "1.554",  "CB",  "OD1",  "OD2",  "Z", };
+     281          16 :   haselmap["ASP_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     282          16 :   haselmap["ASP_OD2"] = { "1.7",  "0.922",  "CG",  "Z",  "Z",  "Z", };
+     283          16 :   haselmap["ASN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     284          16 :   haselmap["ASN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     285          16 :   haselmap["ASN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     286          16 :   haselmap["ASN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     287          16 :   haselmap["ASN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     288          16 :   haselmap["ASN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     289          16 :   haselmap["ASN_CG"] = { "1.7",  "2.149",  "CB",  "OD1",  "ND2",  "Z", };
+     290          16 :   haselmap["ASN_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     291          16 :   haselmap["ASN_ND2"] = { "1.6",  "1.215",  "CG",  "1HD2",  "1HD2",  "Z", };
+     292          16 :   haselmap["ASN_1HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     293          16 :   haselmap["ASN_2HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     294          16 :   haselmap["ARG_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     295          16 :   haselmap["ARG_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     296          16 :   haselmap["ARG_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     297          16 :   haselmap["ARG_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     298          16 :   haselmap["ARG_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     299          16 :   haselmap["ARG_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     300          16 :   haselmap["ARG_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     301          16 :   haselmap["ARG_CD"] = { "1.9",  "1.045",  "CG",  "NE",  "Z",  "Z", };
+     302          16 :   haselmap["ARG_NE"] = { "1.55",  "1.028",  "CD",  "HE",  "CZ",  "Z", };
+     303          16 :   haselmap["ARG_NH1"] = { "1.55",  "1.028",  "CZ",  "1HH1",  "2HH1",  "Z", };
+     304          16 :   haselmap["ARG_NH2"] = { "1.55",  "1.028",  "CZ",  "1HH2",  "2HH2",  "Z", };
+     305          16 :   haselmap["ARG_CZ"] = { "1.72",  "1.554",  "NE",  "NH1",  "NH2",  "Z", };
+     306          16 :   haselmap["ARG_HE"] = { "1.1",  "1.128",  "NE",  "Z",  "Z",  "Z", };
+     307          16 :   haselmap["ARG_1HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     308          16 :   haselmap["ARG_2HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     309          16 :   haselmap["ARG_2HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     310          16 :   haselmap["ARG_1HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     311          16 :   haselmap["CYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     312          16 :   haselmap["CYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     313          16 :   haselmap["CYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     314          16 :   haselmap["CYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     315          16 :   haselmap["CYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     316          16 :   haselmap["CYS_CB"] = { "1.9",  "1.045",  "CA",  "SG",  "Z",  "Z", };
+     317          16 :   haselmap["CYS_SG"] = { "1.8",  "1.121",  "CB",  "HG",  "Z",  "Z", };
+     318          16 :   haselmap["CYS_HG"] = { "1.2",  "0.928",  "SG",  "Z",  "Z",  "Z", };
+     319          16 :   haselmap["GLU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     320          16 :   haselmap["GLU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     321          16 :   haselmap["GLU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     322          16 :   haselmap["GLU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     323          16 :   haselmap["GLU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     324          16 :   haselmap["GLU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     325          16 :   haselmap["GLU_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     326          16 :   haselmap["GLU_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "OE2",  "Z", };
+     327          16 :   haselmap["GLU_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     328          16 :   haselmap["GLU_OE2"] = { "1.7",  "0.922",  "CD",  "Z",  "Z",  "Z", };
+     329          16 :   haselmap["GLN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     330          16 :   haselmap["GLN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     331          16 :   haselmap["GLN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     332          16 :   haselmap["GLN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     333          16 :   haselmap["GLN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     334          16 :   haselmap["GLN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     335          16 :   haselmap["GLN_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     336          16 :   haselmap["GLN_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "NE2",  "Z", };
+     337          16 :   haselmap["GLN_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     338          16 :   haselmap["GLN_NE2"] = { "1.6",  "1.215",  "CD",  "2HE2",  "1HE2",  "Z", };
+     339          16 :   haselmap["GLN_2HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     340          16 :   haselmap["GLN_1HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     341          16 :   haselmap["GLY_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     342          16 :   haselmap["GLY_CA"] = { "1.7",  "2.149",  "N",  "C",  "Z",  "Z", };
+     343          16 :   haselmap["GLY_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     344          16 :   haselmap["GLY_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     345          16 :   haselmap["GLY_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     346          16 :   haselmap["HIS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     347          16 :   haselmap["HIS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     348          16 :   haselmap["HIS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     349          16 :   haselmap["HIS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     350          16 :   haselmap["HIS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     351          16 :   haselmap["HIS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     352          16 :   haselmap["HIS_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "ND1",  "Z", };
+     353          16 :   haselmap["HIS_ND1"] = { "1.55",  "1.028",  "CG",  "CE1",  "Z",  "Z", };
+     354          16 :   haselmap["HIS_CE1"] = { "1.8",  "1.073",  "ND1",  "NE2",  "Z",  "Z", };
+     355          16 :   haselmap["HIS_NE2"] = { "1.55",  "1.413",  "CE1",  "2HE",  "CD2",  "Z", };
+     356          16 :   haselmap["HIS_CD2"] = { "1.8",  "1.073",  "NE2",  "CG",  "Z",  "Z", };
+     357          16 :   haselmap["HIS_2HE"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     358          16 :   haselmap["ILE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     359          16 :   haselmap["ILE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     360          16 :   haselmap["ILE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     361          16 :   haselmap["ILE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     362          16 :   haselmap["ILE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     363          16 :   haselmap["ILE_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "CG1",  "Z", };
+     364          16 :   haselmap["ILE_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     365          16 :   haselmap["ILE_CG1"] = { "1.9",  "1.045",  "CB",  "CD1",  "Z",  "Z", };
+     366          16 :   haselmap["ILE_CD1"] = { "2.0",  "0.88",  "CG1",  "Z",  "Z",  "Z", };
+     367          16 :   haselmap["LEU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     368          16 :   haselmap["LEU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     369          16 :   haselmap["LEU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     370          16 :   haselmap["LEU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     371          16 :   haselmap["LEU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     372          16 :   haselmap["LEU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     373          16 :   haselmap["LEU_CG"] = { "1.8",  "1.276",  "CB",  "CD1",  "CD2",  "Z", };
+     374          16 :   haselmap["LEU_CD1"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     375          16 :   haselmap["LEU_CD2"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     376          16 :   haselmap["LYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     377          16 :   haselmap["LYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     378          16 :   haselmap["LYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     379          16 :   haselmap["LYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     380          16 :   haselmap["LYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     381          16 :   haselmap["LYS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     382          16 :   haselmap["LYS_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     383          16 :   haselmap["LYS_CD"] = { "1.9",  "1.045",  "CG",  "CE",  "Z",  "Z", };
+     384          16 :   haselmap["LYS_CE"] = { "1.9",  "1.045",  "CD",  "NZ",  "Z",  "Z", };
+     385          16 :   haselmap["LYS_NZ"] = { "1.6",  "1.215",  "CE",  "1HZ",  "2HZ",  "3HZ", };
+     386          16 :   haselmap["LYS_1HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     387          16 :   haselmap["LYS_2HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     388          16 :   haselmap["LYS_3HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     389          16 :   haselmap["MET_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     390          16 :   haselmap["MET_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     391          16 :   haselmap["MET_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     392          16 :   haselmap["MET_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     393          16 :   haselmap["MET_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     394          16 :   haselmap["MET_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     395          16 :   haselmap["MET_CG"] = { "1.9",  "1.045",  "CB",  "SD",  "Z",  "Z", };
+     396          16 :   haselmap["MET_SD"] = { "1.8",  "1.121",  "CG",  "CE",  "Z",  "Z", };
+     397          16 :   haselmap["MET_CE"] = { "2.0",  "0.88",  "SD",  "Z",  "Z",  "Z", };
+     398          16 :   haselmap["PHE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     399          16 :   haselmap["PHE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     400          16 :   haselmap["PHE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     401          16 :   haselmap["PHE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     402          16 :   haselmap["PHE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     403          16 :   haselmap["PHE_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     404          16 :   haselmap["PHE_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     405          16 :   haselmap["PHE_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     406          16 :   haselmap["PHE_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     407          16 :   haselmap["PHE_CZ"] = { "1.8",  "1.073",  "CE1",  "CE2",  "Z",  "Z", };
+     408          16 :   haselmap["PHE_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     409          16 :   haselmap["PHE_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     410          16 :   haselmap["PRO_N"] = { "1.55",  "1.028",  "CD",  "CA",  "Z",  "Z", };
+     411          16 :   haselmap["PRO_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     412          16 :   haselmap["PRO_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     413          16 :   haselmap["PRO_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     414          16 :   haselmap["PRO_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     415          16 :   haselmap["PRO_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     416          16 :   haselmap["PRO_CD"] = { "1.9",  "1.045",  "CG",  "N",  "Z",  "Z", };
+     417          16 :   haselmap["SER_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     418          16 :   haselmap["SER_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     419          16 :   haselmap["SER_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     420          16 :   haselmap["SER_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     421          16 :   haselmap["SER_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     422          16 :   haselmap["SER_CB"] = { "1.9",  "1.045",  "CA",  "OG",  "Z",  "Z", };
+     423          16 :   haselmap["SER_OG"] = { "1.52",  "1.08",  "CB",  "HG",  "Z",  "Z", };
+     424          16 :   haselmap["SER_HG"] = { "1.0",  "0.944",  "OG",  "Z",  "Z",  "Z", };
+     425          16 :   haselmap["THR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     426          16 :   haselmap["THR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     427          16 :   haselmap["THR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     428          16 :   haselmap["THR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     429          16 :   haselmap["THR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     430          16 :   haselmap["THR_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "OG1",  "Z", };
+     431          16 :   haselmap["THR_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     432          16 :   haselmap["THR_OG1"] = { "1.52",  "1.08",  "1HG",  "CB",  "Z",  "Z", };
+     433          16 :   haselmap["THR_1HG"] = { "1.0",  "0.944",  "OG1",  "Z",  "Z",  "Z", };
+     434          16 :   haselmap["TRP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     435          16 :   haselmap["TRP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     436          16 :   haselmap["TRP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     437          16 :   haselmap["TRP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     438          16 :   haselmap["TRP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     439          16 :   haselmap["TRP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     440          16 :   haselmap["TRP_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "CD1",  "Z", };
+     441          16 :   haselmap["TRP_CD1"] = { "1.8",  "1.073",  "CG",  "NE1",  "Z",  "Z", };
+     442          16 :   haselmap["TRP_NE1"] = { "1.55",  "1.413",  "CD1",  "CE2",  "1HE",  "Z", };
+     443          16 :   haselmap["TRP_CE2"] = { "1.72",  "1.554",  "NE1",  "CD2",  "CZ2",  "Z", };
+     444          16 :   haselmap["TRP_CZ2"] = { "1.8",  "1.073",  "CE2",  "CH2",  "Z",  "Z", };
+     445          16 :   haselmap["TRP_CH2"] = { "1.8",  "1.073",  "CZ2",  "CZ3",  "Z",  "Z", };
+     446          16 :   haselmap["TRP_CZ3"] = { "1.8",  "1.073",  "CH2",  "CE3",  "Z",  "Z", };
+     447          16 :   haselmap["TRP_CE3"] = { "1.8",  "1.073",  "CZ3",  "CD2",  "Z",  "Z", };
+     448          16 :   haselmap["TRP_CD2"] = { "1.72",  "1.554",  "CE3",  "CE2",  "CG",  "Z", };
+     449          16 :   haselmap["TRP_1HE"] = { "1.1",  "1.128",  "NE1",  "Z",  "Z",  "Z", };
+     450          16 :   haselmap["TYR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     451          16 :   haselmap["TYR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     452          16 :   haselmap["TYR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     453          16 :   haselmap["TYR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     454          16 :   haselmap["TYR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     455          16 :   haselmap["TYR_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     456          16 :   haselmap["TYR_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     457          16 :   haselmap["TYR_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     458          16 :   haselmap["TYR_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     459          16 :   haselmap["TYR_CZ"] = { "1.72",  "1.554",  "CE1",  "OH",  "CE2",  "Z", };
+     460          16 :   haselmap["TYR_OH"] = { "1.52",  "1.08",  "CZ",  "HH",  "Z",  "Z", };
+     461          16 :   haselmap["TYR_HH"] = { "1.0",  "0.944",  "OH",  "Z",  "Z",  "Z", };
+     462          16 :   haselmap["TYR_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     463          16 :   haselmap["TYR_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     464          16 :   haselmap["VAL_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     465          16 :   haselmap["VAL_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     466          16 :   haselmap["VAL_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     467          16 :   haselmap["VAL_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     468          16 :   haselmap["VAL_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     469          16 :   haselmap["VAL_CB"] = { "1.8",  "1.276",  "CA",  "CG1",  "CG2",  "Z", };
+     470          16 :   haselmap["VAL_CG1"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     471          16 :   haselmap["VAL_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     472           2 :   return haselmap;
+     473             : }
+     474             : 
+     475             : //assigns SASA parameters to each atom reading from HASEL parameter database
+     476           2 : void SASA_HASEL::readSASAparam() {
+     477             : 
+     478         242 :   for(unsigned i=0; i<natoms; i++) {
+     479         240 :     SASAparam[i].clear();
+     480             :     CONNECTparam[i].clear();
+     481             :   }
+     482             : 
+     483             :   map<string, vector<std::string> > haselmap;
+     484           4 :   haselmap = setupHASELparam();
+     485             :   vector<std::string> HASELparamVector;
+     486             :   string identifier;
+     487             : 
+     488             : 
+     489         242 :   for(unsigned i=0; i<natoms; i++) {
+     490         480 :     identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     491         240 :     if (haselmap.find(identifier)!=haselmap.end()) {
+     492         144 :       HASELparamVector = haselmap.at(identifier);
+     493         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[0].c_str())+rs*10);
+     494         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[1].c_str()));
+     495         288 :       CONNECTparam[i].push_back (HASELparamVector[2].c_str());
+     496         288 :       CONNECTparam[i].push_back (HASELparamVector[3].c_str());
+     497         288 :       CONNECTparam[i].push_back (HASELparamVector[4].c_str());
+     498         288 :       CONNECTparam[i].push_back (HASELparamVector[5].c_str());
+     499             :     }
+     500             :   }
+     501             : 
+     502             : 
+     503         242 :   for(unsigned i=0; i<natoms; i++) {
+     504         240 :     if (SASAparam[i].size()==0 ) {
+     505          96 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     506           0 :         cout << "Could not find SASA paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     507           0 :         error ("missing SASA parameters\n");
+     508             :       }
+     509             :     }
+     510             :   }
+     511             : 
+     512             : 
+     513           4 : }
+     514             : 
+     515             : 
+     516             : 
+     517             : //Max Surf values, used only if TYPE=TRANSFER
+     518           1 : map<string, vector<double> > SASA_HASEL::setupMaxSurfMap() {
+     519             :   // Max Surface Area for backbone and sidechain, in nm2
+     520             :   map<string, vector<double> > valuemap;
+     521           1 :   valuemap ["ALA"]= {0.56425,0.584851,};
+     522           1 :   valuemap ["ARG"]= {0.498656,1.808093,};
+     523           1 :   valuemap ["ASN"]= {0.473409,0.818394,};
+     524           1 :   valuemap ["ASP"]= {0.477057,0.977303,};
+     525           1 :   valuemap ["CYS"]= {0.507512,0.791483,};
+     526           1 :   valuemap ["GLN"]= {0.485859,1.281534,};
+     527           1 :   valuemap ["GLU"]= {0.495054,1.464718,};
+     528           1 :   valuemap ["GLY"]= {0.658632,0,};
+     529           1 :   valuemap ["HIS"]= {0.48194,1.118851,};
+     530           1 :   valuemap ["ILE"]= {0.461283,1.450569,};
+     531           1 :   valuemap ["LEU"]= {0.476315,1.498843,};
+     532           1 :   valuemap ["LYS"]= {0.493533,1.619731,};
+     533           1 :   valuemap ["MET"]= {0.507019,1.631904,};
+     534           1 :   valuemap ["PHE"]= {0.457462, 1.275125,};
+     535           1 :   valuemap ["PRO"]= {0.315865,0.859456,};
+     536           1 :   valuemap ["SER"]= {0.48636,0.627233,};
+     537           1 :   valuemap ["THR"]= {0.45064,0.91088,};
+     538           1 :   valuemap ["TRP"]= {0.45762,1.366369,};
+     539           1 :   valuemap ["TYR"]= {0.461826,1.425822,};
+     540           1 :   valuemap ["VAL"]= {0.477054,1.149101,};
+     541           1 :   return valuemap;
+     542             : }
+     543             : 
+     544             : 
+     545             : 
+     546             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     547             : 
+     548           1 : void SASA_HASEL::readMaxSurf() {
+     549             :   map<string, vector<double> > valuemap;
+     550           2 :   valuemap = setupMaxSurfMap();
+     551             :   vector<double> MaxSurfVector;
+     552             : 
+     553         121 :   for(unsigned i=0; i<natoms; i++) {
+     554         120 :     MaxSurf[i].clear();
+     555         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     556         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     557         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     558             :   }
+     559           1 : }
+     560             : 
+     561             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     562             : 
+     563           1 : void SASA_HASEL::readDeltaG() {
+     564             : 
+     565         121 :   for(unsigned i=0; i<natoms; i++) {
+     566         120 :     DeltaG[i].clear();
+     567             :   }
+     568             : 
+     569             :   string DeltaGline;
+     570           1 :   fstream DeltaGFile;
+     571           1 :   DeltaGFile.open(DeltaGValues);
+     572           1 :   if (DeltaGFile) {
+     573             :     int backboneflag = 0;
+     574          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     575          22 :       if(!DeltaGline.empty()) {
+     576             :         std::vector<std::string> DeltaGtoken;
+     577          21 :         split(DeltaGline, DeltaGtoken);
+     578        2541 :         for(unsigned i=0; i<natoms; i++) {
+     579        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     580         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     581             :           }
+     582             :         }
+     583          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     584             :           backboneflag = 1;
+     585           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     586             :         }
+     587          21 :       }
+     588             :     }
+     589           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     590             :   }
+     591           0 :   else error("Cannot open DeltaG file");
+     592             : 
+     593         121 :   for(unsigned i=0; i<natoms; i++) {
+     594         120 :     if (DeltaG[i].size()==0 ) {
+     595           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     596           0 :       error ("missing Delta G parameter\n");
+     597             :     }
+     598             :   }
+     599             : 
+     600           2 : }
+     601             : 
+     602             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     603             : 
+     604           0 : void SASA_HASEL::computeDeltaG() {
+     605             : 
+     606           0 :   for(unsigned i=0; i<natoms; i++) {
+     607           0 :     DeltaG[i].clear();
+     608             :   }
+     609             : 
+     610             :   double T;
+     611           0 :   T = plumed.getAtoms().getKbT()/plumed.getAtoms().getKBoltzmann();
+     612             : 
+     613           0 :   if (T != Ti) {
+     614           0 :     for(unsigned i=0; i<natoms; i++) {
+     615           0 :       if (approach==2) {
+     616           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     617           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     618             :         }
+     619           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     620           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     621             :         }
+     622           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     623           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     624             :         }
+     625           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     626           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     627             :         }
+     628           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     629           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     630             :         }
+     631           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     632           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     633             :         }
+     634           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     635           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     636             :         }
+     637           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     638           0 :           DeltaG[i].push_back (0);
+     639             :         }
+     640           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     641           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     642             :         }
+     643           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     644           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     645             :         }
+     646           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     647           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     648             :         }
+     649           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     650           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     651             :         }
+     652           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     653           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     654             :         }
+     655           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     656           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     657             :         }
+     658           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     659           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     660             :         }
+     661           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     662           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     663             :         }
+     664           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     665           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     666             :         }
+     667           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     668           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     669             :         }
+     670           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     671           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     672             :         }
+     673           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     674           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     675             :         }
+     676           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     677             :       }
+     678           0 :       if (approach==3) {
+     679           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     680           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     681             :         }
+     682           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     683           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     684             :         }
+     685           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     686           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     687             :         }
+     688           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     689           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     690             :         }
+     691           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     692           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     693             :         }
+     694           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     695           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     696             :         }
+     697           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     698           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     699             :         }
+     700           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     701           0 :           DeltaG[i].push_back (0);
+     702             :         }
+     703           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     704           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     705             :         }
+     706           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     707           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     708             :         }
+     709           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     710           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     711             :         }
+     712           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     713           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     714             :         }
+     715           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     716           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     717             :         }
+     718           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     719           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     720             :         }
+     721           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     722           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     723             :         }
+     724           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     725           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     726             :         }
+     727           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     728           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     729             :         }
+     730           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     731           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     732             :         }
+     733           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     734           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     735             :         }
+     736           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     737           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     738             :         }
+     739           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     740             :       }
+     741             :     }
+     742             :   }
+     743             : 
+     744           0 :   Ti = T;
+     745             : 
+     746           0 :   if (firstStepFlag ==0) {
+     747           0 :     if (approach!=2 && approach!=3) {
+     748           0 :       cout << "Unknown approach " << approach << endl;
+     749             :     }
+     750           0 :     for(unsigned i=0; i<natoms; i++) {
+     751           0 :       if (DeltaG[i].size()==0 ) {
+     752           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     753           0 :         error ("missing Delta G parameter\n");
+     754             :       }
+     755             :     }
+     756             :   }
+     757           0 : }
+     758             : 
+     759             : 
+     760             : //calculates neighbor list
+     761          24 : void SASA_HASEL::calcNlist() {
+     762          24 :   if(!nopbc) makeWhole();
+     763             : 
+     764        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     765        2880 :     Nlist[i].clear();
+     766             :   }
+     767             : 
+     768        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     769        2880 :     if (SASAparam[i].size()>0) {
+     770      103680 :       for (unsigned j = 0; j < i; j++) {
+     771      101952 :         if (SASAparam[j].size()>0) {
+     772       61344 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     773       61344 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     774       61344 :           double overlapD = SASAparam[i][0]+SASAparam[j][0];
+     775       61344 :           if (Delta_ij_mod < overlapD) {
+     776       26748 :             Nlist.at(i).push_back (j);
+     777       26748 :             Nlist.at(j).push_back (i);
+     778             :           }
+     779             :         }
+     780             :       }
+     781             :     }
+     782             :   }
+     783          24 : }
+     784             : 
+     785             : 
+     786             : //calculates SASA according to Hasel et al., Tetrahedron Computer Methodology Vol. 1, No. 2, pp. 103-116, 1988
+     787          24 : void SASA_HASEL::calculate() {
+     788          24 :   if(!nopbc) makeWhole();
+     789             : 
+     790          24 :   if(getExchangeStep()) nl_update = 0;
+     791          24 :   if (firstStepFlag ==0) {
+     792           2 :     readPDB();
+     793           2 :     readSASAparam();
+     794             :   }
+     795          24 :   if (nl_update == 0) {
+     796          24 :     calcNlist();
+     797             :   }
+     798             : 
+     799             : 
+     800          24 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     801          24 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     802             :   double Si, sasai, bij;
+     803          24 :   double sasa = 0;
+     804          24 :   vector<Vector> derivatives( natoms );
+     805        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     806        2880 :     derivatives[i][0] = 0.;
+     807        2880 :     derivatives[i][1] = 0.;
+     808        2880 :     derivatives[i][2] = 0.;
+     809             :   }
+     810             : 
+     811          24 :   Tensor virial;
+     812          24 :   vector <double> ddij_di(3);
+     813          24 :   vector <double> dbij_di(3);
+     814          24 :   vector <double> dAijt_di(3);
+     815             : 
+     816          24 :   if( sasa_type==TOTAL ) {
+     817        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     818        1440 :       if(SASAparam[i].size() > 0) {
+     819         864 :         double ri = SASAparam[i][0];
+     820         864 :         Si = 4*M_PI*ri*ri;
+     821             :         sasai = 1.0;
+     822             : 
+     823        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     824             : 
+     825         864 :         dAijt_di[0] = 0;
+     826         864 :         dAijt_di[1] = 0;
+     827         864 :         dAijt_di[2] = 0;
+     828         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     829             : 
+     830       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     831             :           double pij = 0.3516;
+     832             : 
+     833       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     834       26748 :           if (NumRes_i==NumRes_j) {
+     835        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     836             :               pij = 0.8875;
+     837             :             }
+     838             :           }
+     839       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     840       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     841             :               pij = 0.8875;
+     842             :             }
+     843             :           }
+     844             : 
+     845       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     846       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     847             : 
+     848       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     849       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     850             : 
+     851       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     852             : 
+     853       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     854       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     855       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     856             : 
+     857       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     858       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     859       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     860             : 
+     861       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     862       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     863       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     864             : 
+     865       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     866       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     867       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     868             : 
+     869             :         }
+     870             : 
+     871         864 :         sasa += Si*sasai/100; //nm2
+     872             : 
+     873         864 :         derivatives[i][0] += Si*sasai/10*dAijt_di[0]; //nm
+     874         864 :         derivatives[i][1] += Si*sasai/10*dAijt_di[1];
+     875         864 :         derivatives[i][2] += Si*sasai/10*dAijt_di[2];
+     876             : 
+     877       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     878       26748 :           derivatives[Nlist[i][j]][0] += Si*sasai/10*derTerm[j][0]; //nm
+     879       26748 :           derivatives[Nlist[i][j]][1] += Si*sasai/10*derTerm[j][1];
+     880       26748 :           derivatives[Nlist[i][j]][2] += Si*sasai/10*derTerm[j][2];
+     881             :         }
+     882         864 :       }
+     883             :     }
+     884             :   }
+     885             : 
+     886             : 
+     887          24 :   if( sasa_type==TRANSFER ) {
+     888             : 
+     889          12 :     if (firstStepFlag ==0) {
+     890           1 :       readMaxSurf();
+     891             :     }
+     892             : 
+     893          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     894           1 :       readDeltaG();
+     895             :     }
+     896             : 
+     897          12 :     if (DeltaGValues == "absent") {
+     898           0 :       computeDeltaG();
+     899             :     }
+     900             : 
+     901             : 
+     902        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     903             : 
+     904             : 
+     905             : 
+     906        1440 :       if(SASAparam[i].size() > 0) {
+     907         864 :         double ri = SASAparam[i][0];
+     908         864 :         Si = 4*M_PI*ri*ri;
+     909             :         sasai = 1.0;
+     910             : 
+     911        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     912             : 
+     913         864 :         dAijt_di[0] = 0;
+     914         864 :         dAijt_di[1] = 0;
+     915         864 :         dAijt_di[2] = 0;
+     916         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     917             : 
+     918       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     919             :           double pij = 0.3516;
+     920             : 
+     921       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     922       26748 :           if (NumRes_i==NumRes_j) {
+     923        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     924             :               pij = 0.8875;
+     925             :             }
+     926             :           }
+     927       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     928       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     929             :               pij = 0.8875;
+     930             :             }
+     931             :           }
+     932             : 
+     933       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     934       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     935             : 
+     936       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     937       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     938             : 
+     939       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     940             : 
+     941       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     942       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     943       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     944             : 
+     945       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     946       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     947       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     948             : 
+     949       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     950       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     951       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     952             : 
+     953       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     954       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     955       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     956             : 
+     957             :         }
+     958             : 
+     959        2880 :         if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     960             : 
+     961         720 :           sasa += Si*sasai/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol
+     962             : 
+     963             : 
+     964         720 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][0]*DeltaG[natoms][0]*10; //kJ/mol/nm
+     965         720 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     966         720 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     967             :         }
+     968             : 
+     969        2880 :         if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     970         144 :           sasa += Si*sasai/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol
+     971             : 
+     972         144 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][1]*DeltaG[i][0]*10; //kJ/mol/nm
+     973         144 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     974         144 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     975             :         }
+     976             : 
+     977             : 
+     978       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     979       86883 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     980       22438 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol/nm
+     981       22438 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][0]*DeltaG[natoms][0];
+     982       22438 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][0]*DeltaG[natoms][0];
+     983             :           }
+     984             : 
+     985       86883 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     986        4310 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol/nm
+     987        4310 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][1]*DeltaG[i][0];
+     988        4310 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][1]*DeltaG[i][0];
+     989             :           }
+     990             :         }
+     991         864 :       }
+     992             :     }
+     993             :   }
+     994             : 
+     995             : 
+     996        2904 :   for(unsigned i=0; i<natoms; i++) {
+     997        2880 :     setAtomsDerivatives(i,derivatives[i]);
+     998        2880 :     virial -= Tensor(getPosition(i),derivatives[i]);
+     999             :   }
+    1000             : 
+    1001          24 :   setBoxDerivatives(virial);
+    1002          24 :   setValue(sasa);
+    1003          24 :   firstStepFlag = 1;
+    1004          24 :   ++nl_update;
+    1005          24 :   if (nl_update == stride) {
+    1006          24 :     nl_update = 0;
+    1007             :   }
+    1008             : // setBoxDerivativesNoPbc();
+    1009          24 : }
+    1010             : 
+    1011             : }//namespace sasa
+    1012             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html new file mode 100644 index 0000000000..7fc9f22950 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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:51963182.3 %
Date:2024-05-27 13:05: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_LCPORegisterMe1636createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe163C2Ev4168
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe163D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func.html b/coverage/sasa/sasa_LCPO.cpp.func.html new file mode 100644 index 0000000000..845be7b714 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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:51963182.3 %
Date:2024-05-27 13:05:14Functions:131681.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe1636createERKNS_13ActionOptionsE2
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe163C2Ev4168
_ZN4PLMD4sasa12_GLOBAL__N_122SASA_LCPORegisterMe163D2Ev4168
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.gcov.html b/coverage/sasa/sasa_LCPO.cpp.gcov.html new file mode 100644 index 0000000000..f82a8ad3da --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.gcov.html @@ -0,0 +1,1156 @@ + + + + + + + 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:51963182.3 %
Date:2024-05-27 13:05: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.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The LCPO algorithm is used for the calculation (please, read and cite \cite Weiser1999). The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of the SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : ----------------Sample DeltaG.dat file---------------------
+      58             : ALA     0.711019999999962
+      59             : ARG     -2.24832799999996
+      60             : ASN     -2.74838799999999
+      61             : ASP     -2.5626376
+      62             : CYS     3.89864000000006
+      63             : GLN     -1.76192
+      64             : GLU     -2.38664400000002
+      65             : GLY     0
+      66             : HIS     -3.58152799999999
+      67             : ILE     2.42634399999986
+      68             : LEU     1.77233599999988
+      69             : LYS     -1.92576400000002
+      70             : MET     -0.262827999999956
+      71             : PHE     1.62028800000007
+      72             : PRO     -2.15598800000001
+      73             : SER     -1.60934800000004
+      74             : THR     -0.591559999999987
+      75             : TRP     1.22936000000027
+      76             : TYR     0.775547999999958
+      77             : VAL     2.12779200000011
+      78             : BACKBONE        1.00066920000002
+      79             : -----------------------------------------------------------
+      80             : \endverbatim
+      81             : 
+      82             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      83             : 
+      84             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      85             : 
+      86             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      87             : 
+      88             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      89             : 
+      90             : In case you want to recover the old behavior you should use the NOPBC flag.
+      91             : In that case you need to take care that atoms are in the correct periodic image.
+      92             : 
+      93             : The SASA may also be computed using the SASA_HASEL collective variable, which makes use of the algorithm described in \cite Hasel1988. SASA_HASEL is less accurate then SASA_LCPO, but the computation is faster.
+      94             : 
+      95             : 
+      96             : 
+      97             : \par Examples
+      98             : 
+      99             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     100             : \plumedfile
+     101             : SASA_LCPO TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     102             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     103             : \endplumedfile
+     104             : 
+     105             : 
+     106             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     107             : 
+     108             : \plumedfile
+     109             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     110             : 
+     111             : bias: BIASVALUE ARG=sasa
+     112             : 
+     113             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     114             : \endplumedfile
+     115             : 
+     116             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     117             : 
+     118             : \plumedfile
+     119             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     120             : 
+     121             : bias: BIASVALUE ARG=sasa
+     122             : 
+     123             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     124             : \endplumedfile
+     125             : 
+     126             : */
+     127             : //+ENDPLUMEDOC
+     128             : 
+     129             : class SASA_LCPO : public Colvar {
+     130             : private:
+     131             :   enum CV_TYPE {TOTAL, TRANSFER};
+     132             :   int sasa_type;
+     133             :   bool nopbc;
+     134             :   double rs;
+     135             :   string DeltaGValues;
+     136             :   int approach;
+     137             :   unsigned stride;
+     138             :   unsigned nl_update;
+     139             :   int firstStepFlag;
+     140             :   double Ti;
+     141             :   // cppcheck-suppress duplInheritedMember
+     142             :   std::vector<AtomNumber> atoms;
+     143             :   vector < vector < std::string > > AtomResidueName;
+     144             :   vector < vector < double > > LCPOparam;
+     145             :   unsigned natoms;
+     146             :   vector < vector < double > > MaxSurf;
+     147             :   vector < vector < double > > DeltaG;
+     148             :   vector < vector < int > > Nlist;
+     149             : public:
+     150             :   static void registerKeywords(Keywords& keys);
+     151             :   explicit SASA_LCPO(const ActionOptions&);
+     152             :   void readPDB();
+     153             :   map<string, vector<double> > setupLCPOparam();
+     154             :   void readLCPOparam();
+     155             :   void calcNlist();
+     156             :   map<string, vector<double> > setupMaxSurfMap();
+     157             :   void readMaxSurf();
+     158             :   void readDeltaG();
+     159             :   void computeDeltaG();
+     160             :   virtual void calculate();
+     161             : };
+     162             : 
+     163       12508 : PLUMED_REGISTER_ACTION(SASA_LCPO,"SASA_LCPO")
+     164             : 
+     165           4 : void SASA_LCPO::registerKeywords(Keywords& keys) {
+     166           4 :   Colvar::registerKeywords(keys);
+     167           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     168           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     169           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list is updated.");
+     170           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy values for backbone and sidechains. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     171           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     172           4 : }
+     173             : 
+     174             : 
+     175           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
+     176             :   PLUMED_COLVAR_INIT(ao),
+     177           2 :   nopbc(false),
+     178           4 :   DeltaGValues("absent"),
+     179           2 :   Ti(0),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           2 :   firstStepFlag(0)
+     183             : {
+     184           2 :   rs = 0.14;
+     185           2 :   parse("DELTAGFILE",DeltaGValues);
+     186           2 :   parse("APPROACH", approach);
+     187           4 :   parseAtomList("ATOMS",atoms);
+     188           2 :   if(atoms.size()==0) error("no atoms specified");
+     189             :   std::string Type;
+     190           2 :   parse("TYPE",Type);
+     191           2 :   parse("NL_STRIDE", stride);
+     192           2 :   parseFlag("NOPBC",nopbc);
+     193           2 :   checkRead();
+     194             : 
+     195           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     196           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     197           0 :   else error("Unknown SASA type");
+     198             : 
+     199           2 :   switch(sasa_type)
+     200             :   {
+     201           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     202           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     203             :   }
+     204             : 
+     205           2 :   log.printf("  atoms involved : ");
+     206         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     207         240 :     if(i%25==0) log<<"\n";
+     208         240 :     log.printf("%d ",atoms[i].serial());
+     209             :   }
+     210           2 :   log.printf("\n");
+     211             : 
+     212           2 :   if(nopbc) {
+     213           0 :     log<<"  PBC will be ignored\n";
+     214             :   } else {
+     215           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     216             :   }
+     217             : 
+     218             : 
+     219           2 :   addValueWithDerivatives(); setNotPeriodic();
+     220           2 :   requestAtoms(atoms);
+     221             : 
+     222           2 :   natoms = getNumberOfAtoms();
+     223           2 :   AtomResidueName.resize(2);
+     224           2 :   LCPOparam.resize(natoms);
+     225           2 :   MaxSurf.resize(natoms);
+     226           2 :   DeltaG.resize(natoms+1);
+     227           2 :   Nlist.resize(natoms);
+     228             : 
+     229             : 
+     230           2 : }
+     231             : 
+     232             : 
+     233             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
+     234             : template <class Container>
+     235           0 : void split(const std::string& str, Container& cont)
+     236             : {
+     237           0 :   std::istringstream iss(str);
+     238           0 :   std::copy(std::istream_iterator<std::string>(iss),
+     239           0 :             std::istream_iterator<std::string>(),
+     240             :             std::back_inserter(cont));
+     241           0 : }
+     242             : 
+     243             : 
+     244             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     245             : 
+     246           2 : void SASA_LCPO::readPDB() {
+     247           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     248           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     249             :   AtomResidueName[0].clear();
+     250             :   AtomResidueName[1].clear();
+     251             : 
+     252         242 :   for(unsigned i=0; i<natoms; i++) {
+     253         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     254         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     255         240 :     AtomResidueName[0].push_back (Aname);
+     256         240 :     AtomResidueName[1].push_back (Rname);
+     257             :   }
+     258             : 
+     259           2 : }
+     260             : 
+     261             : //LCPO parameters database
+     262           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
+     263             :   map<string, vector<double> > lcpomap;
+     264           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     265           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     266           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     267           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     268           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     269           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     270           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     271           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     272           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     273           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     274           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     275           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     276           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     277           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     278           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     279           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     280           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     281           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     282           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     283           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     284           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     285           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     286           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     287           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     288           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     289           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     290           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     291           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     292           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     293           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     294           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     295           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     296           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     297           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     298           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     299           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     300           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     301           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     302           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     303           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     304           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     305           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     306           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     307           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     308           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     309           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     310           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     311           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     312           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     313           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     314           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     315           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     316           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     317           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     318           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     319           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     320           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     321           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     322           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     323           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     324           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     325           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     326           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     327           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     328           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     329           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     330           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     331           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     332           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     333           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     334           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     335           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     336           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     337           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     338           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     339           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     340           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     341           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     342           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     343           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     344           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     345           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     346           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     347           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     348           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     349           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     350           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     351           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     352           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     353           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     354           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     355           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     356           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     357           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     358           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     359           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     360           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     361           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     362           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     363           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     364           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     365           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     366           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     367           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     368           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     369           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     370           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     371           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     372           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     373           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     374           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     375           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     376           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     377           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     378           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     379           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     380           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     381           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     382           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     383           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     384           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     385           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     386           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     387           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     388           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     389           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     390           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     391           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     392           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     393           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     394           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     395           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     396           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     397           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     398           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     399           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     400           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     401           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     402           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     403           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     404           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     405           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     406           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     407           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     408           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     409           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     410           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     411           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     412           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     413           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     414           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     415           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     416           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     417           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     418           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     419           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     420           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     421           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     422           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     423           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     424           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     425           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     426           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     427           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     428           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     429           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     430           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     431           2 :   return lcpomap;
+     432             : }
+     433             : 
+     434             : //assigns LCPO parameters to each atom reading from database
+     435           2 : void SASA_LCPO::readLCPOparam() {
+     436             : 
+     437         242 :   for(unsigned i=0; i<natoms; i++) {
+     438         240 :     LCPOparam[i].clear();
+     439             :   }
+     440             : 
+     441             :   map<string, vector<double> > lcpomap;
+     442           4 :   lcpomap = setupLCPOparam();
+     443             :   vector<double> LCPOparamVector;
+     444             :   string identifier;
+     445         242 :   for(unsigned i=0; i<natoms; i++) {
+     446         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     447         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     448         120 :       LCPOparamVector = lcpomap.at(identifier);
+     449         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
+     450         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
+     451         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
+     452         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
+     453         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
+     454             :     }
+     455             :   }
+     456             : 
+     457             : 
+     458         242 :   for(unsigned i=0; i<natoms; i++) {
+     459         240 :     if (LCPOparam[i].size()==0 ) {
+     460         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     461           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     462           0 :         error ("missing LCPO parameters\n");
+     463             :       }
+     464             :     }
+     465             :   }
+     466             : 
+     467           2 :   if (AtomResidueName[0][0] == "N") {
+     468           2 :     LCPOparam[0][1] = 7.3511e-01;
+     469           2 :     LCPOparam[0][2] = -2.2116e-01;
+     470           2 :     LCPOparam[0][3] = -8.9148e-04;
+     471           2 :     LCPOparam[0][4] = 2.5230e-04;
+     472             :   }
+     473             : 
+     474           2 :   if (AtomResidueName[0][natoms-1] == "O") {
+     475           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+     476           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+     477           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+     478           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+     479             :   }
+     480           2 : }
+     481             : 
+     482             : 
+     483             : //Max Surf values, used only if TYPE=TRANSFER
+     484           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
+     485             :   // Max Surface Area for backbone and sidechain, in nm2
+     486             :   map<string, vector<double> > valuemap;
+     487           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
+     488           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
+     489           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
+     490           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
+     491           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
+     492           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
+     493           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
+     494           1 :   valuemap ["GLY"]= {0.861439,0,};
+     495           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
+     496           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
+     497           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
+     498           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
+     499           1 :   valuemap ["MET"]= {0.5856,1.498954,};
+     500           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
+     501           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
+     502           1 :   valuemap ["SER"]= {0.59074,0.714538,};
+     503           1 :   valuemap ["THR"]= {0.559116,0.951644,};
+     504           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
+     505           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
+     506           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
+     507           1 :   return valuemap;
+     508             : }
+     509             : 
+     510             : 
+     511             : 
+     512             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     513             : 
+     514           1 : void SASA_LCPO::readMaxSurf() {
+     515             :   map<string, vector<double> > valuemap;
+     516           2 :   valuemap = setupMaxSurfMap();
+     517             :   vector<double> MaxSurfVector;
+     518             : 
+     519         121 :   for(unsigned i=0; i<natoms; i++) {
+     520         120 :     MaxSurf[i].clear();
+     521         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     522         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     523         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     524             :   }
+     525           1 : }
+     526             : 
+     527             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     528             : 
+     529           1 : void SASA_LCPO::readDeltaG() {
+     530             : 
+     531         121 :   for(unsigned i=0; i<natoms; i++) {
+     532         120 :     DeltaG[i].clear();
+     533             :   }
+     534             : 
+     535             :   string DeltaGline;
+     536           1 :   fstream DeltaGFile;
+     537           1 :   DeltaGFile.open(DeltaGValues);
+     538           1 :   if (DeltaGFile) {
+     539             :     int backboneflag = 0;
+     540          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     541          22 :       if(!DeltaGline.empty()) {
+     542             :         std::vector<std::string> DeltaGtoken;
+     543          21 :         split(DeltaGline, DeltaGtoken);
+     544        2541 :         for(unsigned i=0; i<natoms; i++) {
+     545        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     546         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     547             :           }
+     548             :         }
+     549          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     550             :           backboneflag = 1;
+     551           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     552             :         }
+     553          21 :       }
+     554             :     }
+     555           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     556             :   }
+     557           0 :   else error("Cannot open DeltaG file");
+     558             : 
+     559         121 :   for(unsigned i=0; i<natoms; i++) {
+     560         120 :     if (DeltaG[i].size()==0 ) {
+     561           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     562           0 :       error ("missing Delta G parameter\n");
+     563             :     }
+     564             :   }
+     565             : 
+     566           2 : }
+     567             : 
+     568             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     569             : 
+     570           0 : void SASA_LCPO::computeDeltaG() {
+     571             : 
+     572           0 :   for(unsigned i=0; i<natoms; i++) {
+     573           0 :     DeltaG[i].clear();
+     574             :   }
+     575             : 
+     576             :   double T;
+     577           0 :   T = plumed.getAtoms().getKbT()/plumed.getAtoms().getKBoltzmann();
+     578             : 
+     579           0 :   if (T != Ti) {
+     580           0 :     for(unsigned i=0; i<natoms; i++) {
+     581           0 :       if (approach==2) {
+     582           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     583           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     584             :         }
+     585           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     586           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     587             :         }
+     588           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     589           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     590             :         }
+     591           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     592           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     593             :         }
+     594           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     595           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     596             :         }
+     597           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     598           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     599             :         }
+     600           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     601           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     602             :         }
+     603           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     604           0 :           DeltaG[i].push_back (0);
+     605             :         }
+     606           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     607           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     608             :         }
+     609           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     610           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     611             :         }
+     612           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     613           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     614             :         }
+     615           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     616           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     617             :         }
+     618           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     619           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     620             :         }
+     621           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     622           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     623             :         }
+     624           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     625           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     626             :         }
+     627           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     628           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     629             :         }
+     630           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     631           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     632             :         }
+     633           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     634           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     635             :         }
+     636           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     637           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     638             :         }
+     639           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     640           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     641             :         }
+     642           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     643             :       }
+     644           0 :       if (approach==3) {
+     645           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     646           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     647             :         }
+     648           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     649           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     650             :         }
+     651           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     652           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     653             :         }
+     654           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     655           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     656             :         }
+     657           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     658           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     659             :         }
+     660           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     661           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     662             :         }
+     663           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     664           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     665             :         }
+     666           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     667           0 :           DeltaG[i].push_back (0);
+     668             :         }
+     669           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     670           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     671             :         }
+     672           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     673           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     674             :         }
+     675           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     676           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     677             :         }
+     678           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     679           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     680             :         }
+     681           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     682           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     683             :         }
+     684           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     685           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     686             :         }
+     687           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     688           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     689             :         }
+     690           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     691           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     692             :         }
+     693           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     694           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     695             :         }
+     696           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     697           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     698             :         }
+     699           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     700           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     701             :         }
+     702           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     703           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     704             :         }
+     705           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     706             :       }
+     707             :     }
+     708             :   }
+     709             : 
+     710           0 :   Ti = T;
+     711             : 
+     712           0 :   if (firstStepFlag ==0) {
+     713           0 :     if (approach!=2 && approach!=3) {
+     714           0 :       cout << "Unknown approach " << approach << endl;
+     715             :     }
+     716           0 :     for(unsigned i=0; i<natoms; i++) {
+     717           0 :       if (DeltaG[i].size()==0 ) {
+     718           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     719           0 :         error ("missing Delta G parameter\n");
+     720             :       }
+     721             :     }
+     722             :   }
+     723           0 : }
+     724             : 
+     725             : 
+     726             : //calculates neighbor list
+     727          24 : void SASA_LCPO::calcNlist() {
+     728          24 :   if(!nopbc) makeWhole();
+     729             : 
+     730        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     731        2880 :     Nlist[i].clear();
+     732             :   }
+     733             : 
+     734        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     735        2880 :     if (LCPOparam[i].size()>0) {
+     736       87264 :       for (unsigned j = 0; j < i; j++) {
+     737       85824 :         if (LCPOparam[j].size()>0) {
+     738       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     739       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     740       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     741       42480 :           if (Delta_ij_mod < overlapD) {
+     742       19030 :             Nlist.at(i).push_back (j);
+     743       19030 :             Nlist.at(j).push_back (i);
+     744             :           }
+     745             :         }
+     746             :       }
+     747             :     }
+     748             :   }
+     749          24 : }
+     750             : 
+     751             : 
+     752             : //calculates SASA according to LCPO algorithm
+     753          24 : void SASA_LCPO::calculate() {
+     754          24 :   if(!nopbc) makeWhole();
+     755             : 
+     756          24 :   if(getExchangeStep()) nl_update = 0;
+     757          24 :   if (firstStepFlag ==0) {
+     758           2 :     readPDB();
+     759           2 :     readLCPOparam();
+     760             :   }
+     761          24 :   if (nl_update == 0) {
+     762          24 :     calcNlist();
+     763             :   }
+     764             : 
+     765             : 
+     766             : 
+     767             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
+     768             :   double dAdd;
+     769          24 :   double sasa = 0;
+     770          24 :   vector<Vector> derivatives( natoms );
+     771          24 :   Tensor virial;
+     772          24 :   vector <double> dAijdc_2t(3);
+     773          24 :   vector <double> dSASA_2_neigh_dc(3);
+     774          24 :   vector <double> ddij_di(3);
+     775          24 :   vector <double> ddik_di(3);
+     776             : 
+     777          24 :   if( sasa_type==TOTAL ) {
+     778        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     779        1440 :       derivatives[i][0] = 0.;
+     780        1440 :       derivatives[i][1] = 0.;
+     781        1440 :       derivatives[i][2] = 0.;
+     782        1440 :       if ( LCPOparam[i].size()>1) {
+     783         720 :         if (LCPOparam[i][1]>0.0) {
+     784             :           Aij = 0.0;
+     785             :           Aijk = 0.0;
+     786             :           Ajk = 0.0;
+     787         720 :           double ri = LCPOparam[i][0];
+     788         720 :           S1 = 4*M_PI*ri*ri;
+     789         720 :           vector <double> dAijdc_2(3, 0);
+     790         720 :           vector <double> dAijdc_4(3, 0);
+     791             : 
+     792             : 
+     793       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     794       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     795       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     796             : 
+     797       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     798       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     799       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     800             : 
+     801       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     802             : 
+     803       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     804       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     805       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     806             : 
+     807             :             Ajkt = 0.0;
+     808             :             Aikt = 0.0;
+     809             : 
+     810       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     811       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     812       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     813       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     814             : 
+     815       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     816       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     817       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     818             : 
+     819       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     820             : 
+     821             : 
+     822       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     823       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     824       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     825             : 
+     826      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     827      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     828      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     829      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     830             : 
+     831      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     832      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     833             : 
+     834      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     835      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     836      370872 :                 Ajkt += sjk;
+     837      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     838             : 
+     839      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     840             : 
+     841      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     842      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     843      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     844             : 
+     845             : 
+     846      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     847      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     848      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     849             : 
+     850      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     851             : 
+     852      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     853      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     854      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+     855             : 
+     856      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+     857      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+     858      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+     859             : 
+     860             :               }
+     861             :             }
+     862       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+     863       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+     864       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+     865             : 
+     866       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+     867       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+     868       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+     869             : 
+     870       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+     871       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+     872       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+     873             : 
+     874             : 
+     875       19030 :             derivatives[i][0] += (dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/10;
+     876       19030 :             derivatives[i][1] += (dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/10;
+     877       19030 :             derivatives[i][2] += (dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/10;
+     878             : 
+     879             : 
+     880       19030 :             Aijk += (Aijt * Ajkt);
+     881       19030 :             Aij += Aijt;
+     882       19030 :             Ajk += Ajkt;
+     883             : 
+     884       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+     885       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+     886       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+     887             : 
+     888             : 
+     889       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+     890       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+     891       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+     892             : 
+     893             : 
+     894             :           }
+     895         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     896         720 :           if (sasai > 0 ) sasa += sasai/100;
+     897         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
+     898         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
+     899         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
+     900             :         }
+     901             :       }
+     902        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+     903             :     }
+     904             :   }
+     905             : 
+     906             : 
+     907             : 
+     908          24 :   if( sasa_type==TRANSFER ) {
+     909             : 
+     910          12 :     if (firstStepFlag ==0) {
+     911           1 :       readMaxSurf();
+     912             :     }
+     913             : 
+     914          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     915           1 :       readDeltaG();
+     916             :     }
+     917             : 
+     918          12 :     if (DeltaGValues == "absent") {
+     919           0 :       computeDeltaG();
+     920             :     }
+     921             : 
+     922             : 
+     923        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     924             : 
+     925             : 
+     926             : 
+     927        1440 :       derivatives[i][0] = 0.;
+     928        1440 :       derivatives[i][1] = 0.;
+     929        1440 :       derivatives[i][2] = 0.;
+     930             : 
+     931        1440 :       if ( LCPOparam[i].size()>1) {
+     932         720 :         if (LCPOparam[i][1]>0.0) {
+     933             :           Aij = 0.0;
+     934             :           Aijk = 0.0;
+     935             :           Ajk = 0.0;
+     936         720 :           double ri = LCPOparam[i][0];
+     937         720 :           S1 = 4*M_PI*ri*ri;
+     938         720 :           vector <double> dAijdc_2(3, 0);
+     939         720 :           vector <double> dAijdc_4(3, 0);
+     940             : 
+     941             : 
+     942       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     943       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     944       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     945             : 
+     946       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     947       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     948       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     949             : 
+     950       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     951       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     952       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     953       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     954             : 
+     955             :             Ajkt = 0.0;
+     956             :             Aikt = 0.0;
+     957             : 
+     958       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     959       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     960       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     961       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     962             : 
+     963       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     964       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     965       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     966             : 
+     967       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     968             : 
+     969       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     970       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     971       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     972             : 
+     973      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     974      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     975      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     976      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     977             : 
+     978      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     979      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     980             : 
+     981      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     982      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     983      370872 :                 Ajkt += sjk;
+     984      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     985             : 
+     986      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     987             : 
+     988      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     989      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     990      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     991             : 
+     992             : 
+     993      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     994      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     995      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     996             : 
+     997      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     998             : 
+     999      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+    1000      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+    1001      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+    1002             : 
+    1003      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+    1004      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+    1005      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+    1006             : 
+    1007             :               }
+    1008             :             }
+    1009       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+    1010       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+    1011       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+    1012             : 
+    1013       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+    1014       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+    1015       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+    1016             : 
+    1017       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+    1018       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+    1019       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+    1020             : 
+    1021       19030 :             if (AtomResidueName[0][Nlist[i][j]] == "N" || AtomResidueName[0][Nlist[i][j]] == "CA"  || AtomResidueName[0][Nlist[i][j]] == "C" || AtomResidueName[0][Nlist[i][j]] == "O") {
+    1022       15720 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1023       15720 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1024       15720 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1025             :             }
+    1026             : 
+    1027       19030 :             if (AtomResidueName[0][Nlist[i][j]] != "N" && AtomResidueName[0][Nlist[i][j]] != "CA"  && AtomResidueName[0][Nlist[i][j]] != "C" && AtomResidueName[0][Nlist[i][j]] != "O") {
+    1028        3310 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1029        3310 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1030        3310 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1031             :             }
+    1032             : 
+    1033       19030 :             Aijk += (Aijt * Ajkt);
+    1034       19030 :             Aij += Aijt;
+    1035       19030 :             Ajk += Ajkt;
+    1036             : 
+    1037       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+    1038       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+    1039       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+    1040             : 
+    1041       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+    1042       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+    1043       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+    1044             : 
+    1045             :           }
+    1046             :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1047             : 
+    1048        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
+    1049         576 :             if (sasai > 0 ) sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
+    1050         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1051         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1052         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1053             :           }
+    1054             : 
+    1055        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
+    1056         144 :             if (sasai > 0. ) sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
+    1057         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1058         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1059         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1060             :           }
+    1061             :         }
+    1062             :       }
+    1063        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+    1064             :     }
+    1065             :   }
+    1066             : 
+    1067             : 
+    1068        2904 :   for(unsigned i=0; i<natoms; i++) { setAtomsDerivatives(i,derivatives[i]);}
+    1069          24 :   setBoxDerivatives(virial);
+    1070          24 :   setValue(sasa);
+    1071          24 :   firstStepFlag = 1;
+    1072          24 :   ++nl_update;
+    1073          24 :   if (nl_update == stride) {
+    1074          24 :     nl_update = 0;
+    1075             :   }
+    1076             : // setBoxDerivativesNoPbc();
+    1077          24 : }
+    1078             : 
+    1079             : }//namespace sasa
+    1080             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..daf4166781 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe946createERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func.html b/coverage/secondarystructure/AlphaRMSD.cpp.func.html new file mode 100644 index 0000000000..09e24323ca --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe946createERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_121AlphaRMSDRegisterMe94D2Ev4168
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..f125574e87 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5050100.0 %
Date:2024-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(AlphaRMSD,"ALPHARMSD")
+      95             : 
+      96           5 : void AlphaRMSD::registerKeywords( Keywords& keys ) {
+      97           5 :   SecondaryStructureRMSD::registerKeywords( keys );
+      98           5 : }
+      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.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..38aa13987c --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe956createERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html new file mode 100644 index 0000000000..28920ca434 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe956createERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_124AntibetaRMSDRegisterMe95D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..1e14e4cb59 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:767897.4 %
Date:2024-05-27 13:05: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       12528 : PLUMED_REGISTER_ACTION(AntibetaRMSD,"ANTIBETARMSD")
+      96             : 
+      97          14 : void AntibetaRMSD::registerKeywords( Keywords& keys ) {
+      98          14 :   SecondaryStructureRMSD::registerKeywords( keys );
+      99          28 :   keys.add("compulsory","STYLE","all","Antiparallel beta sheets can either form in a single chain or from a pair of chains. If STYLE=all all "
+     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          14 :   keys.use("STRANDS_CUTOFF");
+     104          14 : }
+     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.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..90c016e0ff --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe966createERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html new file mode 100644 index 0000000000..6d4f77ad44 --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe966createERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96C2Ev4168
_ZN4PLMD18secondarystructure12_GLOBAL__N_124ParabetaRMSDRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html new file mode 100644 index 0000000000..3bf8517dae --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html @@ -0,0 +1,320 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10610997.2 %
Date:2024-05-27 13:05: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       12524 : PLUMED_REGISTER_ACTION(ParabetaRMSD,"PARABETARMSD")
+      97             : 
+      98          12 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
+      99          12 :   SecondaryStructureRMSD::registerKeywords( keys );
+     100          24 :   keys.add("compulsory","STYLE","all","Parallel beta sheets can either form in a single chain or from a pair of chains. If STYLE=all all "
+     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          12 :   keys.use("STRANDS_CUTOFF");
+     105          12 : }
+     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.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..d9e7e52f8e --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE31
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD21setSecondaryStructureERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEdd35
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17turnOnDerivativesEv62
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD5applyEv192
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv2568
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9addColvarERKSt6vectorIjSaIjEE99342
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjS3_RNS_10MultiValueE400032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html new file mode 100644 index 0000000000..604ca04335 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + 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-05-27 13:05:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17turnOnDerivativesEv62
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19setAtomsFromStrandsERKjS3_22
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD21setSecondaryStructureERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEdd35
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD5applyEv192
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9addColvarERKSt6vectorIjSaIjEE99342
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv2568
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD0Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD1Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD2Ev25
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjS3_RNS_10MultiValueE400032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html new file mode 100644 index 0000000000..e5e80d7cf9 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html @@ -0,0 +1,344 @@ + + + + + + + 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-05-27 13:05: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          31 : void SecondaryStructureRMSD::registerKeywords( Keywords& keys ) {
+      35          31 :   Action::registerKeywords( keys );
+      36          31 :   ActionWithValue::registerKeywords( keys );
+      37          31 :   ActionAtomistic::registerKeywords( keys );
+      38          62 :   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          62 :   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          62 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions");
+      49          62 :   keys.add("compulsory","R_0","0.08","The r_0 parameter of the switching function.");
+      50          62 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      51          62 :   keys.add("compulsory","NN","8","The n parameter of the switching function");
+      52          62 :   keys.add("compulsory","MM","12","The m parameter of the switching function");
+      53          62 :   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          62 :   keys.addFlag("VERBOSE",false,"write a more detailed output");
+      58          62 :   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          31 :   ActionWithVessel::registerKeywords( keys );
+      61         155 :   keys.use("LESS_THAN"); keys.use("MIN"); keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      62          31 :   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          31 : }
+      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          50 :   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.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html new file mode 100644 index 0000000000..3f4f6e2880 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html new file mode 100644 index 0000000000..8b1af76610 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html new file mode 100644 index 0000000000..4b6464f33c --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html @@ -0,0 +1,186 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-f.html b/coverage/secondarystructure/index-sort-f.html new file mode 100644 index 0000000000..648d669850 --- /dev/null +++ b/coverage/secondarystructure/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37638996.7 %
Date:2024-05-27 13:05: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
AlphaRMSD.cpp +
100.0%
+
100.0 %50 / 5083.3 %5 / 6
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
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-l.html b/coverage/secondarystructure/index-sort-l.html new file mode 100644 index 0000000000..e7bcd82cc6 --- /dev/null +++ b/coverage/secondarystructure/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37638996.7 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/secondarystructure/index.html b/coverage/secondarystructure/index.html new file mode 100644 index 0000000000..3a7f332825 --- /dev/null +++ b/coverage/secondarystructure/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37638996.7 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func-sort-c.html b/coverage/setup/Load.cpp.func-sort-c.html new file mode 100644 index 0000000000..f52e1f55ee --- /dev/null +++ b/coverage/setup/Load.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe1046createERKNS_13ActionOptionsE2
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE2
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func.html b/coverage/setup/Load.cpp.func.html new file mode 100644 index 0000000000..85d020c634 --- /dev/null +++ b/coverage/setup/Load.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe1046createERKNS_13ActionOptionsE2
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_117LoadRegisterMe104D2Ev4168
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE2
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.gcov.html b/coverage/setup/Load.cpp.gcov.html new file mode 100644 index 0000000000..291446b345 --- /dev/null +++ b/coverage/setup/Load.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_ACTION(Load,"LOAD")
+     105             : 
+     106           4 : void Load::registerKeywords( Keywords& keys ) {
+     107           4 :   ActionSetup::registerKeywords(keys);
+     108           8 :   keys.add("compulsory","FILE","file to be loaded");
+     109           4 : }
+     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.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func-sort-c.html b/coverage/setup/Restart.cpp.func-sort-c.html new file mode 100644 index 0000000000..69980e33c7 --- /dev/null +++ b/coverage/setup/Restart.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe986createERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func.html b/coverage/setup/Restart.cpp.func.html new file mode 100644 index 0000000000..002b43286e --- /dev/null +++ b/coverage/setup/Restart.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe986createERKNS_13ActionOptionsE56
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_119RestartRegisterMe98D2Ev4168
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.gcov.html b/coverage/setup/Restart.cpp.gcov.html new file mode 100644 index 0000000000..2ac722b6f8 --- /dev/null +++ b/coverage/setup/Restart.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + 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-05-27 13:05: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       12616 : PLUMED_REGISTER_ACTION(Restart,"RESTART")
+      99             : 
+     100          58 : void Restart::registerKeywords( Keywords& keys ) {
+     101          58 :   ActionSetup::registerKeywords(keys);
+     102         116 :   keys.addFlag("NO",false,"switch off restart - can be used to override the behavior of the MD engine");
+     103          58 : }
+     104             : 
+     105          56 : Restart::Restart(const ActionOptions&ao):
+     106             :   Action(ao),
+     107          56 :   ActionSetup(ao)
+     108             : {
+     109          56 :   bool no=false;
+     110          56 :   parseFlag("NO",no);
+     111          56 :   bool md=plumed.getRestart();
+     112         111 :   log<<"  MD code "<<(md?"did":"didn't")<<" require restart\n";
+     113          56 :   if(no) {
+     114           1 :     if(md) log<<"  Switching off restart\n";
+     115           1 :     plumed.setRestart(false);
+     116           1 :     log<<"  Not restarting simulation: files will be backed up\n";
+     117             :   } else {
+     118          55 :     if(!md) log<<"  Switching on restart\n";
+     119          55 :     plumed.setRestart(true);
+     120          55 :     log<<"  Restarting simulation: files will be appended\n";
+     121             :   }
+     122          56 : }
+     123             : 
+     124             : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func-sort-c.html b/coverage/setup/Units.cpp.func-sort-c.html new file mode 100644 index 0000000000..ef89bc8975 --- /dev/null +++ b/coverage/setup/Units.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe986createERKNS_13ActionOptionsE20
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE20
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func.html b/coverage/setup/Units.cpp.func.html new file mode 100644 index 0000000000..2c5ceb7ab5 --- /dev/null +++ b/coverage/setup/Units.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe986createERKNS_13ActionOptionsE20
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98C2Ev4168
_ZN4PLMD5setup12_GLOBAL__N_117UnitsRegisterMe98D2Ev4168
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE20
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.gcov.html b/coverage/setup/Units.cpp.gcov.html new file mode 100644 index 0000000000..fb3927c660 --- /dev/null +++ b/coverage/setup/Units.cpp.gcov.html @@ -0,0 +1,277 @@ + + + + + + + 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-05-27 13:05: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       12544 : PLUMED_REGISTER_ACTION(Units,"UNITS")
+      99             : 
+     100          22 : void Units::registerKeywords( Keywords& keys ) {
+     101          22 :   ActionSetup::registerKeywords(keys);
+     102          44 :   keys.add("optional","LENGTH","the units of lengths.  Either specify a conversion factor from the default, nm, or use one of the defined units, A (for angstroms), um (for micrometer), and Bohr.");
+     103          44 :   keys.add("optional","ENERGY","the units of energy.  Either specify a conversion factor from the default, kj/mol, or use one of the defined units, j/mol, kcal/mol and Ha (for Hartree)");
+     104          44 :   keys.add("optional","TIME","the units of time.  Either specify a conversion factor from the default, ps, or use one of the defined units, ns, fs, and atomic");
+     105          44 :   keys.add("optional","MASS","the units of masses.  Specify a conversion factor from the default, amu");
+     106          44 :   keys.add("optional","CHARGE","the units of charges.  Specify a conversion factor from the default, e");
+     107          44 :   keys.addFlag("NATURAL",false,"use natural units");
+     108          22 : }
+     109             : 
+     110          20 : Units::Units(const ActionOptions&ao):
+     111             :   Action(ao),
+     112          20 :   ActionSetup(ao)
+     113             : {
+     114          20 :   PLMD::Units u;
+     115             : 
+     116             :   std::string s;
+     117             : 
+     118             :   s="";
+     119          40 :   parse("LENGTH",s);
+     120          20 :   if(s.length()>0) u.setLength(s);
+     121          38 :   if(u.getLengthString().length()>0 && u.getLengthString()=="nm") {
+     122           8 :     log.printf("  length: %s\n",u.getLengthString().c_str());
+     123             :   }
+     124          22 :   else if(u.getLengthString().length()>0 && u.getLengthString()!="nm") {
+     125          10 :     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          40 :   parse("ENERGY",s);
+     133          20 :   if(s.length()>0) u.setEnergy(s);
+     134          38 :   if(u.getEnergyString().length()>0 && u.getEnergyString()=="kj/mol") {
+     135          13 :     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          40 :   parse("TIME",s);
+     146          20 :   if(s.length()>0) u.setTime(s);
+     147          38 :   if(u.getTimeString().length()>0 && u.getTimeString()=="ps") {
+     148          15 :     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          40 :   parse("CHARGE",s);
+     159          20 :   if(s.length()>0) u.setCharge(s);
+     160          38 :   if(u.getChargeString().length()>0 && u.getChargeString()=="e") {
+     161          18 :     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          40 :   parse("MASS",s);
+     172          20 :   if(s.length()>0) u.setMass(s);
+     173          39 :   if(u.getMassString().length()>0 && u.getMassString()=="amu") {
+     174          19 :     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          20 :   bool natural=false;
+     184          20 :   parseFlag("NATURAL",natural);
+     185          20 :   plumed.getAtoms().setNaturalUnits(natural);
+     186             : 
+     187          20 :   checkRead();
+     188             : 
+     189          20 :   plumed.getAtoms().setUnits(u);
+     190          20 :   if(natural) {
+     191           6 :     log.printf("  using natural units\n");
+     192             :   } else {
+     193          14 :     log.printf("  using physical units\n");
+     194             :   }
+     195          20 :   log.printf("  inside PLUMED, Boltzmann constant is %g\n",plumed.getAtoms().getKBoltzmann());
+     196             : 
+     197          20 :   plumed.getAtoms().updateUnits();
+     198          20 : }
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-f.html b/coverage/setup/index-sort-f.html new file mode 100644 index 0000000000..851c3bdbb2 --- /dev/null +++ b/coverage/setup/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:878997.8 %
Date:2024-05-27 13:05:14Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Restart.cpp +
100.0%
+
100.0 %19 / 1983.3 %5 / 6
Units.cpp +
96.6%96.6%
+
96.6 %57 / 5983.3 %5 / 6
Load.cpp +
100.0%
+
100.0 %11 / 1183.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-l.html b/coverage/setup/index-sort-l.html new file mode 100644 index 0000000000..dbd4cf1876 --- /dev/null +++ b/coverage/setup/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:878997.8 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/setup/index.html b/coverage/setup/index.html new file mode 100644 index 0000000000..8102b96d56 --- /dev/null +++ b/coverage/setup/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:878997.8 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/snow.png b/coverage/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage/tools/Angle.cpp.func-sort-c.html b/coverage/tools/Angle.cpp.func-sort-c.html new file mode 100644 index 0000000000..0d585ad239 --- /dev/null +++ b/coverage/tools/Angle.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.func.html b/coverage/tools/Angle.cpp.func.html new file mode 100644 index 0000000000..b077f15dd0 --- /dev/null +++ b/coverage/tools/Angle.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.gcov.html b/coverage/tools/Angle.cpp.gcov.html new file mode 100644 index 0000000000..ac7bb41007 --- /dev/null +++ b/coverage/tools/Angle.cpp.gcov.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func-sort-c.html b/coverage/tools/AtomNumber.h.func-sort-c.html new file mode 100644 index 0000000000..a28a349119 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj713333
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func.html b/coverage/tools/AtomNumber.h.func.html new file mode 100644 index 0000000000..4b8c989b24 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func.html @@ -0,0 +1,80 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj696
_ZN4PLMD10AtomNumber9setSerialEj713333
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.gcov.html b/coverage/tools/AtomNumber.h.gcov.html new file mode 100644 index 0000000000..977aaaee17 --- /dev/null +++ b/coverage/tools/AtomNumber.h.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-05-27 13:05: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     1581971 : AtomNumber::AtomNumber() {
+      75     1581923 :   index_=0;
+      76             : }
+      77             : 
+      78             : inline
+      79             : AtomNumber::AtomNumber(unsigned i) {
+      80             :   index_=i;
+      81             : }
+      82             : 
+      83             : inline
+      84             : unsigned AtomNumber::serial()const {
+      85      411757 :   return index_+1;
+      86             : }
+      87             : 
+      88             : inline
+      89             : unsigned AtomNumber::index()const {
+      90    38158570 :   return index_;
+      91             : }
+      92             : 
+      93             : inline
+      94      713333 : AtomNumber & AtomNumber::setSerial(unsigned i) {
+      95      713333 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+      96      713333 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+      97      713333 :   index_=i-1;
+      98      713333 :   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   376057732 :   return a.index_<b.index_;
+     122             : }
+     123             : 
+     124             : inline
+     125             : bool operator>(const AtomNumber&a,const AtomNumber&b) {
+     126      692645 :   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   172343719 :   return a.index_==b.index_;
+     142             : }
+     143             : 
+     144             : inline
+     145             : bool operator!=(const AtomNumber&a,const AtomNumber&b) {
+     146   117933074 :   return a.index_!=b.index_;
+     147             : }
+     148             : 
+     149             : }
+     150             : 
+     151             : #endif
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func-sort-c.html b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html new file mode 100644 index 0000000000..99822927e6 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func.html b/coverage/tools/BiasRepresentation.cpp.func.html new file mode 100644 index 0000000000..9e7ecbed6e --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.gcov.html b/coverage/tools/BiasRepresentation.cpp.gcov.html new file mode 100644 index 0000000000..90a5295ea4 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.gcov.html @@ -0,0 +1,363 @@ + + + + + + + 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-05-27 13:05: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        6750 :     } else nneighb=kk->getSupport(BiasGrid_->getDx());
+     181        3375 :     std::vector<Grid::index_t> neighbors=BiasGrid_->getNeighbors(kk->getCenter(),nneighb);
+     182        3375 :     std::vector<double> der(ndim);
+     183        3375 :     std::vector<double> xx(ndim);
+     184        3375 :     if(mycomm.Get_size()==1) {
+     185     1027680 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     186     1024305 :         Grid::index_t ineigh=neighbors[i];
+     187     3072823 :         for(int j=0; j<ndim; ++j) {der[j]=0.0;}
+     188     1024305 :         BiasGrid_->getPoint(ineigh,xx);
+     189             :         // assign xx to a new vector of values
+     190     3072823 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     191             :         double bias;
+     192     1024305 :         if(doInt_) bias=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     193     1024305 :         else bias=kk->evaluate(values,der,true);
+     194     1024305 :         if(rescaledToBias) {
+     195       45234 :           double f=(biasf.back()-1.)/(biasf.back());
+     196       45234 :           bias*=f;
+     197      135702 :           for(int j=0; j<ndim; ++j) {der[j]*=f;}
+     198             :         }
+     199     1024305 :         BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
+     200             :       }
+     201             :     } else {
+     202           0 :       unsigned stride=mycomm.Get_size();
+     203           0 :       unsigned rank=mycomm.Get_rank();
+     204           0 :       std::vector<double> allder(ndim*neighbors.size(),0.0);
+     205           0 :       std::vector<double> allbias(neighbors.size(),0.0);
+     206           0 :       std::vector<double> tmpder(ndim);
+     207           0 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+     208           0 :         Grid::index_t ineigh=neighbors[i];
+     209           0 :         BiasGrid_->getPoint(ineigh,xx);
+     210           0 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     211           0 :         if(doInt_) allbias[i]=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     212           0 :         else allbias[i]=kk->evaluate(values,der,true);
+     213           0 :         if(rescaledToBias) {
+     214           0 :           double f=(biasf.back()-1.)/(biasf.back());
+     215           0 :           allbias[i]*=f;
+     216           0 :           for(int j=0; j<ndim; ++j) {tmpder[j]*=f;}
+     217             :         }
+     218             :         // this solution with the temporary vector is rather bad, probably better to take
+     219             :         // a pointer of double as it was in old gaussian
+     220           0 :         for(int j=0; j<ndim; ++j) { allder[ndim*i+j]=tmpder[j]; tmpder[j]=0.;}
+     221             :       }
+     222           0 :       mycomm.Sum(allbias);
+     223           0 :       mycomm.Sum(allder);
+     224           0 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     225           0 :         Grid::index_t ineigh=neighbors[i];
+     226           0 :         for(int j=0; j<ndim; ++j) {der[j]=allder[ndim*i+j];}
+     227           0 :         BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
+     228             :       }
+     229             :     }
+     230             :   }
+     231        5563 :   hills.emplace_back(std::move(kk));
+     232        5563 : }
+     233             : 
+     234        5578 : int BiasRepresentation::getNumberOfKernels() {
+     235        5578 :   return hills.size();
+     236             : }
+     237             : 
+     238          10 : Grid* BiasRepresentation::getGridPtr() {
+     239          10 :   plumed_massert(hasgrid,"if you want the grid pointer then you should have defined a grid before");
+     240          10 :   return BiasGrid_.get();
+     241             : }
+     242             : 
+     243           5 : void BiasRepresentation::getMinMaxBin(std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin) {
+     244             :   std::vector<double> ss,cc,binsize;
+     245           5 :   vmin.clear(); vmin.resize(ndim,10.e20);
+     246           5 :   vmax.clear(); vmax.resize(ndim,-10.e20);
+     247           5 :   vbin.clear(); vbin.resize(ndim);
+     248           5 :   binsize.clear(); binsize.resize(ndim,10.e20);
+     249             :   int ndiv=10; // adjustable parameter: division per support
+     250        2193 :   for(unsigned i=0; i<hills.size(); i++) {
+     251        2188 :     if(histosigma.size()!=0) {
+     252         546 :       ss=histosigma;
+     253             :     } else {
+     254        3284 :       ss=hills[i]->getContinuousSupport();
+     255             :     }
+     256        2188 :     cc=hills[i]->getCenter();
+     257        6564 :     for(int j=0; j<ndim; j++) {
+     258        4376 :       double dmin=cc[j]-ss[j];
+     259        4376 :       double dmax=cc[j]+ss[j];
+     260        4376 :       double ddiv=ss[j]/double(ndiv);
+     261        4376 :       if(dmin<vmin[j])vmin[j]=dmin;
+     262        4376 :       if(dmax>vmax[j])vmax[j]=dmax;
+     263        4376 :       if(ddiv<binsize[j])binsize[j]=ddiv;
+     264             :     }
+     265             :   }
+     266          15 :   for(int j=0; j<ndim; j++) {
+     267             :     // reset to periodicity
+     268          10 :     if(values[j]->isPeriodic()) {
+     269             :       double minv,maxv;
+     270           8 :       values[j]->getDomain(minv,maxv);
+     271           8 :       if(minv>vmin[j])vmin[j]=minv;
+     272           8 :       if(maxv<vmax[j])vmax[j]=maxv;
+     273             :     }
+     274          10 :     vbin[j]=static_cast<unsigned>(std::ceil((vmax[j]-vmin[j])/binsize[j]) );
+     275             :   }
+     276           5 : }
+     277             : 
+     278           0 : void BiasRepresentation::clear() {
+     279           0 :   hills.clear();
+     280             :   // clear the grid
+     281           0 :   if(hasgrid) {
+     282           0 :     BiasGrid_->clear();
+     283             :   }
+     284           0 : }
+     285             : 
+     286             : 
+     287             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func-sort-c.html b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html new file mode 100644 index 0000000000..54c13c6475 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func.html b/coverage/tools/Brent1DRootSearch.h.func.html new file mode 100644 index 0000000000..d316c17291 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.gcov.html b/coverage/tools/Brent1DRootSearch.h.gcov.html new file mode 100644 index 0000000000..617a765e25 --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.gcov.html @@ -0,0 +1,196 @@ + + + + + + + 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-05-27 13:05: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        5194 :         p=2.0*xm*s; q=1.0-s;
+      96             :       } else {
+      97        2155 :         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         699 :     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.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func-sort-c.html b/coverage/tools/Citations.cpp.func-sort-c.html new file mode 100644 index 0000000000..0125d1e2b7 --- /dev/null +++ b/coverage/tools/Citations.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Citations5emptyEv318
_ZN4PLMD9Citations5clearEv358
_ZN4PLMDlsERSoRKNS_9CitationsE1009
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3798
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func.html b/coverage/tools/Citations.cpp.func.html new file mode 100644 index 0000000000..c839e2d313 --- /dev/null +++ b/coverage/tools/Citations.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3798
_ZN4PLMD9Citations5clearEv358
_ZN4PLMDlsERSoRKNS_9CitationsE1009
_ZNK4PLMD9Citations5emptyEv318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.gcov.html b/coverage/tools/Citations.cpp.gcov.html new file mode 100644 index 0000000000..5627ccea13 --- /dev/null +++ b/coverage/tools/Citations.cpp.gcov.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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        3798 : std::string Citations::cite(const std::string & item) {
+      30             :   unsigned i;
+      31       10462 :   for(i=0; i<items.size(); ++i) if(items[i]==item) break;
+      32        3798 :   if(i==items.size()) items.push_back(item);
+      33        3798 :   plumed_assert(i<items.size());
+      34             :   std::string ret;
+      35        3798 :   Tools::convert(i+1,ret);
+      36        7596 :   ret="["+ret+"]";
+      37        3798 :   return ret;
+      38             : }
+      39             : 
+      40        1009 : std::ostream & operator<<(std::ostream &log,const Citations&cit) {
+      41        4135 :   for(unsigned i=0; i<cit.items.size(); ++i)
+      42        6252 :     log<<"  ["<<i+1<<"] "<<cit.items[i]<<"\n";
+      43        1009 :   return log;
+      44             : }
+      45             : 
+      46         358 : void Citations::clear() {
+      47         358 :   items.clear();
+      48         358 : }
+      49             : 
+      50         318 : bool Citations::empty()const {
+      51         318 :   return items.empty();
+      52             : }
+      53             : 
+      54             : }
+      55             : 
+      56             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func-sort-c.html b/coverage/tools/Citations.h.func-sort-c.html new file mode 100644 index 0000000000..831105381e --- /dev/null +++ b/coverage/tools/Citations.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func.html b/coverage/tools/Citations.h.func.html new file mode 100644 index 0000000000..8bf4318b98 --- /dev/null +++ b/coverage/tools/Citations.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.gcov.html b/coverage/tools/Citations.h.gcov.html new file mode 100644 index 0000000000..e30b94988a --- /dev/null +++ b/coverage/tools/Citations.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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      805268 : class Citations {
+      55             :   std::vector<std::string> items;
+      56             : public:
+      57             : /// Add a citation.
+      58             : /// It returns a string containing the reference number, something like "[10]"
+      59             :   std::string cite(const std::string &);
+      60             : /// Dumps the bibliography.
+      61             : /// It writes on the ostream the list of all the bibliographic items
+      62             : /// prefixed with their reference number
+      63             :   friend std::ostream &operator<<(std::ostream &,const Citations&);
+      64             : /// Delete all references
+      65             :   void clear();
+      66             : /// Check if bibliography is empty
+      67             :   bool empty()const;
+      68             : };
+      69             : 
+      70             : std::ostream & operator<<(std::ostream &,const Citations&);
+      71             : 
+      72             : }
+      73             : 
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func-sort-c.html b/coverage/tools/Communicator.cpp.func-sort-c.html new file mode 100644 index 0000000000..c25db04af7 --- /dev/null +++ b/coverage/tools/Communicator.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-05-27 13:05:14Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatoraSERKS0_0
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1199
_ZN4PLMD12Communicator8Get_commEv1674
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2172
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7589
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14902
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15302
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15302
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43101
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv59667
_ZN4PLMD12CommunicatorD0Ev1615161
_ZN4PLMD12CommunicatorC2Ev2422194
_ZN4PLMD12CommunicatorD2Ev2422194
_ZNK4PLMD12Communicator8Get_sizeEv2584342
_ZN4PLMD12Communicator3SumENS0_4DataE4283901
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4558765
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4603489
_ZNK4PLMD12Communicator7BarrierEv4608892
_ZN4PLMD12Communicator5BcastENS0_4DataEi4893290
_ZNK4PLMD12Communicator8Get_rankEv6784151
_ZN4PLMD12Communicator11initializedEv25663221
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func.html b/coverage/tools/Communicator.cpp.func.html new file mode 100644 index 0000000000..002f35c61a --- /dev/null +++ b/coverage/tools/Communicator.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-05-27 13:05:14Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv24
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4558765
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv59667
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43101
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4603489
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator11initializedEv25663221
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator3SumENS0_4DataE4283901
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15302
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator5BcastENS0_4DataEi4893290
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15302
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14902
_ZN4PLMD12Communicator8Get_commEv1674
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2172
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1199
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatorC2Ev2422194
_ZN4PLMD12CommunicatorD0Ev1615161
_ZN4PLMD12CommunicatorD2Ev2422194
_ZN4PLMD12CommunicatoraSERKS0_0
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7589
_ZNK4PLMD12Communicator7BarrierEv4608892
_ZNK4PLMD12Communicator8Get_rankEv6784151
_ZNK4PLMD12Communicator8Get_sizeEv2584342
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.gcov.html b/coverage/tools/Communicator.cpp.gcov.html new file mode 100644 index 0000000000..179e96a778 --- /dev/null +++ b/coverage/tools/Communicator.cpp.gcov.html @@ -0,0 +1,394 @@ + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-05-27 13:05:14Functions:303683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Communicator.h"
+      23             : #include "Exception.h"
+      24             : #include "AtomNumber.h"
+      25             : #include <cstdlib>
+      26             : #include <cstring>
+      27             : #include <cstdio>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31          54 : bool Communicator::plumedHasMPI() {
+      32             : #ifdef __PLUMED_HAS_MPI
+      33          54 :   return true;
+      34             : #else
+      35             :   return false;
+      36             : #endif
+      37             : }
+      38             : 
+      39     2422194 : Communicator::Communicator()
+      40             : #ifdef __PLUMED_HAS_MPI
+      41     2422194 :   : communicator(MPI_COMM_SELF)
+      42             : #endif
+      43             : {
+      44     2422194 : }
+      45             : 
+      46           0 : Communicator::Communicator(const Communicator&pc) {
+      47           0 :   Set_comm(pc.communicator);
+      48           0 : }
+      49             : 
+      50             : Communicator::Status Communicator::StatusIgnore;
+      51             : 
+      52           0 : Communicator& Communicator::operator=(const Communicator&pc) {
+      53           0 :   if (this != &pc) {
+      54           0 :     Set_comm(pc.communicator);
+      55             :   }
+      56           0 :   return *this;
+      57             : }
+      58             : 
+      59     6784151 : int Communicator::Get_rank()const {
+      60     6784151 :   int r=0;
+      61             : #ifdef __PLUMED_HAS_MPI
+      62     6784151 :   if(initialized()) MPI_Comm_rank(communicator,&r);
+      63             : #endif
+      64     6784151 :   return r;
+      65             : }
+      66             : 
+      67     2584342 : int Communicator::Get_size()const {
+      68     2584342 :   int s=1;
+      69             : #ifdef __PLUMED_HAS_MPI
+      70     2584342 :   if(initialized()) MPI_Comm_size(communicator,&s);
+      71             : #endif
+      72     2584342 :   return s;
+      73             : }
+      74             : 
+      75        2172 : void Communicator::Set_comm(MPI_Comm c) {
+      76             : #ifdef __PLUMED_HAS_MPI
+      77        2172 :   if(initialized()) {
+      78        1673 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      79        1673 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
+      80             :   }
+      81             : #else
+      82             :   (void) c;
+      83             : #endif
+      84        2172 : }
+      85             : 
+      86     4037355 : Communicator::~Communicator() {
+      87             : #ifdef __PLUMED_HAS_MPI
+      88     2422194 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      89             : #endif
+      90     4037355 : }
+      91             : 
+      92        1199 : void Communicator::Set_comm(const TypesafePtr & val) {
+      93             : #ifdef __PLUMED_HAS_MPI
+      94        1199 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      95        2398 :   if(val) Set_comm(*(const MPI_Comm*)val.get<const void*>());
+      96             : #else
+      97             :   (void) val;
+      98             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+      99             : #endif
+     100        1199 : }
+     101             : 
+     102           0 : void Communicator::Set_fcomm(const TypesafePtr & val) {
+     103             : #ifdef __PLUMED_HAS_MPI
+     104           0 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     105           0 :   if(val) {
+     106           0 :     MPI_Comm comm=MPI_Comm_f2c(*(const MPI_Fint*)val.get<const void*>());
+     107           0 :     Set_comm(comm);
+     108             :   }
+     109             : #else
+     110             :   (void) val;
+     111             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     112             : #endif
+     113           0 : }
+     114             : 
+     115           0 : void Communicator::Abort(int errorcode) {
+     116             : #ifdef __PLUMED_HAS_MPI
+     117           0 :   if(initialized()) {
+     118           0 :     MPI_Abort(communicator,errorcode);
+     119             :   }
+     120             : #endif
+     121           0 :   std::fprintf(stderr,"aborting with error code %d\n",errorcode);
+     122           0 :   std::abort();
+     123             : }
+     124             : 
+     125     4893290 : void Communicator::Bcast(Data data,int root) {
+     126             : #if defined(__PLUMED_HAS_MPI)
+     127     4893290 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
+     128             : #else
+     129             :   (void) data;
+     130             :   (void) root;
+     131             : #endif
+     132     4893290 : }
+     133             : 
+     134     4283901 : void Communicator::Sum(Data data) {
+     135             : #if defined(__PLUMED_HAS_MPI)
+     136     4283901 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
+     137             : #else
+     138             :   (void) data;
+     139             : #endif
+     140     4283901 : }
+     141             : 
+     142           3 : void Communicator::Prod(Data data) {
+     143             : #if defined(__PLUMED_HAS_MPI)
+     144           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_PROD,communicator);
+     145             : #else
+     146             :   (void) data;
+     147             : #endif
+     148           3 : }
+     149             : 
+     150         155 : void Communicator::Max(Data data) {
+     151             : #if defined(__PLUMED_HAS_MPI)
+     152         155 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MAX,communicator);
+     153             : #else
+     154             :   (void) data;
+     155             : #endif
+     156         155 : }
+     157             : 
+     158           3 : void Communicator::Min(Data data) {
+     159             : #if defined(__PLUMED_HAS_MPI)
+     160           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MIN,communicator);
+     161             : #else
+     162             :   (void) data;
+     163             : #endif
+     164           3 : }
+     165             : 
+     166       15302 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
+     167             :   Request req;
+     168             : #ifdef __PLUMED_HAS_MPI
+     169       15302 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     170       15302 :   void*s=const_cast<void*>((const void*)data.pointer);
+     171       15302 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
+     172             : #else
+     173             :   (void) data;
+     174             :   (void) source;
+     175             :   (void) tag;
+     176             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     177             : #endif
+     178       15302 :   return req;
+     179             : }
+     180             : 
+     181       19063 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
+     182       19063 :   void*s=const_cast<void*>((const void*)in.pointer);
+     183       19063 :   void*r=const_cast<void*>((const void*)out.pointer);
+     184             :   int*rc=const_cast<int*>(recvcounts);
+     185             :   int*di=const_cast<int*>(displs);
+     186             : #if defined(__PLUMED_HAS_MPI)
+     187       19063 :   if(initialized()) {
+     188       19062 :     if(s==NULL)s=MPI_IN_PLACE;
+     189       19062 :     MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
+     190             :   } else {
+     191           1 :     plumed_assert(in.nbytes==out.nbytes);
+     192           1 :     plumed_assert(in.size==out.size);
+     193           1 :     plumed_assert(rc);
+     194           1 :     plumed_assert(rc[0]==in.size);
+     195           1 :     plumed_assert(di);
+     196           1 :     if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     197             :   }
+     198             : #else
+     199             :   plumed_assert(in.nbytes==out.nbytes);
+     200             :   plumed_assert(in.size==out.size);
+     201             :   plumed_assert(rc);
+     202             :   plumed_assert(rc[0]==in.size);
+     203             :   plumed_assert(di);
+     204             :   if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     205             : #endif
+     206       19063 : }
+     207             : 
+     208        5838 : void Communicator::Allgather(ConstData in,Data out) {
+     209        5838 :   void*s=const_cast<void*>((const void*)in.pointer);
+     210        5838 :   void*r=const_cast<void*>((const void*)out.pointer);
+     211             : #if defined(__PLUMED_HAS_MPI)
+     212        5838 :   if(initialized()) {
+     213        5837 :     if(s==NULL)s=MPI_IN_PLACE;
+     214        5837 :     MPI_Allgather(s,in.size,in.type,r,out.size/Get_size(),out.type,communicator);
+     215             :   } else {
+     216           1 :     plumed_assert(in.nbytes==out.nbytes);
+     217           1 :     plumed_assert(in.size==out.size);
+     218           1 :     if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     219             :   }
+     220             : #else
+     221             :   plumed_assert(in.nbytes==out.nbytes);
+     222             :   plumed_assert(in.size==out.size);
+     223             :   if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     224             : #endif
+     225        5838 : }
+     226             : 
+     227       15302 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
+     228             : #ifdef __PLUMED_HAS_MPI
+     229       15302 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     230       15302 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
+     231        7589 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
+     232             : #else
+     233             :   (void) data;
+     234             :   (void) source;
+     235             :   (void) tag;
+     236             :   (void) status;
+     237             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     238             : #endif
+     239       15302 : }
+     240             : 
+     241     4608892 : void Communicator::Barrier()const {
+     242             : #ifdef __PLUMED_HAS_MPI
+     243     4608892 :   if(initialized()) MPI_Barrier(communicator);
+     244             : #endif
+     245     4608892 : }
+     246             : 
+     247        1674 : MPI_Comm & Communicator::Get_comm() {
+     248        1674 :   return communicator;
+     249             : }
+     250             : 
+     251    25663221 : bool Communicator::initialized() {
+     252             : #if defined(__PLUMED_HAS_MPI)
+     253    25663221 :   int flag=0;
+     254    25663221 :   MPI_Initialized(&flag);
+     255    25663221 :   if(flag) return true;
+     256    16411613 :   else return false;
+     257             : #endif
+     258             :   return false;
+     259             : }
+     260             : 
+     261       14902 : void Communicator::Request::wait(Status&s) {
+     262             : #ifdef __PLUMED_HAS_MPI
+     263       14902 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     264       14902 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
+     265           1 :   else MPI_Wait(&r,&s.s);
+     266             : #else
+     267             :   (void) s;
+     268             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     269             : #endif
+     270       14902 : }
+     271             : 
+     272             : #ifdef __PLUMED_HAS_MPI
+     273           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
+     274     4558765 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
+     275       59667 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
+     276         295 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
+     277       43101 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
+     278          24 : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_UNSIGNED;}
+     279     4603489 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
+     280           6 : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_UNSIGNED_LONG_LONG;}
+     281           0 : template<> MPI_Datatype Communicator::getMPIType<long double>()   { return MPI_LONG_DOUBLE;}
+     282             : #else
+     283             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
+     284             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
+     285             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
+     286             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
+     287             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
+     288             : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_Datatype();}
+     289             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
+     290             : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_Datatype();}
+     291             : template<> MPI_Datatype Communicator::getMPIType<long double>() { return MPI_Datatype();}
+     292             : #endif
+     293             : 
+     294         406 : void Communicator::Split(int color,int key,Communicator&pc)const {
+     295             : #ifdef __PLUMED_HAS_MPI
+     296         406 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
+     297             : #else
+     298             :   (void) color;
+     299             :   (void) key;
+     300             :   (void) pc;
+     301             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     302             : #endif
+     303         406 : }
+     304             : 
+     305        7589 : int Communicator::Status::Get_count(MPI_Datatype type)const {
+     306             :   int i;
+     307             : #ifdef __PLUMED_HAS_MPI
+     308        7589 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     309        7589 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
+     310             : #else
+     311             :   i=0;
+     312             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     313             : #endif
+     314        7589 :   return i;
+     315             : }
+     316             : 
+     317             : }
+     318             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func-sort-c.html b/coverage/tools/Communicator.h.func-sort-c.html new file mode 100644 index 0000000000..c78cf8e407 --- /dev/null +++ b/coverage/tools/Communicator.h.func-sort-c.html @@ -0,0 +1,320 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_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
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator3SumIjEEvPT_i545
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_580
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator3SumIjEEvRT_1082
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3490
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3836
_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_i15333
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_19986
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i21735
_ZN4PLMD12Communicator3SumIdEEvPT_i68264
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i250957
_ZN4PLMD12Communicator3SumIdEEvRT_2033708
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2125775
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2382091
_ZN4PLMD12Communicator5BcastImEEvRT_i4603489
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func.html b/coverage/tools/Communicator.h.func.html new file mode 100644 index 0000000000..3707b1583b --- /dev/null +++ b/coverage/tools/Communicator.h.func.html @@ -0,0 +1,320 @@ + + + + + + + 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-05-27 13:05: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_2125775
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_150
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3490
_ZN4PLMD12Communicator3SumIdEEvPT_i68264
_ZN4PLMD12Communicator3SumIdEEvRT_2033708
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator3SumIjEEvPT_i545
_ZN4PLMD12Communicator3SumIjEEvRT_1082
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE24
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator4DataC2IdEERNS_6MatrixIT_EE17
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2382091
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3836
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7588
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i21735
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i24
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i250957
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastIiEEvRT_i15333
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastImEEvRT_i4603489
_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
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.gcov.html b/coverage/tools/Communicator.h.gcov.html new file mode 100644 index 0000000000..ce8f83adc6 --- /dev/null +++ b/coverage/tools/Communicator.h.gcov.html @@ -0,0 +1,328 @@ + + + + + + + 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-05-27 13:05: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     2623992 :     template <typename T> Data(T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      73             : /// Init from reference
+      74    13309910 :     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       83442 :     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     2398011 :     template <typename T> explicit Data(std::vector<T>&v) {
+      85     2398182 :       Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+      86     2398011 :     }
+      87             : /// Init from reference to PLMD::Matrix
+      88          17 :     template <typename T> explicit Data(Matrix<T>&m ) {
+      89          17 :       if(m.nrows()*m.ncols()>0) { Data d(&m(0,0),m.nrows()*m.ncols()); pointer=d.pointer; size=d.size; type=d.type; }
+      90           0 :       else { pointer=NULL; size=0; }
+      91          17 :     }
+      92             : /// Init from reference to std::string
+      93          61 :     explicit Data(std::string&s) {
+      94          61 :       if(s.size()>0) { Data d(&s[0],s.size()); pointer=d.pointer; size=d.size; type=d.type; }
+      95           0 :       else { pointer=NULL; size=0; }
+      96          61 :     }
+      97             :   };
+      98             : /// Const version of Communicator::Data
+      99             : /// See Communicator::Data documentation
+     100             :   struct ConstData {
+     101             :     const void*pointer;
+     102             :     int size;
+     103             :     int nbytes=0;
+     104             :     MPI_Datatype type;
+     105       19900 :     template <typename T> explicit ConstData(const T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+     106        5164 :     template <typename T> explicit ConstData(const T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+     107             :     template <unsigned n> explicit ConstData(const VectorGeneric<n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     108             :     template <unsigned n> explicit ConstData(const VectorGeneric<n> &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     109             :     template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     110             :     template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     111         732 :     template <typename T> explicit ConstData(const std::vector<T>&v) {
+     112         732 :       ConstData d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+     113         732 :     }
+     114             :     template <typename T> explicit ConstData(const Matrix<T>&m ) {
+     115             :       if(m.nrows()*m.ncols()>0) { ConstData d(&m(0,0),m.nrows()*m.ncols()); pointer=d.pointer; size=d.size; type=d.type; }
+     116             :       else { pointer=NULL; size=0; }
+     117             :     }
+     118          57 :     explicit ConstData(const std::string&s) {
+     119          57 :       if(s.size()>0) { ConstData d(&s[0],s.size()); pointer=d.pointer; size=d.size; type=d.type; }
+     120           0 :       else { pointer=NULL; size=0; }
+     121          57 :     }
+     122             :   };
+     123             : public:
+     124             :   ///Runtime acces to the __PLUMED_HAS_MPI definition
+     125             :   static bool plumedHasMPI();
+     126             : 
+     127             : /// Wrapper class for MPI_Status
+     128             :   class Status {
+     129             :     int Get_count(MPI_Datatype)const;
+     130             :   public:
+     131             :     MPI_Status s;
+     132             :     template <class T>
+     133        7588 :     int Get_count()const {return Get_count(getMPIType<T>());}
+     134             :   };
+     135             : /// Special status used when status should be ignored.
+     136             : /// E.g. `Recv(a,0,1,Communicator::StatusIgnore);`
+     137             : /// Notice that this is the default for Recv, so this is equivalent to
+     138             : /// `Recv(a,0,1);`
+     139             :   static Status StatusIgnore;
+     140             : /// Wrapper class for MPI_Request
+     141             :   class Request {
+     142             :   public:
+     143             :     MPI_Request r;
+     144             :     void wait(Status&s=StatusIgnore);
+     145             :   };
+     146             : /// Default constructor
+     147             :   Communicator();
+     148             : /// Copy constructor.
+     149             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     150             :   Communicator(const Communicator&);
+     151             : /// Assignment operator.
+     152             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     153             :   Communicator& operator=(const Communicator&);
+     154             : /// Destructor
+     155             :   virtual ~Communicator();
+     156             : /// Obtain the rank of the present process
+     157             :   int Get_rank()const;
+     158             : /// Obtain the number of processes
+     159             :   int Get_size()const;
+     160             : /// Set from a real MPI communicator.
+     161             : /// \param comm MPI communicator
+     162             :   void Set_comm(MPI_Comm comm);
+     163             : /// Reference to MPI communicator
+     164             :   MPI_Comm & Get_comm();
+     165             : /// Set from a pointer to a real MPI communicator (C).
+     166             : /// \param comm Pointer to a C MPI communicator
+     167             :   void Set_comm(const TypesafePtr & comm);
+     168             : /// Set from a pointer to a real MPI communicator (FORTRAN).
+     169             : /// \param comm Pointer to a FORTRAN MPI communicator (INTEGER)
+     170             :   void Set_fcomm(const TypesafePtr & comm);
+     171             : /// Wrapper to MPI_Abort.
+     172             : /// \param code Error code
+     173             :   void Abort(int code);
+     174             : /// Wrapper to MPI_Barrier
+     175             :   void Barrier()const;
+     176             : /// Tests if MPI library is initialized
+     177             :   static bool initialized();
+     178             : /// Wrapper for MPI_Allreduce with MPI_SUM (data struct)
+     179             :   void Sum(Data);
+     180             : /// Wrapper for MPI_Allreduce with MPI_SUM (pointer)
+     181       88290 :   template <class T> void Sum(T*buf,int count) {Sum(Data(buf,count));}
+     182             : /// Wrapper for MPI_Allreduce with MPI_SUM (reference)
+     183     4195607 :   template <class T> void Sum(T&buf) {Sum(Data(buf));}
+     184             : /// Wrapper for MPI_Allreduce with MPI_PROD (data struct)
+     185             :   void Prod(Data);
+     186             : /// Wrapper for MPI_Allreduce with MPI_PROD (pointer)
+     187             :   template <class T> void Prod(T*buf,int count) {Prod(Data(buf,count));}
+     188             : /// Wrapper for MPI_Allreduce with MPI_PROD (reference)
+     189             :   template <class T> void Prod(T&buf) {Prod(Data(buf));}
+     190             : /// Wrapper for MPI_Allreduce with MPI_MAX (data struct)
+     191             :   void Max(Data);
+     192             : /// Wrapper for MPI_Allreduce with MPI_MAX (pointer)
+     193             :   template <class T> void Max(T*buf,int count) {Max(Data(buf,count));}
+     194             : /// Wrapper for MPI_Allreduce with MPI_MAX (reference)
+     195         152 :   template <class T> void Max(T&buf) {Max(Data(buf));}
+     196             : /// Wrapper for MPI_Allreduce with MPI_MIN (data struct)
+     197             :   void Min(Data);
+     198             : /// Wrapper for MPI_Allreduce with MPI_MIN (pointer)
+     199             :   template <class T> void Min(T*buf,int count) {Min(Data(buf,count));}
+     200             : /// Wrapper for MPI_Allreduce with MPI_MIN (reference)
+     201           0 :   template <class T> void Min(T&buf) {Min(Data(buf));}
+     202             : 
+     203             : /// Wrapper for MPI_Bcast (data struct)
+     204             :   void Bcast(Data,int);
+     205             : /// Wrapper for MPI_Bcast (pointer)
+     206             :   template <class T> void Bcast(T*buf,int count,int root) {Bcast(Data(buf,count),root);}
+     207             : /// Wrapper for MPI_Bcast (reference)
+     208     4893281 :   template <class T> void Bcast(T&buf,int root) {Bcast(Data(buf),root);}
+     209             : 
+     210             : /// Wrapper for MPI_Isend (data struct)
+     211             :   Request Isend(ConstData,int,int);
+     212             : /// Wrapper for MPI_Isend (pointer)
+     213       15176 :   template <class T> Request Isend(const T*buf,int count,int source,int tag) {return Isend(ConstData(buf,count),source,tag);}
+     214             : /// Wrapper for MPI_Isend (reference)
+     215         114 :   template <class T> Request Isend(const T&buf,int source,int tag) {return Isend(ConstData(buf),source,tag);}
+     216             : 
+     217             : /// Wrapper for MPI_Allgatherv (data struct)
+     218             :   void Allgatherv(ConstData in,Data out,const int*,const int*);
+     219             : /// Wrapper for MPI_Allgatherv (pointer)
+     220       18907 :   template <class T,class S> void Allgatherv(const T*sendbuf,int sendcount,S*recvbuf,const int*recvcounts,const int*displs) {
+     221       18907 :     Allgatherv(ConstData(sendbuf,sendcount),Data(recvbuf,0),recvcounts,displs);
+     222       18907 :   }
+     223             : /// Wrapper for MPI_Allgatherv (reference)
+     224         152 :   template <class T,class S> void Allgatherv(const T&sendbuf,S&recvbuf,const int*recvcounts,const int*displs) {
+     225         152 :     Allgatherv(ConstData(sendbuf),Data(recvbuf),recvcounts,displs);
+     226         152 :   }
+     227             : 
+     228             : /// Wrapper for MPI_Allgather (data struct)
+     229             :   void Allgather(ConstData in,Data out);
+     230             : /// Wrapper for MPI_Allgatherv (pointer)
+     231         204 :   template <class T,class S> void Allgather(const T*sendbuf,int sendcount,S*recvbuf,int recvcount) {
+     232         408 :     Allgather(ConstData(sendbuf,sendcount),Data(recvbuf,recvcount*Get_size()));
+     233         204 :   }
+     234             : /// Wrapper for MPI_Allgatherv (reference)
+     235        5630 :   template <class T,class S> void Allgather(const T&sendbuf,S&recvbuf) {
+     236       10680 :     Allgather(ConstData(sendbuf),Data(recvbuf));
+     237        5630 :   }
+     238             : 
+     239             : /// Wrapper for MPI_Recv (data struct)
+     240             :   void Recv(Data,int,int,Status&s=StatusIgnore);
+     241             : /// Wrapper for MPI_Recv (pointer)
+     242       15176 :   template <class T> void Recv(T*buf,int count,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf,count),source,tag,s);}
+     243             : /// Wrapper for MPI_Recv (reference)
+     244         114 :   template <class T> void Recv(T&buf,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf),source,tag,s);}
+     245             : 
+     246             : /// Wrapper to MPI_Comm_split
+     247             :   void Split(int,int,Communicator&)const;
+     248             : };
+     249             : 
+     250             : }
+     251             : 
+     252             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func-sort-c.html b/coverage/tools/ConjugateGradient.h.func-sort-c.html new file mode 100644 index 0000000000..d1ea2814ee --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func.html b/coverage/tools/ConjugateGradient.h.func.html new file mode 100644 index 0000000000..ac77dc8989 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.gcov.html b/coverage/tools/ConjugateGradient.h.gcov.html new file mode 100644 index 0000000000..2cd0953f5b --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func-sort-c.html b/coverage/tools/DLLoader.cpp.func-sort-c.html new file mode 100644 index 0000000000..7183eface6 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8DLLoader9installedEv2
_ZN4PLMD8DLLoaderC2Ev809485
_ZN4PLMD8DLLoaderD2Ev809485
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func.html b/coverage/tools/DLLoader.cpp.func.html new file mode 100644 index 0000000000..ae633c4feb --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader9installedEv2
_ZN4PLMD8DLLoaderC2Ev809485
_ZN4PLMD8DLLoaderD2Ev809485
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.gcov.html b/coverage/tools/DLLoader.cpp.gcov.html new file mode 100644 index 0000000000..84ba5e9c25 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + 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-05-27 13:05: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      809485 : DLLoader::~DLLoader() {
+      60      809485 :   auto debug=std::getenv("PLUMED_LOAD_DEBUG");
+      61             : #ifdef __PLUMED_HAS_DLOPEN
+      62      809485 :   if(debug) std::fprintf(stderr,"delete dlloader\n");
+      63      809486 :   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      809485 :   if(debug) std::fprintf(stderr,"end delete dlloader\n");
+      71             : #endif
+      72      809485 : }
+      73             : 
+      74      809485 : DLLoader::DLLoader() {
+      75             :   // do nothing
+      76      809485 : }
+      77             : 
+      78             : 
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func-sort-c.html b/coverage/tools/DynamicList.h.func-sort-c.html new file mode 100644 index 0000000000..a197a12e4d --- /dev/null +++ b/coverage/tools/DynamicList.h.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE5clearEv41860
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402101
_ZN4PLMD11DynamicListIjE14completeUpdateEv876595
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv932900
_ZN4PLMD11DynamicListIjE13deactivateAllEv2099234
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4878695
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54365506
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77411726
_ZNK4PLMD11DynamicListIjE8isActiveERKj424180368
_ZN4PLMD11DynamicListIjE8activateEj1544110399
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func.html b/coverage/tools/DynamicList.h.func.html new file mode 100644 index 0000000000..216145e8e7 --- /dev/null +++ b/coverage/tools/DynamicList.h.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE13deactivateAllEv2099234
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE14completeUpdateEv876595
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv932900
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77411726
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402101
_ZN4PLMD11DynamicListIjE5clearEv41860
_ZN4PLMD11DynamicListIjE8activateEj1544110399
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4878695
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54365506
_ZNK4PLMD11DynamicListIjE8isActiveERKj424180368
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.gcov.html b/coverage/tools/DynamicList.h.gcov.html new file mode 100644 index 0000000000..60335dc07e --- /dev/null +++ b/coverage/tools/DynamicList.h.gcov.html @@ -0,0 +1,455 @@ + + + + + + + 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-05-27 13:05: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      360242 :   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   642999946 :     return all[ active[i] ];
+     161             :   }
+     162             : /// An operator that returns the element from the full list (used in neighbour lists)
+     163             :   inline T operator () (const unsigned& i) const {
+     164             :     plumed_dbg_assert( i<all.size() );
+     165             :     return all[i];
+     166             :   }
+     167             : /// Clear the list
+     168             :   void clear();
+     169             : /// Return the total number of elements in the list
+     170             :   unsigned fullSize() const;
+     171             : /// Return the number of elements that are currently active
+     172             :   unsigned getNumberActive() const;
+     173             : /// Find out if a member is active
+     174             :   bool isActive(const unsigned& ) const;
+     175             : /// Setup MPI communication if things are activated/deactivated on different nodes
+     176             :   void setupMPICommunication( Communicator& comm );
+     177             : /// Add something to the active list
+     178             :   void addIndexToList( const T & ii );
+     179             : /// Create the list from a vector
+     180             :   void createIndexListFromVector( const std::vector<T>& myind );
+     181             : /// Find the index of in the list which has value t
+     182             :   int getIndexOfElement( const T& t ) const ;
+     183             : /// Make a particular element inactive
+     184             :   void deactivate( const T& t );
+     185             : /// Make everything in the list inactive
+     186             :   void deactivateAll();
+     187             : /// Make something active
+     188             :   void activate( const unsigned ii );
+     189             : /// Make everything in the list active
+     190             :   void activateAll();
+     191             : /// Do updateActiveMembers for a loop that has been distributed over multiple nodes
+     192             :   void mpi_gatherActiveMembers(Communicator& comm);
+     193             : /// Get the list of active members
+     194             :   void updateActiveMembers();
+     195             : /// Empty the list of active members
+     196             :   void emptyActiveMembers();
+     197             : /// This can be used for a fast version of updateActiveMembers in which only a subset of the
+     198             : /// indexes are checked
+     199             :   void putIndexInActiveArray( const unsigned& ii );
+     200             : /// This can be called on once update is complete
+     201             :   void completeUpdate();
+     202             : /// This tells one if an update has been completed
+     203             :   bool updateComplete() const ;
+     204             : /// This sorts the elements in the active list
+     205             :   void sortActiveList();
+     206             : /// Retriee the list of active objects
+     207             :   std::vector<T> retrieveActiveList();
+     208             : };
+     209             : 
+     210             : template <typename T>
+     211             : std::vector<T> DynamicList<T>::retrieveActiveList() {
+     212             :   std::vector<T> this_active(nactive);
+     213             :   for(unsigned k=0; k<nactive; ++k) this_active[k]=all[ active[k] ];
+     214             :   return this_active;
+     215             : }
+     216             : 
+     217             : template <typename T>
+     218       41860 : void DynamicList<T>::clear() {
+     219       41860 :   all.resize(0);
+     220       41860 :   onoff.resize(0); active.resize(0);
+     221       41860 : }
+     222             : 
+     223             : template <typename T>
+     224   424180368 : bool DynamicList<T>::isActive( const unsigned& i ) const {
+     225   424180368 :   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    54365506 : unsigned DynamicList<T>::getNumberActive() const {
+     235    54365506 :   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      402101 : void DynamicList<T>::createIndexListFromVector( const std::vector<T>& myind ) {
+     245      402101 :   plumed_dbg_assert( all.size()==0 ); onoff.resize( myind.size(), 0 );
+     246      402101 :   active.resize( myind.size() );
+     247      402101 :   all.insert( all.end(), myind.begin(), myind.end() );
+     248      402101 : }
+     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     2099234 : void DynamicList<T>::deactivateAll() {
+     275     2099234 :   allWereDeactivated=true; allWereActivated=false;
+     276    82076346 :   for(unsigned i=0; i<nactive; ++i) onoff[ active[i] ]= 0;
+     277     2099234 :   nactive=0;
+     278             : #ifndef NDEBUG
+     279             :   for(unsigned i=0; i<onoff.size(); ++i) plumed_dbg_assert( onoff[i]==0 );
+     280             : #endif
+     281     2099234 : }
+     282             : 
+     283             : template <typename T>
+     284  1544110399 : 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  1544110399 :   onoff[ii]=nprocessors;
+     288  1544110399 : }
+     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      932900 : void DynamicList<T>::emptyActiveMembers() {
+     318             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     319      932900 :   nactive=0;
+     320      932900 : }
+     321             : 
+     322             : template <typename T>
+     323    77411726 : 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    77411726 :   active[nactive]=ii; nactive++;
+     327    77411726 : }
+     328             : 
+     329             : template <typename T>
+     330      876595 : void DynamicList<T>::completeUpdate() {
+     331             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     332      876595 :   allWereActivated=allWereDeactivated=false;
+     333      876595 : }
+     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     4878695 : bool DynamicList<T>::updateComplete() const {
+     344     4878695 :   if( !allWereActivated && !allWereDeactivated ) return true;
+     345             :   return false;
+     346             : }
+     347             : 
+     348             : template <typename U>
+     349             : void mpi_gatherActiveMembers(Communicator& comm, std::vector< DynamicList<U> >& ll ) {
+     350             :   // Setup an array to hold all data
+     351             :   unsigned bufsize=0; unsigned size=comm.Get_size();
+     352             :   for(unsigned i=0; i<ll.size(); ++i) {
+     353             :     plumed_dbg_massert( ll[i].nprocessors==size, "missing a call to DynamicList::setupMPICommunication" );
+     354             :     bufsize+=ll[i].onoff.size();
+     355             :   }
+     356             :   std::vector<unsigned> buffer( bufsize );
+     357             :   // Gather all onoff data into a single array
+     358             :   bufsize=0;
+     359             :   for(unsigned i=0; i<ll.size(); ++i) {
+     360             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) { buffer[bufsize]=ll[i].onoff[j]; bufsize++; }
+     361             :   }
+     362             :   // GATHER from all nodes
+     363             :   comm.Sum(&buffer[0],buffer.size());
+     364             :   // distribute back to original lists
+     365             :   bufsize=0;
+     366             :   for(unsigned i=0; i<ll.size(); ++i) {
+     367             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) {
+     368             :       if( buffer[bufsize]>0 && buffer[bufsize]%size==0 ) ll[i].onoff[j]=size;
+     369             :       else ll[i].onoff[j]=size-1;
+     370             :       bufsize++;
+     371             :     }
+     372             :   }
+     373             :   for(unsigned i=0; i<ll.size(); ++i) ll[i].updateActiveMembers();
+     374             : }
+     375             : 
+     376             : }
+     377             : 
+     378             : #endif
+     379             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func-sort-c.html b/coverage/tools/ERMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..90fe725bda --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func.html b/coverage/tools/ERMSD.cpp.func.html new file mode 100644 index 0000000000..0f7347b320 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.gcov.html b/coverage/tools/ERMSD.cpp.gcov.html new file mode 100644 index 0000000000..62a38f127f --- /dev/null +++ b/coverage/tools/ERMSD.cpp.gcov.html @@ -0,0 +1,379 @@ + + + + + + + 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-05-27 13:05: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           4 : }
+      67             : 
+      68     1139266 : bool ERMSD::inPair(unsigned i, unsigned j) {
+      69             : 
+      70     1139266 :   if(pairs.size()==0) return true;
+      71     3982685 :   for(unsigned idx=0; idx<pairs.size(); idx++) {
+      72     3414408 :     if(pairs[idx].first == i && pairs[idx].second == j) return true;
+      73     3413730 :     if(pairs[idx].second == i && pairs[idx].first == j) return true;
+      74             :   }
+      75             :   return false;
+      76             : }
+      77             : 
+      78         226 : void ERMSD::calcMat(const std::vector<Vector> & positions,const Pbc& pbc, std::vector<Vector4d> &mat, std::vector<TensorGeneric<4,3> > &Gderi) {
+      79             : 
+      80             :   std::vector<Vector3d> pos;
+      81         226 :   pos.resize(3*nresidues);
+      82             : 
+      83             :   std::vector<Tensor3d> deri;
+      84         226 :   deri.resize(nresidues*9);
+      85             : 
+      86             :   std::vector<Vector> centers;
+      87         226 :   centers.resize(nresidues);
+      88             : 
+      89             :   unsigned idx_deri = 0;
+      90             : 
+      91         226 :   Tensor da_dxa = (2./3.)*Tensor::identity();
+      92         226 :   Tensor da_dxb = -(1./3.)*Tensor::identity();
+      93         226 :   Tensor da_dxc = -(1./3.)*Tensor::identity();
+      94             : 
+      95         226 :   Tensor db_dxa = -(1./3.)*Tensor::identity();
+      96         226 :   Tensor db_dxb = (2./3.)*Tensor::identity();
+      97         226 :   Tensor db_dxc = -(1./3.)*Tensor::identity();
+      98             : 
+      99             :   // Form factors - should this be somewhere else?
+     100             : 
+     101             :   double w = 1./3.;
+     102         226 :   Vector form_factor = Vector(2.0,2.0,1.0/0.3);
+     103             : 
+     104       16272 :   for(unsigned res_idx=0; res_idx<natoms/3; res_idx++) {
+     105             : 
+     106             : 
+     107       16046 :     const unsigned at_idx = 3*res_idx;
+     108             :     //center
+     109       64184 :     for (unsigned j=0; j<3; j++) {
+     110       48138 :       centers[res_idx] += w*positions[at_idx+j];
+     111             :     }
+     112             : 
+     113       16046 :     Vector3d a = delta(centers[res_idx],positions[at_idx]);
+     114       16046 :     Vector3d b = delta(centers[res_idx],positions[at_idx+1]);
+     115       16046 :     Vector3d d = crossProduct(a,b);
+     116       16046 :     double ianorm = 1./a.modulo();
+     117       16046 :     double idnorm = 1./d.modulo();
+     118             : 
+     119             :     // X vector: COM-C2
+     120       16046 :     pos[at_idx] = a*ianorm;
+     121             :     // Z versor: C2 x (COM-C4/C6)
+     122       16046 :     pos[at_idx+2] = d*idnorm;
+     123             :     // Y versor: Z x Y
+     124       16046 :     pos[at_idx+1] = crossProduct(pos[at_idx+2],pos[at_idx]);
+     125             : 
+     126             :     // Derivatives ////////
+     127       16046 :     Tensor3d t1 = ianorm*(Tensor::identity()-extProduct(pos[at_idx],pos[at_idx]));
+     128             :     // dv1/dxa
+     129       16046 :     deri[idx_deri] = (2./3. )*t1;
+     130             :     // dv1/dxb
+     131       16046 :     deri[idx_deri+3] = -(1./3.)*t1;
+     132             :     // dv1/dxc
+     133       16046 :     deri[idx_deri+6] = -(1./3.)*t1;
+     134             : 
+     135       16046 :     Tensor dd_dxa =  VcrossTensor(a,db_dxa) -VcrossTensor(b,da_dxa);
+     136       16046 :     Tensor dd_dxb =  VcrossTensor(a,db_dxb)-VcrossTensor(b,da_dxb);
+     137       16046 :     Tensor dd_dxc =  VcrossTensor(a,db_dxc)-VcrossTensor(b,da_dxc);
+     138             : 
+     139             :     // dv3/dxa
+     140       16046 :     deri[idx_deri+2] = deriNorm(d,dd_dxa);
+     141             :     // dv3/dxb
+     142       16046 :     deri[idx_deri+5] = deriNorm(d,dd_dxb);
+     143             :     // dv3/dxc
+     144       16046 :     deri[idx_deri+8] = deriNorm(d,dd_dxc);
+     145             : 
+     146             :     // dv2/dxa = dv3/dxa cross v1 + v3 cross dv1/dxa
+     147       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.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func-sort-c.html b/coverage/tools/ERMSD.h.func-sort-c.html new file mode 100644 index 0000000000..2860b28c7f --- /dev/null +++ b/coverage/tools/ERMSD.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func.html b/coverage/tools/ERMSD.h.func.html new file mode 100644 index 0000000000..129d7a26a6 --- /dev/null +++ b/coverage/tools/ERMSD.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.gcov.html b/coverage/tools/ERMSD.h.gcov.html new file mode 100644 index 0000000000..1941b666c6 --- /dev/null +++ b/coverage/tools/ERMSD.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-05-27 13:05: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           0 : class ERMSD {
+      41             :   //std::map< std::pair <unsigned,unsigned> , double> targets;
+      42             :   //unsigned natoms;
+      43             :   std::vector<Vector4d> reference_mat;
+      44             :   std::size_t natoms;
+      45             :   std::size_t nresidues;
+      46             :   std::vector<std::pair <unsigned,unsigned> > pairs;
+      47             :   double cutoff;
+      48             : 
+      49             : public:
+      50             : /// Constructor
+      51           4 :   ERMSD(): natoms(0),nresidues(0), cutoff(0.0) {}
+      52             : 
+      53             : /// clear the structure
+      54             :   void clear();
+      55             : 
+      56             :   bool inPair(unsigned i, unsigned j);
+      57             : 
+      58             : /// set reference coordinates
+      59             :   void setReference(const std::vector<Vector> & reference, const std::vector<unsigned> & pairs_vec,double mycutoff=0.24);
+      60             : 
+      61             :   void calcMat(const std::vector<Vector> & positions, const Pbc& pbc,std::vector<Vector4d> &mat,std::vector<TensorGeneric<4,3> > & Gderivatives);
+      62             : 
+      63             : /// Compute ermsd ( no pbc )
+      64             : //  double calculate(const std::vector<Vector> & positions,
+      65             : //                   std::vector<Vector> &derivatives, Tensor& virial) const ;
+      66             : /// Compute ermsd ( with pbc )
+      67             :   double calculate(const std::vector<Vector>& positions, const Pbc& pbc,std::vector<Vector> &derivatives, Tensor& virial);
+      68             : };
+      69             : 
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func-sort-c.html b/coverage/tools/Exception.cpp.func-sort-c.html new file mode 100644 index 0000000000..1d4e770214 --- /dev/null +++ b/coverage/tools/Exception.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Exception5stackEv3
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE11
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE56
_ZN4PLMD9ExceptionlsERKNS0_8LocationE56
_ZN4PLMD9ExceptionC2Ev95
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE130
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func.html b/coverage/tools/Exception.cpp.func.html new file mode 100644 index 0000000000..4ffcf7fd03 --- /dev/null +++ b/coverage/tools/Exception.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE56
_ZN4PLMD9ExceptionC2Ev95
_ZN4PLMD9ExceptionlsERKNS0_8LocationE56
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE11
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE130
_ZNK4PLMD9Exception5stackEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.gcov.html b/coverage/tools/Exception.cpp.gcov.html new file mode 100644 index 0000000000..769c82194e --- /dev/null +++ b/coverage/tools/Exception.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-05-27 13:05:14Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Exception.h"
+      23             : 
+      24             : #if defined(__PLUMED_HAS_EXECINFO)
+      25             : #include <execinfo.h>
+      26             : #endif
+      27             : 
+      28             : #include <cstdio>
+      29             : #include <cstring>
+      30             : #include <cstdlib>
+      31             : #include <vector>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : namespace {
+      36             : // see https://www.geeksforgeeks.org/simplify-directory-path-unix-like/
+      37             : 
+      38             : // function to simplify a Unix - styled
+      39             : // absolute path
+      40          56 : std::string simplify(const std::string & path)
+      41             : {
+      42             :   // using vector in place of stack
+      43             :   std::vector<std::string> v;
+      44          56 :   int n = path.length();
+      45             :   std::string ans;
+      46         186 :   for (int i = 0; i < n; i++) {
+      47         130 :     std::string dir = "";
+      48             :     // forming the current directory.
+      49        1095 :     while (i < n && path[i] != '/') {
+      50         965 :       dir += path[i];
+      51         965 :       i++;
+      52             :     }
+      53             : 
+      54             :     // if ".." , we pop.
+      55         130 :     if (dir == "..") {
+      56           6 :       if (!v.empty())
+      57             :         v.pop_back();
+      58             :     }
+      59         248 :     else if (dir == "." || dir == "") {
+      60             :       // do nothing (added for better understanding.)
+      61             :     }
+      62             :     else {
+      63             :       // push the current directory into the vector.
+      64         123 :       v.push_back(dir);
+      65             :     }
+      66             :   }
+      67             : 
+      68             :   // forming the ans
+      69             :   bool first=true;
+      70         173 :   for (auto i : v) {
+      71         117 :     if(!first) ans += "/";
+      72             :     first=false;
+      73             :     ans += i;
+      74             :   }
+      75             : 
+      76             :   // vector is empty
+      77          56 :   if (ans == "")
+      78           0 :     return "/";
+      79             : 
+      80             :   return ans;
+      81          56 : }
+      82             : 
+      83             : }
+      84             : 
+      85          95 : Exception::Exception()
+      86             : {
+      87             :   callstack.fill(nullptr);
+      88             : #ifdef __PLUMED_HAS_EXECINFO
+      89          95 :   callstack_n = backtrace(&callstack[0], callstack.size()-1);
+      90          95 :   const char* env=std::getenv("PLUMED_STACK_TRACE");
+      91          95 :   if(env && !std::strcmp(env,"yes")) {
+      92             :     msg+="\n\n********** STACK DUMP **********\n";
+      93           3 :     msg+=stack();
+      94             :     msg+="\n********** END STACK DUMP **********\n";
+      95             :   }
+      96             : #endif
+      97          95 : }
+      98             : 
+      99         130 : Exception& Exception::operator<<(const std::string&msg)
+     100             : {
+     101         130 :   if(msg.length()>0) {
+     102         130 :     if(note) this->msg +="\n";
+     103         130 :     this->msg +=msg;
+     104         130 :     note=false;
+     105             :   }
+     106         130 :   return *this;
+     107             : }
+     108             : 
+     109          56 : Exception& Exception::operator<<(const Location&loc)
+     110             : {
+     111          56 :   if(loc.file) {
+     112             :     const std::size_t clinelen=1000;
+     113             :     char cline[clinelen];
+     114          56 :     std::snprintf(cline,clinelen,"%u",loc.line);
+     115          56 :     this->msg += "\n(";
+     116             :     try {
+     117         112 :       this->msg += simplify(loc.file);
+     118           0 :     } catch(...) {
+     119             :       // ignore
+     120           0 :     }
+     121             :     this->msg += ":";
+     122             :     this->msg += cline;
+     123             :     this->msg += ")";
+     124          56 :     if(loc.pretty && loc.pretty[0]) {
+     125             :       this->msg += " ";
+     126          56 :       this->msg += loc.pretty;
+     127             :     }
+     128             :   }
+     129          56 :   note=true;
+     130          56 :   return *this;
+     131             : }
+     132             : 
+     133          11 : Exception& Exception::operator<<(const Assertion&as)
+     134             : {
+     135          11 :   if(as.assertion) {
+     136          11 :     this->msg += "\n+++ assertion failed: ";
+     137          11 :     this->msg += as.assertion;
+     138             :   }
+     139          11 :   note=true;
+     140          11 :   return *this;
+     141             : }
+     142             : 
+     143           3 : const char* Exception::stack() const {
+     144             : #ifdef __PLUMED_HAS_EXECINFO
+     145           3 :   if(stackTrace.length()==0) {
+     146           3 :     char** strs = backtrace_symbols(&callstack[0], callstack_n);
+     147          30 :     for (int i = 0; i < callstack_n; ++i) {stackTrace+=strs[i]; stackTrace+="\n";}
+     148           3 :     free(strs);
+     149             :   }
+     150             : #endif
+     151           3 :   return stackTrace.c_str();
+     152             : }
+     153             : 
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func-sort-c.html b/coverage/tools/Exception.h.func-sort-c.html new file mode 100644 index 0000000000..ac1c044434 --- /dev/null +++ b/coverage/tools/Exception.h.func-sort-c.html @@ -0,0 +1,612 @@ + + + + + + + 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:303683.3 %
Date:2024-05-27 13:05:14Functions:2313517.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_0
_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
_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
_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
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA27_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA58_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA68_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA83_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA89_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionC2ERKS0_25
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZNK4PLMD9Exception4whatEv37
_ZN4PLMD9ExceptionD2Ev54
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func.html b/coverage/tools/Exception.h.func.html new file mode 100644 index 0000000000..fa69eaed0f --- /dev/null +++ b/coverage/tools/Exception.h.func.html @@ -0,0 +1,612 @@ + + + + + + + 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:303683.3 %
Date:2024-05-27 13:05:14Functions:2313517.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_0
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZN4PLMD9ExceptionC2ERKS0_25
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionD2Ev54
_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_1
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_1
_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_1
_ZN4PLMD9ExceptionlsIA8_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA90_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA91_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA92_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA93_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA94_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_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
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZNK4PLMD9Exception4whatEv37
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.gcov.html b/coverage/tools/Exception.h.gcov.html new file mode 100644 index 0000000000..69a17d2b59 --- /dev/null +++ b/coverage/tools/Exception.h.gcov.html @@ -0,0 +1,478 @@ + + + + + + + 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:303683.3 %
Date:2024-05-27 13:05:14Functions:2313517.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_Exception_h
+      23             : #define __PLUMED_tools_Exception_h
+      24             : 
+      25             : #include <exception>
+      26             : #include <string>
+      27             : #include <stdexcept>
+      28             : #include <sstream>
+      29             : #include <array>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class to deal with Plumed runtime errors.
+      36             : 
+      37             : This class and the related macros can be used to detect programming
+      38             : errors. Typical cases are internal inconsistencies or errors in the plumed<->MD
+      39             : interface. Mistakes made by final users (i.e. in the `plumed.dat` file)
+      40             : should probably be documented in some better way (e.g. printing parts of the manual in the output).
+      41             : However, also this class allows for significant information to be attached.
+      42             : Let's try to make error messages as informative as possible!
+      43             : 
+      44             : \note This class has been rewritten in PLUMED 2.5. It works in a backward compatible manner,
+      45             : but is much more flexible. The main novelty is that we can use insertion operators to
+      46             : add arbitrary messages, as in `plumed_error()<<"check this vector "<<v;`
+      47             : See below for more details.
+      48             : 
+      49             : To throw an error, just throw a c++ exception
+      50             : \verbatim
+      51             :   if(something_bad) throw Exception();
+      52             : \endverbatim
+      53             : or better add an error message to that
+      54             : \verbatim
+      55             :   if(something_bad) throw Exception("describe the error here");
+      56             : \endverbatim
+      57             : 
+      58             : As of PLUMED 2.5 you can add multiple messages, they will just be concatenated,
+      59             : but to do se you should use the insertion operator. Notice that anything that
+      60             : can be formatted with an insertion operator can go to the exception, even a \ref Vector
+      61             : \verbatim
+      62             :   Vector v;
+      63             :   if(something_bad) throw Exception()<<"problem with this "<<v;
+      64             : \endverbatim
+      65             : In principle you can mix the two syntax (add a message as an argument and insert others with `<<`),
+      66             : however it is not very clear and should be avoided.
+      67             : We only allow using arguments in parenthesis in order to keep backward compatibility.
+      68             : 
+      69             : \par Using macros
+      70             : 
+      71             : In order to provide more context, especially for debugging, it might be useful to know where the exception
+      72             : originated from. The macros below add information about the exact location of the error in the file (filename, line
+      73             : and, when available, function name). Macros ending in "error" unconditionally throw
+      74             : the exception, whereas macros ending in "assert" first perform a conditional check
+      75             : (similarly to standard assert()).
+      76             : An extra `m` in the name (e.g. `plumed_merror`) indicates a macro that provides a message as its argument.
+      77             : However, as of PLUMED 2.5 we should prefer adding messages using insertion operators.
+      78             : \verbatim
+      79             : // this is correct but not recommended. add a message please!
+      80             :   plumed_assert(a>0);
+      81             : 
+      82             : // this is the old syntax (with argument).
+      83             : // this syntax is basically available for backward compatibility.
+      84             :   plumed_massert(a>0,"a should be larger than zero);
+      85             : 
+      86             : // this is the recommended syntax, with insertion operators.
+      87             : // it allows to easily insert multiple objects
+      88             :   plumed_assert(a>0)<<"a should be larger than zero. a="<<a;
+      89             : 
+      90             : // same as above, but the test is made explicitly:
+      91             :   if(a<=0) plumed_error();
+      92             :   if(a<=0) plumed_error("a should be larger than zero);
+      93             :   if(a<=0) plumed_error()<<"a should be larger than zero. a="<<a;
+      94             : \endverbatim
+      95             : 
+      96             : The additional macros
+      97             : plumed_dbg_assert() and plumed_dbg_massert() are similar
+      98             : to plumed_assert() and plumed_massert() respectively, but the corresponding
+      99             : check is only performed when NDEBUG macro is not defined. They should
+     100             : be used when the check is expensive and should be skipped in production
+     101             : code. So, for instance, in the following case:
+     102             : \verbatim
+     103             :   plumed_dbg_assert(expensive_function(i)>0)<<"message";
+     104             : \endverbatim
+     105             : `expensive_function()` is not called in the production code.
+     106             : Notice that the compiler should be able to completely optimize away the
+     107             : whole statement including functions used to produce the message as in this example:
+     108             : \verbatim
+     109             :   plumed_dbg_assert(expensive_function(i)>0)<<"I did this check "<<other_expensive_function(i);
+     110             : \endverbatim
+     111             : 
+     112             : Finally, notice that there is another macro available, \ref plumed_here.
+     113             : In can be used in order to create an exception with information about the
+     114             : line/file coordinates without trowing it. That is, the two following syntaxes
+     115             : are equivalent
+     116             : \verbatim
+     117             : // First way, all at once
+     118             : plumed_error()<<"some message";
+     119             : /////////////////////////////////
+     120             : // Second way, one step at a time
+     121             : // Create exception
+     122             : Exception e;
+     123             : // Append information about line and file
+     124             : e<<plumed_here;
+     125             : // Append some other message
+     126             : e<<"some message";
+     127             : // Throw the resulting exception
+     128             : throw e;
+     129             : \endverbatim
+     130             : 
+     131             : Exceptions can be caught within plumed or outside of it.
+     132             : E.g., in an external c++ code using PLUMED as a library, one can type
+     133             : \verbatim
+     134             :   try{
+     135             :     plumed.cmd("setPrecision",n);
+     136             :   } catch (const std::exception & e) {
+     137             :     std::printf("ee %s",e.what());
+     138             :     exit(1);
+     139             :   }
+     140             : \endverbatim
+     141             : This can be useful if an external code wants to exit in a controlled manner
+     142             : (e.g. flushing files, printing the error message in a specific file, etc.)
+     143             : but is anyway limited to c++ codes. Moreover,
+     144             : since these errors are expected to be unrecoverable, the MD code will
+     145             : usually not be able to do something more clever than exiting.
+     146             : 
+     147             : \note
+     148             : We store message and stack trace in growing strings. This is in
+     149             : principle not recommended, since copying the exception might fail if
+     150             : copying the string throw another exception. However, this has been like
+     151             : this in all previous PLUMED versions. In case it is necessary, we can replace
+     152             : it later with a fixed size array placed on the stack.
+     153             : 
+     154             : */
+     155             : class Exception : public std::exception
+     156             : {
+     157             : /// Reported message. Can be updated.
+     158             :   std::string msg;
+     159             : /// Flag to remember if we have to write the `+++ message follows +++` string.
+     160             : /// Needed so that the string appears only at the beginning of the message.
+     161             :   bool note=true;
+     162             : /// Stream used to insert objects.
+     163             : /// It is not copied when the Exception is copied.
+     164             :   std::stringstream stream;
+     165             : /// Stack trace, computed at construction
+     166             :   std::array<void*,128> callstack;
+     167             : /// Number of frames in stack, computed at construction
+     168             :   int callstack_n=0;
+     169             : /// Parsed stack trace. Built at first use, thus mutable.
+     170             :   mutable std::string stackTrace;
+     171             : 
+     172             : public:
+     173             : 
+     174             : /// Auxiliary containing the location of the exception in the file.
+     175             : /// Typically used from the macros below.
+     176             :   class Location {
+     177             :   public:
+     178             :     const char*file;
+     179             :     const unsigned line;
+     180             :     const char* pretty;
+     181          55 :     explicit Location(const char*file,unsigned line,const char* pretty=nullptr):
+     182          55 :       file(file),
+     183          55 :       line(line),
+     184          55 :       pretty(pretty)
+     185             :     {}
+     186             :   };
+     187             : 
+     188             : /// Auxiliary containing the failed assertion.
+     189             : /// Typically used from the macros below.
+     190             :   class Assertion {
+     191             :   public:
+     192             :     const char*assertion;
+     193          10 :     explicit Assertion(const char*assertion=nullptr):
+     194          10 :       assertion(assertion)
+     195             :     {}
+     196             :   };
+     197             : 
+     198             : /// Auxiliary class used to throw exceptions.
+     199             : /// It just defines <<= operator so that:
+     200             : /// - exceptions can be thrown calling std::throw_with_nested
+     201             : ///   with a "throw like" syntax
+     202             : /// - precedence is the same as the throw operator
+     203             : /// (see https://en.cppreference.com/w/cpp/language/operator_precedence)
+     204             :   class Throw {
+     205             :   public:
+     206             :     template <typename E>
+     207           0 :     [[noreturn]] void operator <<=(E&&e) {
+     208           0 :       if(std::current_exception()) {
+     209           0 :         std::throw_with_nested(e);
+     210             :       } else {
+     211             :         // if not nested, avoid modifying the exception type
+     212           0 :         throw e;
+     213             :       }
+     214             :     }
+     215             :   };
+     216             : 
+     217             : /// Default constructor with no message.
+     218             : /// Only records the stack trace.
+     219             :   Exception();
+     220             : 
+     221             : /// Constructor compatible with PLUMED <=2.4.
+     222          31 :   explicit Exception(const std::string & msg):
+     223          31 :     Exception()
+     224             :   {
+     225          31 :     *this << msg;
+     226          31 :   }
+     227             : 
+     228             : /// Copy constructor.
+     229             : /// Needed to make sure stream is not copied
+     230          25 :   Exception(const Exception & e):
+     231          25 :     msg(e.msg),
+     232          25 :     note(e.note),
+     233          25 :     callstack(e.callstack),
+     234          25 :     callstack_n(e.callstack_n),
+     235          25 :     stackTrace(e.stackTrace)
+     236             :   {
+     237          25 :   }
+     238             : 
+     239             : /// Assignment.
+     240             : /// Needed to make sure stream is not copied
+     241             :   Exception & operator=(const Exception & e) {
+     242             :     msg=e.msg;
+     243             :     note=e.note;
+     244             :     callstack=e.callstack;
+     245             :     callstack_n=e.callstack_n;
+     246             :     stackTrace=e.stackTrace;
+     247             :     stream.str("");
+     248             :     return *this;
+     249             :   }
+     250             : 
+     251             : /// Returns the error message.
+     252             : /// In case the environment variable PLUMED_STACK_TRACE was defined
+     253             : /// and equal to `yes` when the exception was raised,
+     254             : /// the error message will contain the stack trace as well.
+     255          37 :   const char* what() const noexcept override {return msg.c_str();}
+     256             : 
+     257             : /// Returns the stack trace as a string.
+     258             : /// This function is slow as it requires building a parsed string.
+     259             : /// If storing the stack for later usage, you might prefer to use trace().
+     260             :   const char* stack() const;
+     261             : 
+     262             : /// Returns the callstack.
+     263             :   const std::array<void*,128> & trace() const noexcept {return callstack;}
+     264             : 
+     265             : /// Returns the number of elements in the trace array
+     266             :   int trace_n() const noexcept {return callstack_n;}
+     267             : 
+     268             : /// Destructor should be defined and should not throw other exceptions
+     269          54 :   ~Exception() noexcept override {}
+     270             : 
+     271             : /// Insert location.
+     272             : /// Format the location properly.
+     273             :   Exception& operator<<(const Location&);
+     274             : 
+     275             : /// Insert assertion.
+     276             : /// Format the assertion properly
+     277             :   Exception& operator<<(const Assertion&);
+     278             : 
+     279             : /// Insert string.
+     280             : /// Append this string to the message.
+     281             :   Exception& operator<<(const std::string&);
+     282             : 
+     283             : /// Insert anything else.
+     284             : /// This allows to dump also other types (e.g. double, or even Vector).
+     285             : /// Anything that can be written on a stream can go here.
+     286             :   template<typename T>
+     287          37 :   Exception& operator<<(const T & x) {
+     288          37 :     stream<<x;
+     289          37 :     (*this)<<stream.str();
+     290          37 :     stream.str("");
+     291          37 :     return *this;
+     292             :   }
+     293             : };
+     294             : 
+     295             : /// Class representing a generic error
+     296         151 : class ExceptionError :
+     297             :   public Exception {
+     298             : public:
+     299           1 :   using Exception::Exception;
+     300             :   template<typename T>
+     301             :   ExceptionError& operator<<(const T & x) {
+     302          96 :     *static_cast<Exception*>(this) <<x;
+     303             :     return *this;
+     304             :   }
+     305             : };
+     306             : 
+     307             : /// Class representing a debug error (can only be thrown when using debug options)
+     308           0 : class ExceptionDebug :
+     309             :   public Exception {
+     310             : public:
+     311           1 :   using Exception::Exception;
+     312             :   template<typename T>
+     313             :   ExceptionDebug& operator<<(const T & x) {
+     314             :     *static_cast<Exception*>(this) <<x;
+     315             :     return *this;
+     316             :   }
+     317             : };
+     318             : 
+     319             : /// Class representing a type error in the PLMD::Plumed interface
+     320          21 : class ExceptionTypeError :
+     321             :   public Exception {
+     322             : public:
+     323           0 :   using Exception::Exception;
+     324             :   template<typename T>
+     325             :   ExceptionTypeError& operator<<(const T & x) {
+     326          21 :     *static_cast<Exception*>(this) <<x;
+     327             :     return *this;
+     328             :   }
+     329             : };
+     330             : 
+     331             : #ifdef __GNUG__
+     332             : // With GNU compiler, we can use __PRETTY_FUNCTION__ to get the function name
+     333             : #define __PLUMED_FUNCNAME __PRETTY_FUNCTION__
+     334             : #else
+     335             : // Otherwise, we use the standard C++11 variable
+     336             : #define __PLUMED_FUNCNAME __func__
+     337             : #endif
+     338             : 
+     339             : #ifndef PLUMED_MODULE_DIR
+     340             : #define PLUMED_MODULE_DIR ""
+     341             : #endif
+     342             : 
+     343             : /// \relates PLMD::Exception
+     344             : /// Auxiliary macro that generates a PLMD::Exception::Location object.
+     345             : /// Might be useful if we want to use derived exceptions that could
+     346             : /// be thrown using `throw DerivedException()<<plumed_here<<" "<<other stuff"`.
+     347             : /// It is used in the macros below to throw PLMD::Exception.
+     348             : #define plumed_here PLMD::Exception::Location(PLUMED_MODULE_DIR __FILE__,__LINE__,__PLUMED_FUNCNAME)
+     349             : 
+     350             : /// \relates PLMD::Exception
+     351             : /// Throw an exception with information about the position in the file.
+     352             : /// Messages can be inserted with `plumed_error()<<"message"`.
+     353             : #define plumed_error() throw PLMD::ExceptionError() << plumed_here
+     354             : 
+     355             : /// \relates PLMD::Exception
+     356             : /// Throw a nested exception with information about the position in the file.
+     357             : /// It preliminary checks if we are in a catch block. If so, the caught exception
+     358             : /// is rethrown as nested. If not, it throws a normal ExceptionError.
+     359             : /// NB in theory we could have just redefined plumed_error to this, but
+     360             : /// for some reason cppcheck does not understand that the <<= operator used here is
+     361             : /// [[noreturn]] and thus gives many false warnings
+     362             : #define plumed_error_nested() PLMD::Exception::Throw() <<= PLMD::ExceptionError() << plumed_here
+     363             : 
+     364             : /// \relates PLMD::Exception
+     365             : /// Throw an exception with information about the position in the file
+     366             : /// and a message. Mostly available for backward compatibility
+     367             : #define plumed_merror(msg) plumed_error() << msg
+     368             : 
+     369             : /// \relates PLMD::Exception
+     370             : /// Launches plumed_merror only if test evaluates to false.
+     371             : /// The string describing the test is also reported.
+     372             : /// Further messages can be inserted with `<<`.
+     373             : #define plumed_assert(test) if(!(test)) plumed_error() << PLMD::Exception::Assertion(#test)
+     374             : 
+     375             : /// \relates PLMD::Exception
+     376             : /// Launches plumed_merror only if test evaluates to false.
+     377             : /// The string describing the test is also reported, in addition to
+     378             : /// messages reported in the extra argument. Mostly available for backward compatibility.
+     379             : #define plumed_massert(test,msg) plumed_assert(test) << msg
+     380             : 
+     381             : #ifdef NDEBUG
+     382             : 
+     383             : // These are the versions used when compiling with NDEBUG flag.
+     384             : // The condition is always true, so that the rest of the statement
+     385             : // should be optimized away.
+     386             : #define plumed_dbg_assert(test) plumed_assert(true)
+     387             : #define plumed_dbg_massert(test,msg) plumed_massert(true,msg)
+     388             : 
+     389             : #else
+     390             : 
+     391             : /// \relates PLMD::Exception
+     392             : /// Same as \ref plumed_assert, but only evaluates the condition if NDEBUG is not defined.
+     393             : #define plumed_dbg_assert(test) if(!(test)) PLMD::Exception::Throw() <<= PLMD::ExceptionDebug() << plumed_here << PLMD::Exception::Assertion(#test) << "(this check is enabled only in debug builds)\n"
+     394             : 
+     395             : /// \relates PLMD::Exception
+     396             : /// Same as \ref plumed_massert, but only evaluates the condition if NDEBUG is not defined.
+     397             : #define plumed_dbg_massert(test,msg) plumed_dbg_assert(test) << msg
+     398             : 
+     399             : #endif
+     400             : 
+     401             : }
+     402             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func-sort-c.html b/coverage/tools/FileBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..240b2d30f5 --- /dev/null +++ b/coverage/tools/FileBase.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-05-27 13:05:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase5closeEv982
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1892
_ZN4PLMD8FileBase4linkERNS_6ActionE3949
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4833
_ZN4PLMD8FileBase5flushEv5028
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5538
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6733
_ZN4PLMD8FileBase4linkEP8_IO_FILE20959
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE810316
_ZN4PLMD8FileBase6isOpenEv812522
_ZN4PLMD8FileBaseC2Ev831502
_ZN4PLMD8FileBaseD2Ev831502
_ZNK4PLMD8FileBasecvbEv29232036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func.html b/coverage/tools/FileBase.cpp.func.html new file mode 100644 index 0000000000..2fc2f45ffc --- /dev/null +++ b/coverage/tools/FileBase.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-05-27 13:05:14Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6733
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE20959
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4833
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE810316
_ZN4PLMD8FileBase4linkERNS_6ActionE3949
_ZN4PLMD8FileBase5closeEv982
_ZN4PLMD8FileBase5flushEv5028
_ZN4PLMD8FileBase6isOpenEv812522
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1892
_ZN4PLMD8FileBaseC2Ev831502
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBaseD2Ev831502
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5538
_ZNK4PLMD8FileBasecvbEv29232036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.gcov.html b/coverage/tools/FileBase.cpp.gcov.html new file mode 100644 index 0000000000..ecbfec45e5 --- /dev/null +++ b/coverage/tools/FileBase.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-05-27 13:05: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       20959 : FileBase& FileBase::link(FILE*fp) {
+      43       20959 :   plumed_massert(!this->fp,"cannot link an already open file");
+      44       20959 :   this->fp=fp;
+      45       20959 :   cloned=true;
+      46       20959 :   return *this;
+      47             : }
+      48             : 
+      49        5028 : FileBase& FileBase::flush() {
+      50        5028 :   if(fp) fflush(fp);
+      51        5028 :   return *this;
+      52             : }
+      53             : 
+      54      810316 : FileBase& FileBase::link(Communicator&comm) {
+      55      810316 :   plumed_massert(!fp,"cannot link an already open file");
+      56      810316 :   this->comm=&comm;
+      57      810316 :   return *this;
+      58             : }
+      59             : 
+      60        4833 : FileBase& FileBase::link(PlumedMain&plumed) {
+      61        4833 :   plumed_massert(!fp,"cannot link an already open file");
+      62        4833 :   this->plumed=&plumed;
+      63        4833 :   link(plumed.comm);
+      64        4833 :   return *this;
+      65             : }
+      66             : 
+      67        3949 : FileBase& FileBase::link(Action&action) {
+      68        3949 :   plumed_massert(!fp,"cannot link an already open file");
+      69        3949 :   this->action=&action;
+      70        3949 :   link(action.plumed);
+      71        3949 :   return *this;
+      72             : }
+      73             : 
+      74        1892 : bool FileBase::FileExist(const std::string& path) {
+      75             :   bool do_exist=false;
+      76        3784 :   this->path=appendSuffix(path,getSuffix());
+      77        1892 :   mode="r";
+      78             :   // first try with suffix
+      79        1892 :   FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      80             : // call fclose when ff goes out of scope
+      81        1321 :   auto deleter=[](FILE* f) { if(f) std::fclose(f); };
+      82             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(ff,deleter);
+      83             : 
+      84        1892 :   if(!ff) {
+      85             :     this->path=path;
+      86             :     // then try without suffic
+      87         571 :     ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      88             :     mode="r";
+      89             :   }
+      90        1892 :   if(ff) do_exist=true;
+      91        1892 :   if(comm) comm->Barrier();
+      92        1892 :   return do_exist;
+      93             : }
+      94             : 
+      95      812522 : bool FileBase::isOpen() {
+      96             :   bool isopen=false;
+      97      812522 :   if(fp) isopen=true;
+      98      812522 :   return isopen;
+      99             : }
+     100             : 
+     101         982 : void        FileBase::close() {
+     102         982 :   plumed_assert(!cloned);
+     103         982 :   eof=false;
+     104         982 :   err=false;
+     105         982 :   if(fp)   std::fclose(fp);
+     106             : #ifdef __PLUMED_HAS_ZLIB
+     107         982 :   if(gzfp) gzclose(gzFile(gzfp));
+     108             : #endif
+     109         982 :   fp=NULL;
+     110         982 :   gzfp=NULL;
+     111         982 : }
+     112             : 
+     113      831502 : FileBase::FileBase():
+     114      831502 :   fp(NULL),
+     115      831502 :   gzfp(NULL),
+     116      831502 :   comm(NULL),
+     117      831502 :   plumed(NULL),
+     118      831502 :   action(NULL),
+     119      831502 :   cloned(false),
+     120      831502 :   eof(false),
+     121      831502 :   err(false),
+     122      831502 :   heavyFlush(false),
+     123      831502 :   enforcedSuffix_(false)
+     124             : {
+     125      831502 : }
+     126             : 
+     127      831502 : FileBase::~FileBase()
+     128             : {
+     129      831502 :   if(plumed) plumed->eraseFile(*this);
+     130      831502 :   if(!cloned && fp)   std::fclose(fp);
+     131             : #ifdef __PLUMED_HAS_ZLIB
+     132      831502 :   if(!cloned && gzfp) gzclose(gzFile(gzfp));
+     133             : #endif
+     134      831502 : }
+     135             : 
+     136    29232036 : FileBase::operator bool()const {
+     137    29232036 :   return !eof;
+     138             : }
+     139             : 
+     140        6733 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
+     141        6733 :   if(path=="/dev/null") return path; // do not append a suffix to /dev/null
+     142        6558 :   std::string ret=path;
+     143        6558 :   std::string ext=Tools::extension(path);
+     144             : 
+     145             : // These are the recognized extensions so far:
+     146             : // gz xtc trr
+     147             : // If a file name ends with one of these extensions, the suffix is added *before*
+     148             : // the extension. This is useful when extensions are conventionally used
+     149             : // to detect file type, so as to allow easier file manipulation.
+     150             : // Removing this line, any extension recognized by Tools::extension() would be considered
+     151             : //  if(ext!="gz" && ext!="xtc" && ext!="trr") ext="";
+     152             : 
+     153        6558 :   if(ext.length()>0) {
+     154        4779 :     int l=path.length()-(ext.length()+1);
+     155        4779 :     plumed_assert(l>=0);
+     156        4779 :     ret.resize(l);
+     157             :   }
+     158             :   ret+=suffix;
+     159       11337 :   if(ext.length()>0)ret+="."+ext;
+     160             :   return ret;
+     161             : }
+     162             : 
+     163         258 : FileBase& FileBase::enforceSuffix(const std::string&suffix) {
+     164         258 :   enforcedSuffix_=true;
+     165         258 :   enforcedSuffix=suffix;
+     166         258 :   return *this;
+     167             : }
+     168             : 
+     169        5538 : std::string FileBase::getSuffix()const {
+     170        5538 :   if(enforcedSuffix_) return enforcedSuffix;
+     171        5274 :   if(plumed) return plumed->getSuffix();
+     172         503 :   return "";
+     173             : }
+     174             : 
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func-sort-c.html b/coverage/tools/FileBase.h.func-sort-c.html new file mode 100644 index 0000000000..3acfa2af1f --- /dev/null +++ b/coverage/tools/FileBase.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func.html b/coverage/tools/FileBase.h.func.html new file mode 100644 index 0000000000..6d22ae734c --- /dev/null +++ b/coverage/tools/FileBase.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.gcov.html b/coverage/tools/FileBase.h.gcov.html new file mode 100644 index 0000000000..1c412c0abb --- /dev/null +++ b/coverage/tools/FileBase.h.gcov.html @@ -0,0 +1,228 @@ + + + + + + + LCOV - plumed test coverage - tools/FileBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-05-27 13:05: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    16816755 :   class FieldBase {
+      48             : // everything is public to simplify usage
+      49             :   public:
+      50             :     std::string name;
+      51             :     std::string value;
+      52             :     bool constant;
+      53    16682344 :     FieldBase(): constant(false) {}
+      54             :   };
+      55             : 
+      56             : /// file pointer
+      57             :   FILE* fp;
+      58             : /// zip file pointer.
+      59             :   void* gzfp;
+      60             : /// communicator. NULL if not set
+      61             :   Communicator* comm;
+      62             : /// pointer to main plumed object. NULL if not linked
+      63             :   PlumedMain* plumed;
+      64             : /// pointer to corresponding action. NULL if not linked
+      65             :   Action* action;
+      66             : /// Control closing on destructor.
+      67             : /// If true, file will not be closed in destructor
+      68             :   bool cloned;
+      69             : /// Private constructor.
+      70             : /// In this manner one cannot instantiate a FileBase object
+      71             :   FileBase();
+      72             : /// Set to true when end of file is encountered
+      73             :   bool eof;
+      74             : /// Set to true when error is encountered
+      75             :   bool err;
+      76             : /// path of the opened file
+      77             :   std::string path;
+      78             : /// mode of the opened file
+      79             :   std::string mode;
+      80             : /// Set to true if you want flush to be heavy (close/reopen)
+      81             :   bool heavyFlush;
+      82             : public:
+      83             : /// Append suffix.
+      84             : /// It appends the desired suffix to the string. Notice that
+      85             : /// it conserves some suffix (e.g. gz/xtc/trr).
+      86             :   static std::string appendSuffix(const std::string&path,const std::string&suffix);
+      87             : private:
+      88             : /// Enforced suffix:
+      89             :   std::string enforcedSuffix;
+      90             : /// If true, use enforcedSuffix, else get it from PlumedMain
+      91             :   bool enforcedSuffix_;
+      92             : public:
+      93             : /// Link to an already open filed
+      94             :   FileBase& link(FILE*);
+      95             : /// Link to a PlumedMain object
+      96             : /// Automatically links also the corresponding Communicator.
+      97             :   FileBase& link(PlumedMain&);
+      98             : /// Link to a Communicator object
+      99             :   FileBase& link(Communicator&);
+     100             : /// Link to an Action object.
+     101             : /// Automatically links also the corresponding PlumedMain and Communicator.
+     102             :   FileBase& link(Action&);
+     103             : /// Enforce suffix.
+     104             : /// Overrides the one set in PlumedMain&
+     105             :   FileBase& enforceSuffix(const std::string&suffix);
+     106             : /// Flushes the file to disk
+     107             :   virtual FileBase& flush();
+     108             : /// Closes the file
+     109             : /// Should be used only for explicitely opened files.
+     110             :   void        close();
+     111             : /// Virtual destructor (allows inheritance)
+     112             :   virtual ~FileBase();
+     113             : /// Check for error/eof.
+     114             :   operator bool () const;
+     115             : /// Set heavyFlush flag
+     116         634 :   void setHeavyFlush() { heavyFlush=true;}
+     117             : /// Opens the file
+     118             :   virtual FileBase& open(const std::string&name)=0;
+     119             : /// Check if the file exists
+     120             :   bool FileExist(const std::string& path);
+     121             : /// Check if a file is open
+     122             :   bool isOpen();
+     123             : /// Retrieve the path
+     124             :   std::string getPath()const;
+     125             : /// Retrieve the mode
+     126             :   std::string getMode()const;
+     127             : /// Get the file suffix
+     128             :   std::string getSuffix()const;
+     129             : /// Get the underlying file pointer.
+     130             : /// It might be null even if the file is open, e.g. when the file
+     131             : /// was open as a gzipped file.
+     132             :   FILE* getFILE()const;
+     133             : };
+     134             : 
+     135             : inline
+     136             : std::string FileBase::getPath()const {
+     137         824 :   return path;
+     138             : }
+     139             : 
+     140             : inline
+     141             : std::string FileBase::getMode()const {
+     142         173 :   return mode;
+     143             : }
+     144             : 
+     145             : inline
+     146             : FILE* FileBase::getFILE()const {
+     147          18 :   return fp;
+     148             : }
+     149             : 
+     150             : }
+     151             : 
+     152             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func-sort-c.html b/coverage/tools/ForwardDecl.h.func-sort-c.html new file mode 100644 index 0000000000..6f224d02ff --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_87
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_582
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_5AtomsEEC2IJRNS_10PlumedMainEEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_815523
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1615161
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func.html b/coverage/tools/ForwardDecl.h.func.html new file mode 100644 index 0000000000..80bd697e68 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1615161
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_87
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_815523
_ZN4PLMD11ForwardDeclINS_5AtomsEEC2IJRNS_10PlumedMainEEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_805268
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_582
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_805268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.gcov.html b/coverage/tools/ForwardDecl.h.gcov.html new file mode 100644 index 0000000000..8ed3b2e9cf --- /dev/null +++ b/coverage/tools/ForwardDecl.h.gcov.html @@ -0,0 +1,131 @@ + + + + + + + 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-05-27 13:05: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     4846941 : 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     9678765 : ForwardDecl<T>::ForwardDecl(Args &&...args):
+      49     9678765 :   std::unique_ptr<T>(new T(std::forward<Args>(args)...))
+      50     9678765 : {}
+      51             : 
+      52             : 
+      53             : }
+      54             : 
+      55             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func-sort-c.html b/coverage/tools/Grid.cpp.func-sort-c.html new file mode 100644 index 0000000000..4a623b65b1 --- /dev/null +++ b/coverage/tools/Grid.cpp.func-sort-c.html @@ -0,0 +1,380 @@ + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-05-27 13:05: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
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1147
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1147
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1327
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1455
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3711
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8910
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase5getDxEm11890
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23364
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104281
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1110281
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1113992
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1171742
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079776
_ZN4PLMD4Grid8setValueEmd6444104
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7145799
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase8getPointEm28822338
_ZNK4PLMD4Grid7getSizeEv28865222
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542440
_ZNK4PLMD8GridBase10getIndicesEm37829485
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func.html b/coverage/tools/Grid.cpp.func.html new file mode 100644 index 0000000000..fc514f72bb --- /dev/null +++ b/coverage/tools/Grid.cpp.func.html @@ -0,0 +1,380 @@ + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-05-27 13:05:14Functions:557771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SparseGrid11writeToFileERNS_5OFileE0
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZN4PLMD10SparseGrid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE0
_ZN4PLMD10SparseGrid8addValueEmd0
_ZN4PLMD10SparseGrid8setValueEmd0
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1147
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1171742
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZN4PLMD4Grid24findSetOfPointsOnContourERKdRKSt6vectorIbSaIbEERjRS3_IS3_IdSaIdEESaISA_EE0
_ZN4PLMD4Grid26logAllValuesAndDerivativesERKd0
_ZN4PLMD4Grid26mpiSumValuesAndDerivativesERNS_12CommunicatorE0
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZN4PLMD4Grid36applyFunctionAllValuesAndDerivativesEPFddES2_1
_ZN4PLMD4Grid5clearEv1
_ZN4PLMD4Grid7projectERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPNS_10WeightBaseE81
_ZN4PLMD4Grid8addValueEmd1
_ZN4PLMD4Grid8setValueEmd6444104
_ZN4PLMD4Grid9integrateERSt6vectorIjSaIjEE0
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1147
_ZN4PLMD8GridBase13writeCubeFileERNS_5OFileERKd0
_ZN4PLMD8GridBase22addValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase22findMaximalPathMinimumERKSt6vectorIdSaIdEES5_273
_ZN4PLMD8GridBase22setValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1455
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileERKS9_IS6_SaIS6_EESL_RKS9_IjSaIjEEbbb20
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileEbbb70
_ZN4PLMD8GridBase8addValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase9addKernelERKNS_15KernelFunctionsE0
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1327
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZNK4PLMD10SparseGrid10getMaxSizeEv0
_ZNK4PLMD10SparseGrid11getMaxValueEv9
_ZNK4PLMD10SparseGrid11getMinValueEv0
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmRSt6vectorIdSaIdEE200
_ZNK4PLMD10SparseGrid7getSizeEv0
_ZNK4PLMD10SparseGrid8getValueEm0
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079776
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD4Grid7getSizeEv28865222
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104281
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3711
_ZNK4PLMD8GridBase10getIndicesEm37829485
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8910
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase12getBinVolumeEv37
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23364
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3711
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZNK4PLMD8GridBase5getDxEm11890
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7145799
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEE0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542440
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1113992
_ZNK4PLMD8GridBase8getPointEm28822338
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1110281
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.gcov.html b/coverage/tools/Grid.cpp.gcov.html new file mode 100644 index 0000000000..ad768dc281 --- /dev/null +++ b/coverage/tools/Grid.cpp.gcov.html @@ -0,0 +1,1204 @@ + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-05-27 13:05: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        1327 : GridBase::GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+      45        1327 :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv) {
+      46             : // various checks
+      47        1327 :   plumed_assert(args.size()<=maxdim) << "grid dim cannot exceed "<<maxdim;
+      48        1327 :   plumed_massert(args.size()==gmin.size(),"grid min dimensions in input do not match number of arguments");
+      49        1327 :   plumed_massert(args.size()==nbin.size(),"number of bins on input do not match number of arguments");
+      50        1327 :   plumed_massert(args.size()==gmax.size(),"grid max dimensions in input do not match number of arguments");
+      51        1327 :   unsigned dim=gmax.size();
+      52             :   std::vector<std::string> names;
+      53             :   std::vector<bool> isperiodic;
+      54             :   std::vector<std::string> pmin,pmax;
+      55        1327 :   names.resize( dim );
+      56        1327 :   isperiodic.resize( dim );
+      57        1327 :   pmin.resize( dim );
+      58        1327 :   pmax.resize( dim );
+      59        2933 :   for(unsigned int i=0; i<dim; ++i) {
+      60        1606 :     names[i]=args[i]->getName();
+      61        1606 :     if( args[i]->isPeriodic() ) {
+      62             :       isperiodic[i]=true;
+      63         502 :       args[i]->getDomain( pmin[i], pmax[i] );
+      64             :     } else {
+      65             :       isperiodic[i]=false;
+      66             :       pmin[i]="0.";
+      67             :       pmax[i]="0.";
+      68             :     }
+      69             :   }
+      70             : // this is a value-independent initializator
+      71        1327 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+      72        2654 : }
+      73             : 
+      74         128 : GridBase::GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+      75             :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+      76         128 :                    const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+      77             : // this calls the initializator
+      78         128 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+      79         128 : }
+      80             : 
+      81        1455 : void GridBase::Init(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+      82             :                     const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+      83             :                     const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+      84        1455 :   fmt_="%14.9f";
+      85             : // various checks
+      86        1455 :   plumed_assert(names.size()<=maxdim) << "grid size cannot exceed "<<maxdim;
+      87        1455 :   plumed_massert(names.size()==gmin.size(),"grid dimensions in input do not match number of arguments");
+      88        1455 :   plumed_massert(names.size()==nbin.size(),"grid dimensions in input do not match number of arguments");
+      89        1455 :   plumed_massert(names.size()==gmax.size(),"grid dimensions in input do not match number of arguments");
+      90        1455 :   dimension_=gmax.size();
+      91        1455 :   str_min_=gmin; str_max_=gmax;
+      92        1455 :   argnames.resize( dimension_ );
+      93        1455 :   min_.resize( dimension_ );
+      94        1455 :   max_.resize( dimension_ );
+      95        1455 :   pbc_.resize( dimension_ );
+      96        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+      97        1734 :     argnames[i]=names[i];
+      98        1734 :     if( isperiodic[i] ) {
+      99             :       pbc_[i]=true;
+     100             :       str_min_[i]=pmin[i];
+     101             :       str_max_[i]=pmax[i];
+     102             :     } else {
+     103             :       pbc_[i]=false;
+     104             :     }
+     105        1734 :     Tools::convert(str_min_[i],min_[i]);
+     106        1734 :     Tools::convert(str_max_[i],max_[i]);
+     107        1734 :     funcname=funcl;
+     108        1734 :     plumed_massert(max_[i]>min_[i],"maximum in grid must be larger than minimum");
+     109        1734 :     plumed_massert(nbin[i]>0,"number of grid points must be greater than zero");
+     110             :   }
+     111        1455 :   nbin_=nbin;
+     112        1455 :   dospline_=dospline;
+     113        1455 :   usederiv_=usederiv;
+     114        1455 :   if(dospline_) plumed_assert(dospline_==usederiv_);
+     115        1455 :   maxsize_=1;
+     116        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+     117        1734 :     dx_.push_back( (max_[i]-min_[i])/static_cast<double>( nbin_[i] ) );
+     118        1734 :     if( !pbc_[i] ) { max_[i] += dx_[i]; nbin_[i] += 1; }
+     119        1734 :     maxsize_*=nbin_[i];
+     120             :   }
+     121        1455 : }
+     122             : 
+     123     1360394 : std::vector<std::string> GridBase::getMin() const {
+     124     1360394 :   return str_min_;
+     125             : }
+     126             : 
+     127         343 : std::vector<std::string> GridBase::getMax() const {
+     128         343 :   return str_max_;
+     129             : }
+     130             : 
+     131     1319573 : std::vector<double> GridBase::getDx() const {
+     132     1319573 :   return dx_;
+     133             : }
+     134             : 
+     135       11890 : double GridBase::getDx(index_t j) const {
+     136       11890 :   return dx_[j];
+     137             : }
+     138             : 
+     139          37 : double GridBase::getBinVolume() const {
+     140             :   double vol=1.;
+     141         102 :   for(unsigned i=0; i<dx_.size(); ++i) vol*=dx_[i];
+     142          37 :   return vol;
+     143             : }
+     144             : 
+     145        2240 : std::vector<bool> GridBase::getIsPeriodic() const {
+     146        2240 :   return pbc_;
+     147             : }
+     148             : 
+     149     1012510 : std::vector<unsigned> GridBase::getNbin() const {
+     150     1012510 :   return nbin_;
+     151             : }
+     152             : 
+     153        9436 : std::vector<std::string> GridBase::getArgNames() const {
+     154        9436 :   return argnames;
+     155             : }
+     156             : 
+     157    18321217 : unsigned GridBase::getDimension() const {
+     158    18321217 :   return dimension_;
+     159             : }
+     160             : 
+     161             : // we are flattening arrays using a column-major order
+     162     7145799 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
+     163             :   plumed_dbg_assert(indices.size()==dimension_);
+     164    19319332 :   for(unsigned int i=0; i<dimension_; i++)
+     165    12173533 :     if(indices[i]>=nbin_[i]) {
+     166             :       std::string is;
+     167           0 :       Tools::convert(i,is);
+     168           0 :       plumed_error() << "Looking for a value outside the grid along the " << is << " dimension (arg name: "<<getArgNames()[i]<<")";
+     169             :     }
+     170     7145799 :   index_t index=indices[dimension_-1];
+     171    12173533 :   for(unsigned int i=dimension_-1; i>0; --i) {
+     172     5027734 :     index=index*nbin_[i-1]+indices[i-1];
+     173             :   }
+     174     7145799 :   return index;
+     175             : }
+     176             : 
+     177     1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
+     178             :   plumed_dbg_assert(x.size()==dimension_);
+     179     2200138 :   return getIndex(getIndices(x));
+     180             : }
+     181             : 
+     182             : // we are flattening arrays using a column-major order
+     183    37829485 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
+     184    37829485 :   std::vector<unsigned> indices(dimension_);
+     185             :   index_t kk=index;
+     186    37829485 :   indices[0]=(index%nbin_[0]);
+     187    54778194 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     188    16948709 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     189    16948709 :     indices[i]=(kk%nbin_[i]);
+     190             :   }
+     191    37829485 :   if(dimension_>=2) {
+     192    36999987 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     193             :   }
+     194    37829485 :   return indices;
+     195             : }
+     196             : 
+     197        8910 : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
+     198        8910 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     199             :   index_t kk=index;
+     200        8910 :   indices[0]=(index%nbin_[0]);
+     201        8910 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     202           0 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     203           0 :     indices[i]=(kk%nbin_[i]);
+     204             :   }
+     205        8910 :   if(dimension_>=2) {
+     206        2980 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     207             :   }
+     208        8910 : }
+     209             : 
+     210     1104281 : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
+     211             :   plumed_dbg_assert(x.size()==dimension_);
+     212     1104281 :   std::vector<unsigned> indices(dimension_);
+     213     3308069 :   for(unsigned int i=0; i<dimension_; ++i) {
+     214     2203788 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     215             :   }
+     216     1104281 :   return indices;
+     217             : }
+     218             : 
+     219        3711 : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
+     220             :   plumed_dbg_assert(x.size()==dimension_);
+     221        3711 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     222        8167 :   for(unsigned int i=0; i<dimension_; ++i) {
+     223        4456 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     224             :   }
+     225        3711 : }
+     226             : 
+     227    31542440 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
+     228             :   plumed_dbg_assert(indices.size()==dimension_);
+     229    31542440 :   std::vector<double> x(dimension_);
+     230   108460905 :   for(unsigned int i=0; i<dimension_; ++i) {
+     231    76918465 :     x[i]=min_[i]+(double)(indices[i])*dx_[i];
+     232             :   }
+     233    31542440 :   return x;
+     234             : }
+     235             : 
+     236    28822338 : std::vector<double> GridBase::getPoint(index_t index) const {
+     237             :   plumed_dbg_assert(index<maxsize_);
+     238    57644676 :   return getPoint(getIndices(index));
+     239             : }
+     240             : 
+     241           0 : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
+     242             :   plumed_dbg_assert(x.size()==dimension_);
+     243           0 :   return getPoint(getIndices(x));
+     244             : }
+     245             : 
+     246     1110281 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
+     247             :   plumed_dbg_assert(index<maxsize_);
+     248     1110281 :   getPoint(getIndices(index),point);
+     249     1110281 : }
+     250             : 
+     251     1113992 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
+     252             :   plumed_dbg_assert(indices.size()==dimension_);
+     253             :   plumed_dbg_assert(point.size()==dimension_);
+     254     3329356 :   for(unsigned int i=0; i<dimension_; ++i) {
+     255     2215364 :     point[i]=min_[i]+(double)(indices[i])*dx_[i];
+     256             :   }
+     257     1113992 : }
+     258             : 
+     259           0 : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
+     260             :   plumed_dbg_assert(x.size()==dimension_);
+     261           0 :   getPoint(getIndices(x),point);
+     262           0 : }
+     263             : 
+     264       23364 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
+     265             :   plumed_dbg_assert(indices.size()==dimension_ && nneigh.size()==dimension_);
+     266             : 
+     267             :   std::vector<index_t> neighbors;
+     268       23364 :   std::vector<unsigned> small_bin(dimension_);
+     269             : 
+     270             :   unsigned small_nbin=1;
+     271       69592 :   for(unsigned j=0; j<dimension_; ++j) {
+     272       46228 :     small_bin[j]=(2*nneigh[j]+1);
+     273       46228 :     small_nbin*=small_bin[j];
+     274             :   }
+     275             : 
+     276       23364 :   std::vector<unsigned> small_indices(dimension_);
+     277             :   std::vector<unsigned> tmp_indices;
+     278     1291958 :   for(unsigned index=0; index<small_nbin; ++index) {
+     279     1268594 :     tmp_indices.resize(dimension_);
+     280             :     unsigned kk=index;
+     281     1268594 :     small_indices[0]=(index%small_bin[0]);
+     282     1268594 :     for(unsigned i=1; i<dimension_-1; ++i) {
+     283           0 :       kk=(kk-small_indices[i-1])/small_bin[i-1];
+     284           0 :       small_indices[i]=(kk%small_bin[i]);
+     285             :     }
+     286     1268594 :     if(dimension_>=2) {
+     287     1255566 :       small_indices[dimension_-1]=((kk-small_indices[dimension_-2])/small_bin[dimension_-2]);
+     288             :     }
+     289             :     unsigned ll=0;
+     290     3792754 :     for(unsigned i=0; i<dimension_; ++i) {
+     291     2524160 :       int i0=small_indices[i]-nneigh[i]+indices[i];
+     292     2524160 :       if(!pbc_[i] && i0<0)         continue;
+     293     2504438 :       if(!pbc_[i] && i0>=static_cast<int>(nbin_[i])) continue;
+     294     2483466 :       if( pbc_[i] && i0<0)         i0=nbin_[i]-(-i0)%nbin_[i];
+     295     2483466 :       if( pbc_[i] && i0>=static_cast<int>(nbin_[i])) i0%=nbin_[i];
+     296     2483466 :       tmp_indices[ll]=static_cast<unsigned>(i0);
+     297     2483466 :       ll++;
+     298             :     }
+     299     1268594 :     tmp_indices.resize(ll);
+     300     1268594 :     if(tmp_indices.size()==dimension_) {neighbors.push_back(getIndex(tmp_indices));}
+     301             :   }
+     302       23364 :   return neighbors;
+     303             : }
+     304             : 
+     305        4211 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
+     306             :   plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
+     307        8422 :   return getNeighbors(getIndices(x),nneigh);
+     308             : }
+     309             : 
+     310       19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
+     311             :   plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
+     312       38306 :   return getNeighbors(getIndices(index),nneigh);
+     313             : }
+     314             : 
+     315        3711 : void GridBase::getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<GridBase::index_t>& neighbors, unsigned& nneighbors)const {
+     316             :   plumed_dbg_assert(indices.size()==dimension_);
+     317        3711 :   unsigned nneigh=unsigned(std::pow(2.0,int(dimension_)));
+     318        3711 :   if (neighbors.size()!=nneigh) neighbors.resize(nneigh);
+     319             : 
+     320        3711 :   std::vector<unsigned> nindices(dimension_);
+     321        3711 :   unsigned inind; nneighbors = 0;
+     322       12623 :   for(unsigned int i=0; i<nneigh; ++i) {
+     323             :     unsigned tmp=i; inind=0;
+     324       20804 :     for(unsigned int j=0; j<dimension_; ++j) {
+     325       11892 :       unsigned i0=tmp%2+indices[j];
+     326       11892 :       tmp/=2;
+     327       11892 :       if(!pbc_[j] && i0==nbin_[j]) continue;
+     328       11890 :       if( pbc_[j] && i0==nbin_[j]) i0=0;
+     329       11890 :       nindices[inind++]=i0;
+     330             :     }
+     331        8912 :     if(inind==dimension_) neighbors[nneighbors++]=getIndex(nindices);
+     332             :   }
+     333        3711 : }
+     334             : 
+     335        9577 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const index_t index) const {
+     336        9577 :   std::vector<index_t> nearest_neighs = std::vector<index_t>();
+     337       28730 :   for (unsigned i = 0; i < dimension_; i++) {
+     338       19153 :     std::vector<unsigned> neighsneeded = std::vector<unsigned>(dimension_, 0);
+     339       19153 :     neighsneeded[i] = 1;
+     340       19153 :     std::vector<index_t> singledim_nearest_neighs = getNeighbors(index, neighsneeded);
+     341       74978 :     for (unsigned j = 0; j < singledim_nearest_neighs.size(); j++) {
+     342       55825 :       index_t neigh = singledim_nearest_neighs[j];
+     343       55825 :       if (neigh != index) {
+     344       36672 :         nearest_neighs.push_back(neigh);
+     345             :       }
+     346             :     }
+     347             :   }
+     348        9577 :   return nearest_neighs;
+     349             : }
+     350             : 
+     351           0 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const std::vector<unsigned> &indices) const {
+     352             :   plumed_dbg_assert(indices.size() == dimension_);
+     353           0 :   return getNearestNeighbors(getIndex(indices));
+     354             : }
+     355             : 
+     356           0 : void GridBase::addKernel( const KernelFunctions& kernel ) {
+     357             :   plumed_dbg_assert( kernel.ndim()==dimension_ );
+     358           0 :   std::vector<unsigned> nneighb=kernel.getSupport( dx_ );
+     359           0 :   std::vector<index_t> neighbors=getNeighbors( kernel.getCenter(), nneighb );
+     360           0 :   std::vector<double> xx( dimension_ );
+     361           0 :   std::vector<std::unique_ptr<Value>> vv( dimension_ );
+     362             :   std::string str_min, str_max;
+     363           0 :   for(unsigned i=0; i<dimension_; ++i) {
+     364           0 :     vv[i]=Tools::make_unique<Value>();
+     365           0 :     if( pbc_[i] ) {
+     366           0 :       Tools::convert(min_[i],str_min);
+     367           0 :       Tools::convert(max_[i],str_max);
+     368           0 :       vv[i]->setDomain( str_min, str_max );
+     369             :     } else {
+     370           0 :       vv[i]->setNotPeriodic();
+     371             :     }
+     372             :   }
+     373             : 
+     374             : // vv_ptr contains plain pointers obtained from vv.
+     375             : // this is the simplest way to replace a unique_ptr here.
+     376             : // perhaps the interface of kernel.evaluate() should be changed
+     377             : // in order to accept a std::vector<std::unique_ptr<Value>>
+     378           0 :   auto vv_ptr=Tools::unique2raw(vv);
+     379             : 
+     380           0 :   std::vector<double> der( dimension_ );
+     381           0 :   for(unsigned i=0; i<neighbors.size(); ++i) {
+     382           0 :     index_t ineigh=neighbors[i];
+     383           0 :     getPoint( ineigh, xx );
+     384           0 :     for(unsigned j=0; j<dimension_; ++j) vv[j]->set(xx[j]);
+     385           0 :     double newval = kernel.evaluate( vv_ptr, der, usederiv_ );
+     386           0 :     if( usederiv_ ) addValueAndDerivatives( ineigh, newval, der );
+     387           0 :     else addValue( ineigh, newval );
+     388             :   }
+     389           0 : }
+     390             : 
+     391     1193613 : double GridBase::getValue(const std::vector<unsigned> & indices) const {
+     392     1193613 :   return getValue(getIndex(indices));
+     393             : }
+     394             : 
+     395         345 : double GridBase::getValue(const std::vector<double> & x) const {
+     396         345 :   if(!dospline_) {
+     397          18 :     return getValue(getIndex(x));
+     398             :   } else {
+     399         327 :     std::vector<double> der(dimension_);
+     400         327 :     return getValueAndDerivatives(x,der);
+     401             :   }
+     402             : }
+     403             : 
+     404     2527708 : double GridBase::getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const {
+     405     2527708 :   return getValueAndDerivatives(getIndex(indices),der);
+     406             : }
+     407             : 
+     408        3711 : double GridBase::getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const {
+     409             :   plumed_dbg_assert(der.size()==dimension_ && usederiv_);
+     410             : 
+     411        3711 :   if(dospline_) {
+     412             :     double X,X2,X3,value;
+     413             :     std::array<double,maxdim> fd, C, D;
+     414        3711 :     std::vector<double> dder(dimension_);
+     415             : // reset
+     416             :     value=0.0;
+     417        8167 :     for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     418             : 
+     419        3711 :     std::vector<unsigned> indices(dimension_);
+     420        3711 :     getIndices(x, indices);
+     421        3711 :     std::vector<double> xfloor(dimension_);
+     422        3711 :     getPoint(indices, xfloor);
+     423        3711 :     std::vector<index_t> neigh; unsigned nneigh; getSplineNeighbors(indices, neigh, nneigh);
+     424             : 
+     425             : // loop over neighbors
+     426             :     std::vector<unsigned> nindices;
+     427       12621 :     for(unsigned int ipoint=0; ipoint<nneigh; ++ipoint) {
+     428        8910 :       double grid=getValueAndDerivatives(neigh[ipoint],dder);
+     429        8910 :       getIndices(neigh[ipoint], nindices);
+     430             :       double ff=1.0;
+     431             : 
+     432       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     433             :         int x0=1;
+     434       11890 :         if(nindices[j]==indices[j]) x0=0;
+     435       11890 :         double dx=getDx(j);
+     436       11890 :         X=std::abs((x[j]-xfloor[j])/dx-(double)x0);
+     437       11890 :         X2=X*X;
+     438       11890 :         X3=X2*X;
+     439             :         double yy;
+     440       11890 :         if(std::abs(grid)<0.0000001) yy=0.0;
+     441        8996 :         else yy=-dder[j]/grid;
+     442       11890 :         C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*dx;
+     443       11890 :         D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*dx;
+     444       11890 :         D[j]*=(x0?-1.0:1.0)/dx;
+     445       11890 :         ff*=C[j];
+     446             :       }
+     447       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     448       11890 :         fd[j]=D[j];
+     449       29740 :         for(unsigned i=0; i<dimension_; ++i) if(i!=j) fd[j]*=C[i];
+     450             :       }
+     451        8910 :       value+=grid*ff;
+     452       20800 :       for(unsigned j=0; j<dimension_; ++j) der[j]+=grid*fd[j];
+     453             :     }
+     454             :     return value;
+     455             :   } else {
+     456           0 :     return getValueAndDerivatives(getIndex(x),der);
+     457             :   }
+     458             : }
+     459             : 
+     460           0 : void GridBase::setValue(const std::vector<unsigned> & indices, double value) {
+     461           0 :   setValue(getIndex(indices),value);
+     462           0 : }
+     463             : 
+     464           0 : void GridBase::setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     465           0 :   setValueAndDerivatives(getIndex(indices),value,der);
+     466           0 : }
+     467             : 
+     468           0 : void GridBase::addValue(const std::vector<unsigned> & indices, double value) {
+     469           0 :   addValue(getIndex(indices),value);
+     470           0 : }
+     471             : 
+     472           0 : void GridBase::addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     473           0 :   addValueAndDerivatives(getIndex(indices),value,der);
+     474           0 : }
+     475             : 
+     476        1147 : void GridBase::writeHeader(OFile& ofile) {
+     477        2611 :   for(unsigned i=0; i<dimension_; ++i) {
+     478        2928 :     ofile.addConstantField("min_" + argnames[i]);
+     479        2928 :     ofile.addConstantField("max_" + argnames[i]);
+     480        2928 :     ofile.addConstantField("nbins_" + argnames[i]);
+     481        2928 :     ofile.addConstantField("periodic_" + argnames[i]);
+     482             :   }
+     483        1147 : }
+     484             : 
+     485           1 : void Grid::clear() {
+     486           1 :   grid_.assign(maxsize_,0.0);
+     487           1 :   if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     488           1 : }
+     489             : 
+     490        1147 : void Grid::writeToFile(OFile& ofile) {
+     491        1147 :   std::vector<double> xx(dimension_);
+     492        1147 :   std::vector<double> der(dimension_);
+     493             :   double f;
+     494        1147 :   writeHeader(ofile);
+     495     2533412 :   for(index_t i=0; i<getSize(); ++i) {
+     496     2532265 :     xx=getPoint(i);
+     497     2532265 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     498     1989707 :     else {f=getValue(i);}
+     499     4914902 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     500     7484524 :     for(unsigned j=0; j<dimension_; ++j) {
+     501     9904518 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     502     9904518 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     503     9904518 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     504     6986607 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     505     5835822 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     506             :     }
+     507     7484524 :     for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField(argnames[j],xx[j]); }
+     508     5064530 :     ofile.fmtField(" "+fmt_); ofile.printField(funcname,f);
+     509     5194297 :     if(usederiv_) for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField("der_" + argnames[j],der[j]); }
+     510     2532265 :     ofile.printField();
+     511             :   }
+     512        1147 : }
+     513             : 
+     514           0 : void GridBase::writeCubeFile(OFile& ofile, const double& lunit) {
+     515           0 :   plumed_assert( dimension_==3 );
+     516           0 :   ofile.printf("PLUMED CUBE FILE\n");
+     517           0 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     518             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     519           0 :   ofile.printf("%d %f %f %f\n",1,-0.5*lunit*(max_[0]-min_[0]),-0.5*lunit*(max_[1]-min_[1]),-0.5*lunit*(max_[2]-min_[2]));
+     520           0 :   ofile.printf("%u %f %f %f\n",nbin_[0],lunit*dx_[0],0.0,0.0);  // Number of bins in each direction followed by
+     521           0 :   ofile.printf("%u %f %f %f\n",nbin_[1],0.0,lunit*dx_[1],0.0);  // shape of voxel
+     522           0 :   ofile.printf("%u %f %f %f\n",nbin_[2],0.0,0.0,lunit*dx_[2]);
+     523           0 :   ofile.printf("%d %f %f %f\n",1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     524           0 :   std::vector<unsigned> pp(3);
+     525           0 :   for(pp[0]=0; pp[0]<nbin_[0]; ++pp[0]) {
+     526           0 :     for(pp[1]=0; pp[1]<nbin_[1]; ++pp[1]) {
+     527           0 :       for(pp[2]=0; pp[2]<nbin_[2]; ++pp[2]) {
+     528           0 :         ofile.printf("%f ",getValue(pp) );
+     529           0 :         if(pp[2]%6==5) ofile.printf("\n");
+     530             :       }
+     531           0 :       ofile.printf("\n");
+     532             :     }
+     533             :   }
+     534           0 : }
+     535             : 
+     536          20 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile,
+     537             :     const std::vector<std::string> & gmin,const std::vector<std::string> & gmax,
+     538             :     const std::vector<unsigned> & nbin,bool dosparse, bool dospline, bool doder) {
+     539          20 :   std::unique_ptr<GridBase> grid=GridBase::create(funcl,args,ifile,dosparse,dospline,doder);
+     540          20 :   std::vector<unsigned> cbin( grid->getNbin() );
+     541          20 :   std::vector<std::string> cmin( grid->getMin() ), cmax( grid->getMax() );
+     542          49 :   for(unsigned i=0; i<args.size(); ++i) {
+     543          29 :     plumed_massert( cmin[i]==gmin[i], "mismatched grid min" );
+     544          29 :     plumed_massert( cmax[i]==gmax[i], "mismatched grid max" );
+     545          29 :     if( args[i]->isPeriodic() ) {
+     546           8 :       plumed_massert( cbin[i]==nbin[i], "mismatched grid nbins" );
+     547             :     } else {
+     548          21 :       plumed_massert( (cbin[i]-1)==nbin[i], "mismatched grid nbins");
+     549             :     }
+     550             :   }
+     551          20 :   return grid;
+     552          20 : }
+     553             : 
+     554          70 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile, bool dosparse, bool dospline, bool doder)
+     555             : {
+     556          70 :   std::unique_ptr<GridBase> grid;
+     557          70 :   unsigned nvar=args.size(); bool hasder=false; std::string pstring;
+     558          70 :   std::vector<int> gbin1(nvar); std::vector<unsigned> gbin(nvar);
+     559          70 :   std::vector<std::string> labels(nvar),gmin(nvar),gmax(nvar);
+     560          70 :   std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     561             : // Retrieve names for fields
+     562         158 :   for(unsigned i=0; i<args.size(); ++i) labels[i]=args[i]->getName();
+     563             : // And read the stuff from the header
+     564          70 :   plumed_massert( ifile.FieldExist( funcl ), "no column labelled " + funcl + " in in grid input");
+     565         158 :   for(unsigned i=0; i<args.size(); ++i) {
+     566         176 :     ifile.scanField( "min_" + labels[i], gmin[i]);
+     567         176 :     ifile.scanField( "max_" + labels[i], gmax[i]);
+     568         176 :     ifile.scanField( "periodic_" + labels[i], pstring );
+     569         176 :     ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     570          88 :     plumed_assert( gbin1[i]>0 );
+     571          88 :     if( args[i]->isPeriodic() ) {
+     572          26 :       plumed_massert( pstring=="true", "input value is periodic but grid is not");
+     573             :       std::string pmin, pmax;
+     574          26 :       args[i]->getDomain( pmin, pmax ); gbin[i]=gbin1[i];
+     575          26 :       if( pmin!=gmin[i] || pmax!=gmax[i] ) plumed_merror("mismatch between grid boundaries and periods of values");
+     576             :     } else {
+     577          62 :       gbin[i]=gbin1[i]-1;  // Note header in grid file indicates one more bin that there should be when data is not periodic
+     578          62 :       plumed_massert( pstring=="false", "input value is not periodic but grid is");
+     579             :     }
+     580          88 :     hasder=ifile.FieldExist( "der_" + args[i]->getName() );
+     581          88 :     if( doder && !hasder ) plumed_merror("missing derivatives from grid file");
+     582         106 :     for(unsigned j=0; j<fieldnames.size(); ++j) {
+     583         124 :       for(unsigned k=i+1; k<args.size(); ++k) {
+     584          18 :         if( fieldnames[j]==labels[k] ) plumed_merror("arguments in input are not in same order as in grid file");
+     585             :       }
+     586         106 :       if( fieldnames[j]==labels[i] ) break;
+     587             :     }
+     588             :   }
+     589             : 
+     590          70 :   if(!dosparse) {grid=Tools::make_unique<Grid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     591           0 :   else {grid=Tools::make_unique<SparseGrid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     592             : 
+     593          70 :   std::vector<double> xx(nvar),dder(nvar);
+     594          70 :   std::vector<double> dx=grid->getDx();
+     595             :   double f,x;
+     596     1099575 :   while( ifile.scanField(funcl,f) ) {
+     597     3294553 :     for(unsigned i=0; i<nvar; ++i) {
+     598     2195048 :       ifile.scanField(labels[i],x); xx[i]=x+dx[i]/2.0;
+     599     4390096 :       ifile.scanField( "min_" + labels[i], gmin[i]);
+     600     4390096 :       ifile.scanField( "max_" + labels[i], gmax[i]);
+     601     4390096 :       ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     602     4390096 :       ifile.scanField( "periodic_" + labels[i], pstring );
+     603             :     }
+     604     3211140 :     if(hasder) { for(unsigned i=0; i<nvar; ++i) { ifile.scanField( "der_" + args[i]->getName(), dder[i] ); } }
+     605     1099505 :     index_t index=grid->getIndex(xx);
+     606     1099505 :     if(doder) {grid->setValueAndDerivatives(index,f,dder);}
+     607       42717 :     else {grid->setValue(index,f);}
+     608     1099505 :     ifile.scanField();
+     609             :   }
+     610          70 :   return grid;
+     611          70 : }
+     612             : 
+     613         861 : double Grid::getMinValue() const {
+     614             :   double minval;
+     615             :   minval=DBL_MAX;
+     616     2258311 :   for(index_t i=0; i<grid_.size(); ++i) {
+     617     2257450 :     if(grid_[i]<minval)minval=grid_[i];
+     618             :   }
+     619         861 :   return minval;
+     620             : }
+     621             : 
+     622         629 : double Grid::getMaxValue() const {
+     623             :   double maxval;
+     624             :   maxval=DBL_MIN;
+     625     3755246 :   for(index_t i=0; i<grid_.size(); ++i) {
+     626     3754617 :     if(grid_[i]>maxval)maxval=grid_[i];
+     627             :   }
+     628         629 :   return maxval;
+     629             : }
+     630             : 
+     631         594 : void Grid::scaleAllValuesAndDerivatives( const double& scalef ) {
+     632         594 :   if(usederiv_) {
+     633       21474 :     for(index_t i=0; i<grid_.size(); ++i) {
+     634       21463 :       grid_[i]*=scalef;
+     635       63888 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]*=scalef;
+     636             :     }
+     637             :   } else {
+     638     1572834 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]*=scalef;
+     639             :   }
+     640         594 : }
+     641             : 
+     642           0 : void Grid::logAllValuesAndDerivatives( const double& scalef ) {
+     643           0 :   if(usederiv_) {
+     644           0 :     for(index_t i=0; i<grid_.size(); ++i) {
+     645           0 :       grid_[i] = scalef*std::log(grid_[i]);
+     646           0 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j] = scalef/der_[i*dimension_+j];
+     647             :     }
+     648             :   } else {
+     649           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i] = scalef*std::log(grid_[i]);
+     650             :   }
+     651           0 : }
+     652             : 
+     653        1329 : void Grid::setMinToZero() {
+     654        1329 :   double min=grid_[0];
+     655     3518541 :   for(index_t i=1; i<grid_.size(); ++i) if(grid_[i]<min) min=grid_[i];
+     656     3519870 :   for(index_t i=0; i<grid_.size(); ++i) grid_[i] -= min;
+     657        1329 : }
+     658             : 
+     659           1 : void Grid::applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) ) {
+     660           1 :   if(usederiv_) {
+     661         901 :     for(index_t i=0; i<grid_.size(); ++i) {
+     662         900 :       grid_[i]=func(grid_[i]);
+     663        2700 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]=funcder(der_[i*dimension_+j]);
+     664             :     }
+     665             :   } else {
+     666           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]=func(grid_[i]);
+     667             :   }
+     668           1 : }
+     669             : 
+     670           0 : double Grid::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+     671           0 :   return getValueAndDerivatives( x, der ) - contour_location;
+     672             : }
+     673             : 
+     674           0 : void Grid::findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch,
+     675             :                                     unsigned& npoints, std::vector<std::vector<double> >& points ) {
+     676             : // Set contour location for function
+     677           0 :   contour_location=target;
+     678             : // Resize points to maximum possible value
+     679           0 :   points.resize( dimension_*maxsize_ );
+     680             : 
+     681             : // Two points for search
+     682           0 :   std::vector<unsigned> ind(dimension_);
+     683           0 :   std::vector<double> direction( dimension_, 0 );
+     684             : 
+     685             : // Run over whole grid
+     686           0 :   npoints=0; RootFindingBase<Grid> mymin( this );
+     687           0 :   for(unsigned i=0; i<maxsize_; ++i) {
+     688           0 :     for(unsigned j=0; j<dimension_; ++j) ind[j]=getIndices(i)[j];
+     689             : 
+     690             :     // Get the value of a point on the grid
+     691           0 :     double val1=getValue(i) - target;
+     692             : 
+     693             :     // Now search for contour in each direction
+     694             :     bool edge=false;
+     695           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     696           0 :       if( nosearch[j] ) continue ;
+     697             :       // Make sure we don't search at the edge of the grid
+     698           0 :       if( !pbc_[j] && (ind[j]+1)==nbin_[j] ) continue;
+     699           0 :       else if( (ind[j]+1)==nbin_[j] ) { edge=true; ind[j]=0; }
+     700           0 :       else ind[j]+=1;
+     701           0 :       double val2=getValue(ind) - target;
+     702           0 :       if( val1*val2<0 ) {
+     703             :         // Use initial point location as first guess for search
+     704           0 :         points[npoints].resize(dimension_); for(unsigned k=0; k<dimension_; ++k) points[npoints][k]=getPoint(i)[k];
+     705             :         // Setup direction vector
+     706           0 :         direction[j]=0.999999999*dx_[j];
+     707             :         // And do proper search for contour point
+     708           0 :         mymin.linesearch( direction, points[npoints], &Grid::getDifferenceFromContour );
+     709           0 :         direction[j]=0.0; npoints++;
+     710             :       }
+     711           0 :       if( pbc_[j] && edge ) { edge=false; ind[j]=nbin_[j]-1; }
+     712           0 :       else ind[j]-=1;
+     713             :     }
+     714             :   }
+     715           0 : }
+     716             : 
+     717             : /// OVERRIDES ARE BELOW
+     718             : 
+     719    28865222 : Grid::index_t Grid::getSize() const {
+     720    28865222 :   return maxsize_;
+     721             : }
+     722             : 
+     723    27284983 : double Grid::getValue(index_t index) const {
+     724             :   plumed_dbg_assert(index<maxsize_);
+     725    27284983 :   return grid_[index];
+     726             : }
+     727             : 
+     728     3079776 : double Grid::getValueAndDerivatives(index_t index, std::vector<double>& der) const {
+     729             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     730     3079776 :   der.resize(dimension_);
+     731     6679531 :   for(unsigned i=0; i<dimension_; i++) der[i]=der_[dimension_*index+i];
+     732     3079776 :   return grid_[index];
+     733             : }
+     734             : 
+     735     6444104 : void Grid::setValue(index_t index, double value) {
+     736             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     737     6444104 :   grid_[index]=value;
+     738     6444104 : }
+     739             : 
+     740     2552369 : void Grid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     741             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     742     2552369 :   grid_[index]=value;
+     743     7609163 :   for(unsigned i=0; i<dimension_; i++) der_[dimension_*index+i]=der[i];
+     744     2552369 : }
+     745             : 
+     746           1 : void Grid::addValue(index_t index, double value) {
+     747             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     748           1 :   grid_[index]+=value;
+     749           1 : }
+     750             : 
+     751     1171742 : void Grid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     752             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     753     1171742 :   grid_[index]+=value;
+     754     3500479 :   for(unsigned int i=0; i<dimension_; ++i) der_[index*dimension_+i]+=der[i];
+     755     1171742 : }
+     756             : 
+     757           0 : Grid::index_t SparseGrid::getSize() const {
+     758           0 :   return map_.size();
+     759             : }
+     760             : 
+     761           0 : Grid::index_t SparseGrid::getMaxSize() const {
+     762           0 :   return maxsize_;
+     763             : }
+     764             : 
+     765           0 : double SparseGrid::getValue(index_t index)const {
+     766           0 :   plumed_assert(index<maxsize_);
+     767             :   double value=0.0;
+     768             :   const auto it=map_.find(index);
+     769           0 :   if(it!=map_.end()) value=it->second;
+     770           0 :   return value;
+     771             : }
+     772             : 
+     773         200 : double SparseGrid::getValueAndDerivatives(index_t index, std::vector<double>& der)const {
+     774         200 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     775             :   double value=0.0;
+     776         580 :   for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     777             :   const auto it=map_.find(index);
+     778         200 :   if(it!=map_.end()) value=it->second;
+     779             :   const auto itder=der_.find(index);
+     780         200 :   if(itder!=der_.end()) der=itder->second;
+     781         200 :   return value;
+     782             : }
+     783             : 
+     784           0 : void SparseGrid::setValue(index_t index, double value) {
+     785           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     786           0 :   map_[index]=value;
+     787           0 : }
+     788             : 
+     789           0 : void SparseGrid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     790           0 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     791           0 :   map_[index]=value;
+     792           0 :   der_[index]=der;
+     793           0 : }
+     794             : 
+     795           0 : void SparseGrid::addValue(index_t index, double value) {
+     796           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     797           0 :   map_[index]+=value;
+     798           0 : }
+     799             : 
+     800       19999 : void SparseGrid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     801       19999 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     802       19999 :   map_[index]+=value;
+     803       19999 :   der_[index].resize(dimension_);
+     804       59682 :   for(unsigned int i=0; i<dimension_; ++i) der_[index][i]+=der[i];
+     805       19999 : }
+     806             : 
+     807           0 : void SparseGrid::writeToFile(OFile& ofile) {
+     808           0 :   std::vector<double> xx(dimension_);
+     809           0 :   std::vector<double> der(dimension_);
+     810             :   double f;
+     811           0 :   writeHeader(ofile);
+     812           0 :   ofile.fmtField(" "+fmt_);
+     813           0 :   for(const auto & it : map_) {
+     814           0 :     index_t i=it.first;
+     815           0 :     xx=getPoint(i);
+     816           0 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     817           0 :     else {f=getValue(i);}
+     818           0 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     819           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     820           0 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     821           0 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     822           0 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     823           0 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     824           0 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     825             :     }
+     826           0 :     for(unsigned j=0; j<dimension_; ++j) ofile.printField(argnames[j],xx[j]);
+     827           0 :     ofile.printField(funcname, f);
+     828           0 :     if(usederiv_) { for(unsigned j=0; j<dimension_; ++j) ofile.printField("der_" + argnames[j],der[j]); }
+     829           0 :     ofile.printField();
+     830             :   }
+     831           0 : }
+     832             : 
+     833           0 : double SparseGrid::getMinValue() const {
+     834             :   double minval;
+     835             :   minval=0.0;
+     836           0 :   for(auto const & i : map_) {
+     837           0 :     if(i.second<minval) minval=i.second;
+     838             :   }
+     839           0 :   return minval;
+     840             : }
+     841             : 
+     842           9 : double SparseGrid::getMaxValue() const {
+     843             :   double maxval;
+     844             :   maxval=0.0;
+     845         590 :   for(auto const & i : map_) {
+     846         581 :     if(i.second>maxval) maxval=i.second;
+     847             :   }
+     848           9 :   return maxval;
+     849             : }
+     850             : 
+     851     1010062 : void Grid::projectOnLowDimension(double &val, std::vector<int> &vHigh, WeightBase * ptr2obj ) {
+     852             :   unsigned i=0;
+     853     3016945 :   for(i=0; i<vHigh.size(); i++) {
+     854     2015726 :     if(vHigh[i]<0) { // this bin needs to be integrated out
+     855             :       // parallelize here???
+     856     1010062 :       for(unsigned j=0; j<(getNbin())[i]; j++) {
+     857     1001219 :         vHigh[i]=int(j);
+     858     1001219 :         projectOnLowDimension(val,vHigh,ptr2obj); // recursive function: this is the core of the mechanism
+     859     1001219 :         vHigh[i]=-1;
+     860             :       }
+     861             :       return; //
+     862             :     }
+     863             :   }
+     864             :   // when there are no more bin to dig in then retrieve the value
+     865     1001219 :   if(i==vHigh.size()) {
+     866             :     //std::cerr<<"POINT: ";
+     867             :     //for(unsigned j=0;j<vHigh.size();j++){
+     868             :     //   std::cerr<<vHigh[j]<<" ";
+     869             :     //}
+     870     1001219 :     std::vector<unsigned> vv(vHigh.size());
+     871     3003657 :     for(unsigned j=0; j<vHigh.size(); j++)vv[j]=unsigned(vHigh[j]);
+     872             :     //
+     873             :     // this is the real assignment !!!!! (hack this to have bias or other stuff)
+     874             :     //
+     875             : 
+     876             :     // this case: produce fes
+     877             :     //val+=exp(beta*getValue(vv)) ;
+     878     1001219 :     double myv=getValue(vv);
+     879     1001219 :     val=ptr2obj->projectInnerLoop(val,myv) ;
+     880             :     // to be added: bias (same as before without negative sign)
+     881             :     //std::cerr<<" VAL: "<<val <<endl;
+     882             :   }
+     883             : }
+     884             : 
+     885          81 : Grid Grid::project(const std::vector<std::string> & proj, WeightBase *ptr2obj ) {
+     886             :   // find extrema only for the projection
+     887             :   std::vector<std::string>   smallMin,smallMax;
+     888             :   std::vector<unsigned> smallBin;
+     889             :   std::vector<unsigned> dimMapping;
+     890             :   std::vector<bool> smallIsPeriodic;
+     891             :   std::vector<std::string> smallName;
+     892             : 
+     893             :   // check if the two key methods are there
+     894             :   WeightBase* pp = dynamic_cast<WeightBase*>(ptr2obj);
+     895          81 :   if (!pp)plumed_merror("This WeightBase is not complete: you need a projectInnerLoop and projectOuterLoop ");
+     896             : 
+     897         162 :   for(unsigned j=0; j<proj.size(); j++) {
+     898         120 :     for(unsigned i=0; i<getArgNames().size(); i++) {
+     899         120 :       if(proj[j]==getArgNames()[i]) {
+     900             :         unsigned offset;
+     901             :         // note that at sizetime the non periodic dimension get a bin more
+     902         162 :         if(getIsPeriodic()[i]) {offset=0;} else {offset=1;}
+     903          81 :         smallMax.push_back(getMax()[i]);
+     904          81 :         smallMin.push_back(getMin()[i]);
+     905          81 :         smallBin.push_back(getNbin()[i]-offset);
+     906         162 :         smallIsPeriodic.push_back(getIsPeriodic()[i]);
+     907          81 :         dimMapping.push_back(i);
+     908          81 :         smallName.push_back(getArgNames()[i]);
+     909          81 :         break;
+     910             :       }
+     911             :     }
+     912             :   }
+     913          81 :   Grid smallgrid("projection",smallName,smallMin,smallMax,smallBin,false,false,smallIsPeriodic,smallMin,smallMax);
+     914             :   // check that the two grids are commensurate
+     915         162 :   for(unsigned i=0; i<dimMapping.size(); i++) {
+     916          81 :     plumed_massert(  (smallgrid.getMax())[i] == (getMax())[dimMapping[i]],  "the two input grids are not compatible in max"   );
+     917          81 :     plumed_massert(  (smallgrid.getMin())[i] == (getMin())[dimMapping[i]],  "the two input grids are not compatible in min"   );
+     918          81 :     plumed_massert(  (smallgrid.getNbin())[i]== (getNbin())[dimMapping[i]], "the two input grids are not compatible in bin"   );
+     919             :   }
+     920             :   std::vector<unsigned> toBeIntegrated;
+     921         243 :   for(unsigned i=0; i<getArgNames().size(); i++) {
+     922             :     bool doappend=true;
+     923         243 :     for(unsigned j=0; j<dimMapping.size(); j++) {
+     924         162 :       if(dimMapping[j]==i) {doappend=false; break;}
+     925             :     }
+     926         162 :     if(doappend)toBeIntegrated.push_back(i);
+     927             :   }
+     928             : 
+     929             :   // loop over all the points in the Grid, find the corresponding fixed index, rotate over all the other ones
+     930        8924 :   for(unsigned i=0; i<smallgrid.getSize(); i++) {
+     931             :     std::vector<unsigned> v;
+     932        8843 :     v=smallgrid.getIndices(i);
+     933        8843 :     std::vector<int> vHigh((getArgNames()).size(),-1);
+     934       17686 :     for(unsigned j=0; j<dimMapping.size(); j++)vHigh[dimMapping[j]]=int(v[j]);
+     935             :     // the vector vhigh now contains at the beginning the index of the low dimension and -1 for the values that need to be integrated
+     936        8843 :     double initval=0.;
+     937        8843 :     projectOnLowDimension(initval,vHigh, ptr2obj);
+     938        8843 :     smallgrid.setValue(i,ptr2obj->projectOuterLoop(initval));
+     939             :   }
+     940             : 
+     941          81 :   return smallgrid;
+     942         162 : }
+     943             : 
+     944           0 : double Grid::integrate( std::vector<unsigned>& npoints ) {
+     945           0 :   plumed_dbg_assert( npoints.size()==dimension_ ); plumed_assert( dospline_ );
+     946             : 
+     947             :   unsigned ntotgrid=1; double box_vol=1.0;
+     948           0 :   std::vector<double> ispacing( npoints.size() );
+     949           0 :   for(unsigned j=0; j<dimension_; ++j) {
+     950           0 :     if( !pbc_[j] ) {
+     951           0 :       ispacing[j] = ( max_[j] - dx_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     952           0 :       npoints[j]+=1;
+     953             :     } else {
+     954           0 :       ispacing[j] = ( max_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     955             :     }
+     956           0 :     ntotgrid*=npoints[j]; box_vol*=ispacing[j];
+     957             :   }
+     958             : 
+     959           0 :   std::vector<double> vals( dimension_ );
+     960           0 :   std::vector<unsigned> t_index( dimension_ ); double integral=0.0;
+     961           0 :   for(unsigned i=0; i<ntotgrid; ++i) {
+     962           0 :     t_index[0]=(i%npoints[0]);
+     963             :     unsigned kk=i;
+     964           0 :     for(unsigned j=1; j<dimension_-1; ++j) { kk=(kk-t_index[j-1])/npoints[j-1]; t_index[j]=(kk%npoints[j]); }
+     965           0 :     if( dimension_>=2 ) t_index[dimension_-1]=((kk-t_index[dimension_-2])/npoints[dimension_-2]);
+     966             : 
+     967           0 :     for(unsigned j=0; j<dimension_; ++j) vals[j]=min_[j] + t_index[j]*ispacing[j];
+     968             : 
+     969           0 :     integral += getValue( vals );
+     970             :   }
+     971             : 
+     972           0 :   return box_vol*integral;
+     973             : }
+     974             : 
+     975           0 : void Grid::mpiSumValuesAndDerivatives( Communicator& comm ) {
+     976           0 :   comm.Sum( grid_ ); for(unsigned i=0; i<der_.size(); ++i) comm.Sum( der_[i] );
+     977           0 : }
+     978             : 
+     979             : 
+     980       59573 : bool indexed_lt(std::pair<Grid::index_t, double> const &x, std::pair<Grid::index_t, double> const   &y) {
+     981       59573 :   return x.second < y.second;
+     982             : }
+     983             : 
+     984         273 : double GridBase::findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink) {
+     985             :   plumed_dbg_assert(source.size() == dimension_);
+     986             :   plumed_dbg_assert(sink.size() == dimension_);
+     987             :   // Start and end indices
+     988         273 :   index_t source_idx = getIndex(source);
+     989         273 :   index_t sink_idx = getIndex(sink);
+     990             :   // Path cost
+     991             :   double maximal_minimum = 0;
+     992             :   // In one dimension, path searching is very easy--either go one way if it's not periodic,
+     993             :   // or go both ways if it is periodic. There's no reason to pay the cost of Dijkstra.
+     994         273 :   if (dimension_ == 1) {
+     995             :     // Do a search from the grid source to grid sink that does not
+     996             :     // cross the grid boundary.
+     997         147 :     double curr_min_bias = getValue(source_idx);
+     998             :     // Either search from a high source to a low sink.
+     999         147 :     if (source_idx > sink_idx) {
+    1000         735 :       for (index_t i = source_idx; i >= sink_idx; i--) {
+    1001         588 :         if (curr_min_bias == 0.0) {
+    1002             :           break;
+    1003             :         }
+    1004         588 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1005             :       }
+    1006             :       // Or search from a low source to a high sink.
+    1007           0 :     } else if (source_idx < sink_idx) {
+    1008           0 :       for (index_t i = source_idx; i <= sink_idx; i++) {
+    1009           0 :         if (curr_min_bias == 0.0) {
+    1010             :           break;
+    1011             :         }
+    1012           0 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1013             :       }
+    1014             :     }
+    1015             :     maximal_minimum = curr_min_bias;
+    1016             :     // If the grid is periodic, also do the search that crosses
+    1017             :     // the grid boundary.
+    1018         147 :     if (pbc_[0]) {
+    1019          42 :       double curr_min_bias = getValue(source_idx);
+    1020             :       // Either go from a high source to the upper boundary and
+    1021             :       // then from the bottom boundary to the sink
+    1022          42 :       if (source_idx > sink_idx) {
+    1023         210 :         for (index_t i = source_idx; i < maxsize_; i++) {
+    1024         168 :           if (curr_min_bias == 0.0) {
+    1025             :             break;
+    1026             :           }
+    1027         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1028             :         }
+    1029         210 :         for (index_t i = 0; i <= sink_idx; i++) {
+    1030         168 :           if (curr_min_bias == 0.0) {
+    1031             :             break;
+    1032             :           }
+    1033         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1034             :         }
+    1035             :         // Or go from a low source to the bottom boundary and
+    1036             :         // then from the high boundary to the sink
+    1037           0 :       } else if (source_idx < sink_idx) {
+    1038           0 :         for (index_t i = source_idx; i > 0; i--) {
+    1039           0 :           if (curr_min_bias == 0.0) {
+    1040             :             break;
+    1041             :           }
+    1042           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1043             :         }
+    1044           0 :         curr_min_bias = fmin(curr_min_bias, getValue(0));
+    1045           0 :         for (index_t i = maxsize_ - 1; i <= sink_idx; i--) {
+    1046           0 :           if (curr_min_bias == 0.0) {
+    1047             :             break;
+    1048             :           }
+    1049           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1050             :         }
+    1051             :       }
+    1052             :       // If the boundary crossing paths was more biased, it's
+    1053             :       // minimal bias replaces the non-boundary-crossing path's
+    1054             :       // minimum.
+    1055          42 :       maximal_minimum = fmax(maximal_minimum, curr_min_bias);
+    1056             :     }
+    1057             :     // The one dimensional path search is complete.
+    1058         147 :     return maximal_minimum;
+    1059             :     // In two or more dimensions, path searching isn't trivial and we really
+    1060             :     // do need to use a path search algorithm. Dijkstra is the simplest decent
+    1061             :     // one. Using it we've never found the path search to be performance
+    1062             :     // limiting in any solvated biomolecule test system, but faster options are
+    1063             :     // easy to imagine if they become necessary. NB-In this case, we're actually
+    1064             :     // using a greedy variant of Dijkstra's algorithm where the first possible
+    1065             :     // path to a point always controls the path cost to that point. The structure
+    1066             :     // of the cost function in this case guarantees that the calculated costs will
+    1067             :     // be correct using this variant even though fine details of the paths may not
+    1068             :     // match a normal Dijkstra search.
+    1069         126 :   } else if (dimension_ > 1) {
+    1070             :     // Prepare calculation temporaries for Dijkstra's algorithm.
+    1071             :     // Minimal path costs from source to a given grid point
+    1072         126 :     std::vector<double> mins_from_source = std::vector<double>(maxsize_, -1.0);
+    1073             :     // Heap for tracking available steps, steps are recorded as std::pairs of
+    1074             :     // an index and a value.
+    1075             :     std::vector< std::pair<index_t, double> > next_steps;
+    1076             :     std::pair<index_t, double> curr_indexed_val;
+    1077         126 :     std::make_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1078             :     // The search begins at the source index.
+    1079         252 :     next_steps.push_back(std::pair<index_t, double>(source_idx, getValue(source_idx)));
+    1080         126 :     std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1081             :     // At first no points have been examined and the optimal path has not been found.
+    1082             :     index_t n_examined = 0;
+    1083             :     bool path_not_found = true;
+    1084             :     // Until a path is found,
+    1085             :     while (path_not_found) {
+    1086             :       // Examine the grid point currently most accessible from
+    1087             :       // the set of all previously explored grid points by popping
+    1088             :       // it from the top of the heap.
+    1089        9702 :       std::pop_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1090             :       curr_indexed_val = next_steps.back();
+    1091             :       next_steps.pop_back();
+    1092             :       n_examined++;
+    1093             :       // Check if this point is the sink point, and if so
+    1094             :       // finish the loop.
+    1095        9702 :       if (curr_indexed_val.first == sink_idx) {
+    1096             :         path_not_found = false;
+    1097             :         maximal_minimum = curr_indexed_val.second;
+    1098         126 :         break;
+    1099             :         // Check if this point has reached the worst possible
+    1100             :         // value, and if so stop looking for paths.
+    1101        9576 :       } else if (curr_indexed_val.second == 0.0) {
+    1102             :         maximal_minimum = 0.0;
+    1103             :         break;
+    1104             :       }
+    1105             :       // If the search is not over, add this grid point's neighbors to the
+    1106             :       // possible next points to search for the sink.
+    1107        9576 :       std::vector<index_t> neighs = getNearestNeighbors(curr_indexed_val.first);
+    1108       46246 :       for (unsigned k = 0; k < neighs.size(); k++) {
+    1109       36670 :         index_t i = neighs[k];
+    1110             :         // If the neighbor has not already been added to the list of possible next steps,
+    1111       36670 :         if (mins_from_source[i] == -1.0) {
+    1112             :           // Set the cost to reach it via a path through the current point being examined.
+    1113       12284 :           mins_from_source[i] = fmin(curr_indexed_val.second, getValue(i));
+    1114             :           // Add the neighboring point to the heap of potential next steps.
+    1115       12284 :           next_steps.push_back(std::pair<index_t, double>(i, mins_from_source[i]));
+    1116       12284 :           std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1117             :         }
+    1118             :       }
+    1119             :       // Move on to the next best looking step along any of the paths
+    1120             :       // growing from the source.
+    1121             :     }
+    1122             :     // The multidimensional path search is now complete.
+    1123             :     return maximal_minimum;
+    1124             :   }
+    1125             :   return 0.0;
+    1126             : }
+    1127             : 
+    1128             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func-sort-c.html b/coverage/tools/Grid.h.func-sort-c.html new file mode 100644 index 0000000000..57d03d31eb --- /dev/null +++ b/coverage/tools/Grid.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_IjSaIjEEbb1321
_ZN4PLMD8GridBaseD2Ev1504
_ZN4PLMD10BiasWeight16projectInnerLoopERdS1_13603
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func.html b/coverage/tools/Grid.h.func.html new file mode 100644 index 0000000000..30bf22b34f --- /dev/null +++ b/coverage/tools/Grid.h.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_IjSaIjEEbb1321
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZN4PLMD8GridBaseD0Ev0
_ZN4PLMD8GridBaseD2Ev1504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.gcov.html b/coverage/tools/Grid.h.gcov.html new file mode 100644 index 0000000000..8f2932c7dc --- /dev/null +++ b/coverage/tools/Grid.h.gcov.html @@ -0,0 +1,431 @@ + + + + + + + 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-05-27 13:05: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        3008 :   virtual ~GridBase() {}
+     219             : 
+     220             : /// set output format
+     221         197 :   void setOutputFmt(const std::string & ss) {fmt_=ss;}
+     222             : /// reset output format to the default %14.9f format
+     223             :   void resetToDefaultOutputFmt() {fmt_="%14.9f";}
+     224             : ///
+     225             : /// Find the maximum over paths of the minimum value of the gridded function along the paths
+     226             : /// for all paths of neighboring grid lattice points from a source point to a sink point.
+     227             :   double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
+     228             : };
+     229             : 
+     230             : class Grid : public GridBase
+     231             : {
+     232             :   std::vector<double> grid_;
+     233             :   std::vector<double> der_;
+     234             :   double contour_location=0.0;
+     235             : public:
+     236        1321 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     237             :        const std::vector<std::string> & gmax,
+     238        1321 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     239        1321 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
+     240             :   {
+     241        1321 :     grid_.assign(maxsize_,0.0);
+     242        1321 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     243        1321 :   }
+     244             : /// this constructor here is not Value-aware
+     245         128 :   Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     246             :        const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     247             :        bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
+     248         128 :        const std::vector<std::string> &pmax ):
+     249         128 :     GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
+     250             :   {
+     251         128 :     grid_.assign(maxsize_,0.0);
+     252         128 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     253         128 :   }
+     254             :   index_t getSize() const override;
+     255             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     256             :   using GridBase::getValue;
+     257             :   using GridBase::getValueAndDerivatives;
+     258             :   using GridBase::setValue;
+     259             :   using GridBase::setValueAndDerivatives;
+     260             :   using GridBase::addValue;
+     261             :   using GridBase::addValueAndDerivatives;
+     262             : /// get grid value
+     263             :   double getValue(index_t index) const override;
+     264             : /// get grid value and derivatives
+     265             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
+     266             : 
+     267             : /// set grid value
+     268             :   void setValue(index_t index, double value) override;
+     269             : /// set grid value and derivatives
+     270             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     271             : /// add to grid value
+     272             :   void addValue(index_t index, double value) override;
+     273             : /// add to grid value and derivatives
+     274             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     275             : 
+     276             : /// get minimum value
+     277             :   double getMinValue() const override;
+     278             : /// get maximum value
+     279             :   double getMaxValue() const override;
+     280             : /// Scale all grid values and derivatives by a constant factor
+     281             :   void scaleAllValuesAndDerivatives( const double& scalef );
+     282             : /// Takes the scalef times the logarithm of all grid values and derivatives
+     283             :   void logAllValuesAndDerivatives( const double& scalef );
+     284             : /// dump grid on file
+     285             :   void writeToFile(OFile&) override;
+     286             : 
+     287             : /// Set the minimum value of the grid to zero and translates accordingly
+     288             :   void setMinToZero();
+     289             : /// apply function: takes  pointer to  function that accepts a double and apply
+     290             :   void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
+     291             : /// Get the difference from the contour
+     292             :   double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
+     293             : /// Find a set of points on a contour in the function
+     294             :   void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
+     295             : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
+     296             : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
+     297             : /// to enable many types of weighting
+     298             :   Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj  );
+     299             :   void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
+     300             :   void mpiSumValuesAndDerivatives( Communicator& comm );
+     301             : /// Integrate the function calculated on the grid
+     302             :   double integrate( std::vector<unsigned>& npoints );
+     303             :   void clear();
+     304             : };
+     305             : 
+     306             : 
+     307             : class SparseGrid : public GridBase
+     308             : {
+     309             : 
+     310             :   std::map<index_t,double> map_;
+     311             :   std::map< index_t,std::vector<double> > der_;
+     312             : 
+     313             : public:
+     314           6 :   SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     315             :              const std::vector<std::string> & gmax,
+     316           6 :              const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     317           6 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
+     318             : 
+     319             :   index_t getSize() const override;
+     320             :   index_t getMaxSize() const;
+     321             : 
+     322             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     323             :   using GridBase::getValue;
+     324             :   using GridBase::getValueAndDerivatives;
+     325             :   using GridBase::setValue;
+     326             :   using GridBase::setValueAndDerivatives;
+     327             :   using GridBase::addValue;
+     328             :   using GridBase::addValueAndDerivatives;
+     329             : 
+     330             : /// get grid value
+     331             :   double getValue(index_t index) const override;
+     332             : /// get grid value and derivatives
+     333             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
+     334             : 
+     335             : /// set grid value
+     336             :   void setValue(index_t index, double value) override;
+     337             : /// set grid value and derivatives
+     338             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     339             : /// add to grid value
+     340             :   void addValue(index_t index, double value) override;
+     341             : /// add to grid value and derivatives
+     342             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     343             : 
+     344             : /// get minimum value
+     345             :   double getMinValue() const override;
+     346             : /// get maximum value
+     347             :   double getMaxValue() const override;
+     348             : /// dump grid on file
+     349             :   void writeToFile(OFile&) override;
+     350             : 
+     351          18 :   virtual ~SparseGrid() {}
+     352             : };
+     353             : }
+     354             : 
+     355             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func-sort-c.html b/coverage/tools/HistogramBead.cpp.func-sort-c.html new file mode 100644 index 0000000000..f4ee5bdbff --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func.html b/coverage/tools/HistogramBead.cpp.func.html new file mode 100644 index 0000000000..b6d834dc19 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.gcov.html b/coverage/tools/HistogramBead.cpp.gcov.html new file mode 100644 index 0000000000..f4042cb288 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func-sort-c.html b/coverage/tools/HistogramBead.h.func-sort-c.html new file mode 100644 index 0000000000..17cdb178b3 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func.html b/coverage/tools/HistogramBead.h.func.html new file mode 100644 index 0000000000..579acf1565 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.gcov.html b/coverage/tools/HistogramBead.h.gcov.html new file mode 100644 index 0000000000..043b3ebf75 --- /dev/null +++ b/coverage/tools/HistogramBead.h.gcov.html @@ -0,0 +1,190 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func-sort-c.html b/coverage/tools/IFile.cpp.func-sort-c.html new file mode 100644 index 0000000000..8b5fd8f8a3 --- /dev/null +++ b/coverage/tools/IFile.cpp.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-05-27 13:05:14Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD2Ev0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFileD0Ev348
_ZN4PLMD5IFile10allowNoEOLEv884
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1320
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFileC1Ev11584
_ZN4PLMD5IFileD1Ev11584
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1102484
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1140349
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1140446
_ZN4PLMD5IFile9scanFieldEv1319650
_ZN4PLMD5IFile12advanceFieldEv1326058
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1471078
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7012150
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15852959
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15859294
_ZN4PLMD5IFile6llreadEPcm100050540
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func.html b/coverage/tools/IFile.cpp.func.html new file mode 100644 index 0000000000..132ca5a498 --- /dev/null +++ b/coverage/tools/IFile.cpp.func.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-05-27 13:05:14Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1140349
_ZN4PLMD5IFile10allowNoEOLEv884
_ZN4PLMD5IFile12advanceFieldEv1326058
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1140446
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1320
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFile6llreadEPcm100050540
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1471078
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1102484
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15859294
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7012150
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldEv1319650
_ZN4PLMD5IFileC1Ev11584
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD0Ev348
_ZN4PLMD5IFileD1Ev11584
_ZN4PLMD5IFileD2Ev0
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15852959
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.gcov.html b/coverage/tools/IFile.cpp.gcov.html new file mode 100644 index 0000000000..1fb874044d --- /dev/null +++ b/coverage/tools/IFile.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-05-27 13:05:14Functions:222588.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "IFile.h"
+      23             : #include "Exception.h"
+      24             : #include "core/Action.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "Communicator.h"
+      28             : #include "Tools.h"
+      29             : #include <cstdarg>
+      30             : #include <cstring>
+      31             : #include <cmath>
+      32             : 
+      33             : #include <iostream>
+      34             : #include <string>
+      35             : #ifdef __PLUMED_HAS_ZLIB
+      36             : #include <zlib.h>
+      37             : #endif
+      38             : 
+      39             : namespace PLMD {
+      40             : 
+      41   100050540 : size_t IFile::llread(char*ptr,size_t s) {
+      42   100050540 :   plumed_assert(fp);
+      43             :   size_t r;
+      44   100050540 :   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   100047018 :     if(std::feof(fp))   eof=true;
+      56   100047018 :     if(std::ferror(fp)) err=true;
+      57             :   }
+      58   100050540 :   return r;
+      59             : }
+      60             : 
+      61     1326058 : IFile& IFile::advanceField() {
+      62     1326058 :   plumed_assert(!inMiddleOfField);
+      63             :   std::string line;
+      64             :   bool done=false;
+      65     2653929 :   while(!done) {
+      66     1334282 :     getline(line);
+      67             : // using explicit conversion not to confuse cppcheck 1.86
+      68     1334282 :     if(!bool(*this)) {return *this;}
+      69     1327871 :     std::vector<std::string> words=Tools::getWords(line);
+      70     2655503 :     if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS") {
+      71         713 :       fields.clear();
+      72        4730 :       for(unsigned i=2; i<words.size(); i++) {
+      73             :         Field field;
+      74             :         field.name=words[i];
+      75        4017 :         fields.push_back(field);
+      76             :       }
+      77     1348842 :     } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET") {
+      78             :       Field field;
+      79             :       field.name=words[2];
+      80             :       field.value=words[3];
+      81        3256 :       field.constant=true;
+      82        3256 :       fields.push_back(field);
+      83             :     } else {
+      84             :       unsigned nf=0;
+      85    17104553 :       for(unsigned i=0; i<fields.size(); i++) if(!fields[i].constant) nf++;
+      86     1323902 :       Tools::trimComments(line);
+      87     2647804 :       words=Tools::getWords(line);
+      88     1323902 :       if( words.size()==nf ) {
+      89             :         unsigned j=0;
+      90    17049941 :         for(unsigned i=0; i<fields.size(); i++) {
+      91    15730294 :           if(fields[i].constant) continue;
+      92     6862973 :           fields[i].value=words[j];
+      93     6862973 :           fields[i].read=false;
+      94     6862973 :           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     1327871 :   }
+     102     1319647 :   inMiddleOfField=true;
+     103     1319647 :   return *this;
+     104             : }
+     105             : 
+     106        1320 : IFile& IFile::open(const std::string&path) {
+     107        1320 :   plumed_massert(!cloned,"file "+path+" appears to be cloned");
+     108        1320 :   eof=false;
+     109        1320 :   err=false;
+     110        1320 :   fp=NULL;
+     111        1320 :   gzfp=NULL;
+     112        1320 :   bool do_exist=FileExist(path);
+     113        1322 :   plumed_massert(do_exist,"file " + path + " cannot be found");
+     114        1319 :   fp=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+     115        2638 :   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        1319 :   if(plumed) plumed->insertFile(*this);
+     123        1319 :   return *this;
+     124             : }
+     125             : 
+     126     1140446 : IFile& IFile::scanFieldList(std::vector<std::string>&s) {
+     127     1140446 :   if(!inMiddleOfField) advanceField();
+     128             : // using explicit conversion not to confuse cppcheck 1.86
+     129     1140446 :   if(!bool(*this)) return *this;
+     130             :   s.clear();
+     131     9214087 :   for(unsigned i=0; i<fields.size(); i++)
+     132     8073717 :     s.push_back(fields[i].name);
+     133             :   return *this;
+     134             : }
+     135             : 
+     136     1140349 : bool IFile::FieldExist(const std::string& s) {
+     137             :   std::vector<std::string> slist;
+     138     1140349 :   scanFieldList(slist);
+     139     1140349 :   int mycount = (int) std::count(slist.begin(), slist.end(), s);
+     140     1140349 :   if(mycount>0) return true;
+     141     1116301 :   else return false;
+     142     1140349 : }
+     143             : 
+     144    15859294 : IFile& IFile::scanField(const std::string&name,std::string&str) {
+     145    15859294 :   if(!inMiddleOfField) advanceField();
+     146             : // using explicit conversion not to confuse cppcheck 1.86
+     147    15859294 :   if(!bool(*this)) return *this;
+     148    15852959 :   unsigned i=findField(name);
+     149    15852959 :   str=fields[i].value;
+     150    15852959 :   fields[i].read=true;
+     151    15852959 :   return *this;
+     152             : }
+     153             : 
+     154     7012150 : IFile& IFile::scanField(const std::string&name,double &x) {
+     155             :   std::string str;
+     156     7012150 :   scanField(name,str);
+     157     7012150 :   if(*this) Tools::convert(str,x);
+     158     7012150 :   return *this;
+     159             : }
+     160             : 
+     161     2213283 : IFile& IFile::scanField(const std::string&name,int &x) {
+     162             :   std::string str;
+     163     2213283 :   scanField(name,str);
+     164     2213283 :   if(*this) Tools::convert(str,x);
+     165     2213283 :   return *this;
+     166             : }
+     167             : 
+     168           1 : IFile& IFile::scanField(const std::string&name,long int &x) {
+     169             :   std::string str;
+     170           1 :   scanField(name,str);
+     171           1 :   if(*this) Tools::convert(str,x);
+     172           1 :   return *this;
+     173             : }
+     174             : 
+     175           0 : IFile& IFile::scanField(const std::string&name,long long int &x) {
+     176             :   std::string str;
+     177           0 :   scanField(name,str);
+     178           0 :   if(*this) Tools::convert(str,x);
+     179           0 :   return *this;
+     180             : }
+     181             : 
+     182          17 : IFile& IFile::scanField(const std::string&name,unsigned &x) {
+     183             :   std::string str;
+     184          17 :   scanField(name,str);
+     185          17 :   if(*this) Tools::convert(str,x);
+     186          17 :   return *this;
+     187             : }
+     188             : 
+     189           1 : IFile& IFile::scanField(const std::string&name,long unsigned &x) {
+     190             :   std::string str;
+     191           1 :   scanField(name,str);
+     192           1 :   if(*this) Tools::convert(str,x);
+     193           1 :   return *this;
+     194             : }
+     195             : 
+     196          14 : IFile& IFile::scanField(const std::string&name,long long unsigned &x) {
+     197             :   std::string str;
+     198          14 :   scanField(name,str);
+     199          14 :   if(*this) Tools::convert(str,x);
+     200          14 :   return *this;
+     201             : }
+     202             : 
+     203     1102484 : IFile& IFile::scanField(Value* val) {
+     204     1102484 :   double ff=std::numeric_limits<double>::quiet_NaN(); // this is to be sure a NaN value is replaced upon failure
+     205     1102484 :   scanField(  val->getName(), ff );
+     206     1102484 :   val->set( ff );
+     207     2204968 :   if( FieldExist("min_" + val->getName() ) ) {
+     208             :     std::string min, max;
+     209        3309 :     scanField("min_" + val->getName(), min );
+     210        3309 :     scanField("max_" + val->getName(), max );
+     211        3309 :     val->setDomain( min, max );
+     212             :   } else {
+     213     1099175 :     val->setNotPeriodic();
+     214             :   }
+     215     1102484 :   return *this;
+     216             : }
+     217             : 
+     218     1319650 : IFile& IFile::scanField() {
+     219     1319650 :   if(!ignoreFields) {
+     220    15347585 :     for(unsigned i=0; i<fields.size(); i++) {
+     221    14242508 :       plumed_massert(fields[i].read,"field "+fields[i].name+" was not read: all the fields need to be read otherwise you could miss important infos" );
+     222             :     }
+     223             :   }
+     224     1319650 :   inMiddleOfField=false;
+     225     1319650 :   return *this;
+     226             : }
+     227             : 
+     228       11584 : IFile::IFile():
+     229       11584 :   inMiddleOfField(false),
+     230       11584 :   ignoreFields(false),
+     231       11584 :   noEOL(false)
+     232             : {
+     233       11584 : }
+     234             : 
+     235       11932 : IFile::~IFile() {
+     236       11584 :   if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
+     237       11932 : }
+     238             : 
+     239     1471078 : IFile& IFile::getline(std::string &str) {
+     240     1471078 :   char tmp=0;
+     241             :   str="";
+     242             :   fpos_t pos;
+     243     1471078 :   fgetpos(fp,&pos);
+     244   100050487 :   while(llread(&tmp,1)==1 && tmp && tmp!='\n' && tmp!='\r' && !eof && !err) {
+     245    98579409 :     str+=tmp;
+     246             :   }
+     247     1471078 :   if(tmp=='\r') {
+     248          53 :     llread(&tmp,1);
+     249          53 :     plumed_massert(tmp=='\n',"plumed only accepts \\n (unix) or \\r\\n (dos) new lines");
+     250             :   }
+     251     1471078 :   if(eof && noEOL) {
+     252         869 :     if(str.length()>0) eof=false;
+     253     1470209 :   } else if(eof || err || tmp!='\n') {
+     254        6438 :     eof = true;
+     255             :     str="";
+     256        6438 :     if(!err) fsetpos(fp,&pos);
+     257             : // there was a fsetpos here that apparently is not necessary
+     258             : //  fsetpos(fp,&pos);
+     259             : // I think it was necessary to have rewind working correctly
+     260             : // after end of file. Since rewind is not used now anywhere,
+     261             : // it should be ok not to reset position.
+     262             : // This is necessary so that eof works properly for emacs files
+     263             : // with no endline at end of file.
+     264             :   }
+     265     1471078 :   return *this;
+     266             : }
+     267             : 
+     268    15852959 : unsigned IFile::findField(const std::string&name)const {
+     269             :   unsigned i;
+     270   105158056 :   for(i=0; i<fields.size(); i++) if(fields[i].name==name) break;
+     271    15852959 :   if(i>=fields.size()) {
+     272           0 :     plumed_merror("file " + getPath() + ": field " + name + " cannot be found");
+     273             :   }
+     274    15852959 :   return i;
+     275             : }
+     276             : 
+     277        6136 : void IFile::reset(bool reset) {
+     278        6136 :   eof = reset;
+     279        6136 :   err = reset;
+     280        6136 :   if(!reset && fp) clearerr(fp);
+     281             : #ifdef __PLUMED_HAS_ZLIB
+     282        6136 :   if(!reset && gzfp) gzclearerr(gzFile(gzfp));
+     283             : #endif
+     284        6136 :   return;
+     285             : }
+     286             : 
+     287        5778 : void IFile::allowIgnoredFields() {
+     288        5778 :   ignoreFields=true;
+     289        5778 : }
+     290             : 
+     291         884 : void IFile::allowNoEOL() {
+     292         884 :   noEOL=true;
+     293         884 : }
+     294             : 
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func-sort-c.html b/coverage/tools/IFile.h.func-sort-c.html new file mode 100644 index 0000000000..adc2c5db4e --- /dev/null +++ b/coverage/tools/IFile.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func.html b/coverage/tools/IFile.h.func.html new file mode 100644 index 0000000000..935e94b85d --- /dev/null +++ b/coverage/tools/IFile.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.gcov.html b/coverage/tools/IFile.h.gcov.html new file mode 100644 index 0000000000..339106c08a --- /dev/null +++ b/coverage/tools/IFile.h.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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-05-27 13:05: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       18874 :   class Field:
+      45             :     public FieldBase {
+      46             :   public:
+      47             :     bool read;
+      48        7273 :     Field(): read(false) {}
+      49             :   };
+      50             : /// Low-level read.
+      51             : /// Note: in parallel, all processes read
+      52             :   std::size_t llread(char*,std::size_t);
+      53             : /// All the defined fields
+      54             :   std::vector<Field> fields;
+      55             : /// Flag set in the middle of a field reading
+      56             :   bool inMiddleOfField;
+      57             : /// Set to true if you want to allow fields to be ignored in the read in file
+      58             :   bool ignoreFields;
+      59             : /// Set to true to allow files without end-of-line at the end
+      60             :   bool noEOL;
+      61             : /// Advance to next field (= read one line)
+      62             :   IFile& advanceField();
+      63             : /// Find field index by name
+      64             :   unsigned findField(const std::string&name)const;
+      65             : public:
+      66             : /// Constructor
+      67             :   IFile();
+      68             : /// Destructor
+      69             :   ~IFile();
+      70             : /// Opens the file
+      71             :   IFile& open(const std::string&name) override;
+      72             : /// Gets the list of all fields
+      73             :   IFile& scanFieldList(std::vector<std::string>&);
+      74             : /// Read a double field
+      75             :   IFile& scanField(const std::string&,double&);
+      76             : /// Read a int field
+      77             :   IFile& scanField(const std::string&,int&);
+      78             : /// Read a long int field
+      79             :   IFile& scanField(const std::string&,long int&);
+      80             : /// Read a long long int field
+      81             :   IFile& scanField(const std::string&,long long int&);
+      82             : /// Read a unsigned field
+      83             :   IFile& scanField(const std::string&,unsigned&);
+      84             : /// Read a long unsigned field
+      85             :   IFile& scanField(const std::string&,long unsigned&);
+      86             : /// Read a long long unsigned field
+      87             :   IFile& scanField(const std::string&,long long unsigned&);
+      88             : /// Read a string field
+      89             :   IFile& scanField(const std::string&,std::string&);
+      90             :   /**
+      91             :    Ends a field-formatted line.
+      92             : 
+      93             :   Typically used as
+      94             :   \verbatim
+      95             :     if.scanField("a",a).scanField("b",b).scanField();
+      96             :   \endverbatim
+      97             :   */
+      98             :   IFile& scanField();
+      99             : /// Get a full line as a string
+     100             :   IFile& getline(std::string&);
+     101             : /// Reset end of file
+     102             :   void reset(bool);
+     103             : /// Check if a field exist
+     104             :   bool FieldExist(const std::string& s);
+     105             : /// Read in a value
+     106             :   IFile& scanField(Value* val);
+     107             : /// Allow some of the fields in the input to be ignored
+     108             :   void allowIgnoredFields();
+     109             : /// Allow files without EOL at the end.
+     110             : /// This in practice should be only used when opening
+     111             : /// plumed input files
+     112             :   void allowNoEOL();
+     113             : };
+     114             : 
+     115             : }
+     116             : 
+     117             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func-sort-c.html b/coverage/tools/KernelFunctions.cpp.func-sort-c.html new file mode 100644 index 0000000000..2519e40353 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func.html b/coverage/tools/KernelFunctions.cpp.func.html new file mode 100644 index 0000000000..1fc1c25855 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.gcov.html b/coverage/tools/KernelFunctions.cpp.gcov.html new file mode 100644 index 0000000000..cac3866b48 --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.gcov.html @@ -0,0 +1,531 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func-sort-c.html b/coverage/tools/KernelFunctions.h.func-sort-c.html new file mode 100644 index 0000000000..a547554144 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func.html b/coverage/tools/KernelFunctions.h.func.html new file mode 100644 index 0000000000..df48993c5a --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func.html @@ -0,0 +1,76 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.gcov.html b/coverage/tools/KernelFunctions.h.gcov.html new file mode 100644 index 0000000000..d0bcddf425 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.gcov.html @@ -0,0 +1,173 @@ + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-05-27 13:05: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       30253 : class KernelFunctions {
+      33             : private:
+      34             : /// Is the metric matrix diagonal
+      35             :   enum {diagonal,multi,vonmises} dtype;
+      36             : /// What type of kernel are we using
+      37             :   enum {gaussian,truncatedgaussian,stretchedgaussian,uniform,triangular} ktype;
+      38             : /// The center of the kernel function
+      39             :   std::vector<double> center;
+      40             : /// The width of the kernel
+      41             :   std::vector<double> width;
+      42             : /// The height of the kernel
+      43             :   double height;
+      44             : 
+      45             :   double stretchA=1.0;
+      46             :   double stretchB=0.0;
+      47             : 
+      48             : /// Used to set all the data in the kernel during construction - avoids double coding as this has two constructors
+      49             :   void setData( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w );
+      50             : /// Convert the width into matrix form
+      51             :   Matrix<double> getMatrix() const;
+      52             : public:
+      53             :   explicit KernelFunctions( const std::string& input );
+      54             :   KernelFunctions( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w );
+      55             :   explicit KernelFunctions( const KernelFunctions* in );
+      56             : /// Normalise the function and scale the height accordingly
+      57             :   void normalize( const std::vector<Value*>& myvals );
+      58             : /// Get the dimensionality of the kernel
+      59             :   unsigned ndim() const;
+      60             : /// Get the cutoff for a kernel
+      61             :   double getCutoff( const double& width ) const ;
+      62             : /// Get the position of the center
+      63             :   std::vector<double> getCenter() const;
+      64             : /// Get the support
+      65             :   std::vector<unsigned> getSupport( const std::vector<double>& dx ) const;
+      66             : /// get it in continuous form
+      67             :   std::vector<double> getContinuousSupport( ) const;
+      68             : /// Evaluate the kernel function with constant intervals
+      69             :   double evaluate( const std::vector<Value*>& pos, std::vector<double>& derivatives, bool usederiv=true, bool doInt=false, double lowI_=-1, double uppI_=-1 ) const;
+      70             : /// Read a kernel function from a file
+      71             :   static std::unique_ptr<KernelFunctions> read( IFile* ifile, const bool& cholesky, const std::vector<std::string>& valnames );
+      72             : };
+      73             : 
+      74             : inline
+      75     9632291 : Matrix<double> KernelFunctions::getMatrix() const {
+      76             :   unsigned k=0, ncv=ndim(); Matrix<double> mymatrix(ncv,ncv);
+      77    37554115 :   for(unsigned i=0; i<ncv; i++) {
+      78    82790445 :     for(unsigned j=i; j<ncv; j++) {
+      79    54868621 :       mymatrix(i,j)=mymatrix(j,i)=width[k]; // recompose the full inverse matrix
+      80    54868621 :       k++;
+      81             :     }
+      82             :   }
+      83     9632291 :   return mymatrix;
+      84             : }
+      85             : 
+      86             : inline
+      87             : unsigned KernelFunctions::ndim() const {
+      88   150621987 :   return center.size();
+      89             : }
+      90             : 
+      91             : inline
+      92             : std::vector<double> KernelFunctions::getCenter() const {
+      93       27064 :   return center;
+      94             : }
+      95             : 
+      96             : }
+      97             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func-sort-c.html b/coverage/tools/Keywords.cpp.func-sort-c.html new file mode 100644 index 0000000000..d8b3f51029 --- /dev/null +++ b/coverage/tools/Keywords.cpp.func-sort-c.html @@ -0,0 +1,236 @@ + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-05-27 13:05:14Functions:324178.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev222
_ZNK4PLMD8Keywords9print_vimEv292
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev584
_ZN4PLMD8Keywords3addERKS0_796
_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_796
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1585
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_2118
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2398
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4486
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4523
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4679
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4679
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6758
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7064
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_11123
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12781
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15681
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej27663
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb36898
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_85623
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb119433
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_127329
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_219537
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_230553
_ZNK4PLMD8Keywords3getB5cxx11Ej419194
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_533817
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_827901
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE832387
_ZNK4PLMD8Keywords4sizeEv916902
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1113354
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1133339
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1392419
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func.html b/coverage/tools/Keywords.cpp.func.html new file mode 100644 index 0000000000..43be52985c --- /dev/null +++ b/coverage/tools/Keywords.cpp.func.html @@ -0,0 +1,236 @@ + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-05-27 13:05:14Functions:324178.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_2118
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4679
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_85623
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6758
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_533817
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_230553
_ZN4PLMD8Keywords3addERKS0_796
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15681
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1585
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4679
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1113354
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_219537
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_127329
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej27663
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev584
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7064
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_11123
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb36898
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev222
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4486
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb119433
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4523
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2398
_ZNK4PLMD8Keywords3getB5cxx11Ej419194
_ZNK4PLMD8Keywords4sizeEv916902
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_827901
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1392419
_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_796
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE832387
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12781
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1133339
_ZNK4PLMD8Keywords9print_vimEv292
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.gcov.html b/coverage/tools/Keywords.cpp.gcov.html new file mode 100644 index 0000000000..3c0b26d180 --- /dev/null +++ b/coverage/tools/Keywords.cpp.gcov.html @@ -0,0 +1,739 @@ + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-05-27 13:05:14Functions:324178.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Keywords.h"
+      23             : #include "Log.h"
+      24             : #include "Tools.h"
+      25             : #include <iostream>
+      26             : #include <iomanip>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30     1113354 : Keywords::KeyType::KeyType( const std::string& type ) {
+      31     1113354 :   if( type=="compulsory" ) {
+      32      297210 :     style=compulsory;
+      33      816144 :   } else if( type=="flag" ) {
+      34      221655 :     style=flag;
+      35      594489 :   } else if( type=="optional" ) {
+      36      313638 :     style=optional;
+      37      280851 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      38      143376 :     style=atoms;
+      39      137475 :   } else if( type=="hidden" ) {
+      40       66619 :     style=hidden;
+      41       70856 :   } else if( type=="vessel" ) {
+      42       70856 :     style=vessel;
+      43             :   } else {
+      44           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      45             :   }
+      46     1113354 : }
+      47             : 
+      48        4679 : void Keywords::KeyType::setStyle( const std::string& type ) {
+      49        4679 :   if( type=="compulsory" ) {
+      50          93 :     style=compulsory;
+      51        4586 :   } else if( type=="flag" ) {
+      52           0 :     style=flag;
+      53        4586 :   } else if( type=="optional" ) {
+      54          30 :     style=optional;
+      55        4556 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      56         239 :     style=atoms;
+      57        4317 :   } else if( type=="hidden" ) {
+      58         149 :     style=hidden;
+      59        4168 :   } else if( type=="vessel" ) {
+      60        4168 :     style=vessel;
+      61             :   } else {
+      62           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      63             :   }
+      64        4679 : }
+      65             : 
+      66      832387 : std::string Keywords::getStyle( const std::string & k ) const {
+      67           0 :   plumed_massert( types.count(k), "Did not find keyword " + k );
+      68      832387 :   return (types.find(k)->second).toString();
+      69             : }
+      70             : 
+      71         796 : void Keywords::add( const Keywords& newkeys ) {
+      72         796 :   newkeys.copyData( keys, reserved_keys, types, allowmultiple, documentation, booldefs, numdefs, atomtags, cnames, ckey, cdocs  );
+      73         796 : }
+      74             : 
+      75         796 : void Keywords::copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+      76             :                          std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+      77             :                          std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+      78             :                          std::map<std::string,std::string>& cd ) const {
+      79         796 :   for(unsigned i=0; i<keys.size(); ++i) {
+      80           0 :     std::string thiskey=keys[i];
+      81           0 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      82           0 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      83           0 :     kk.push_back( thiskey );
+      84           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+      85           0 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+      86           0 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+      87           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+      88           0 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+      89           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+      90           0 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+      91           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+      92           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+      93             :   }
+      94       15124 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+      95       14328 :     std::string thiskey=reserved_keys[i];
+      96      140310 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      97      198630 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      98       14328 :     rk.push_back( thiskey );
+      99           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+     100       14328 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+     101       14328 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+     102           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+     103       14328 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+     104           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+     105       28656 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+     106           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+     107           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+     108             :   }
+     109       15124 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     110       14328 :     std::string thisnam=cnames[i];
+     111      136116 :     for(unsigned j=0; j<cnam.size(); ++j) plumed_massert( thisnam!=cnam[j], "component " + thisnam + " is in twice" );
+     112       14328 :     cnam.push_back( thisnam );
+     113           0 :     plumed_massert( ckey.count( thisnam ), "no keyword data on component " + thisnam + " to copy" );
+     114       28656 :     ck.insert( std::pair<std::string,std::string>( thisnam, ckey.find(thisnam)->second) );
+     115           0 :     plumed_massert( cdocs.count( thisnam ), "no documentation on component " + thisnam + " to copy" );
+     116       28656 :     cd.insert( std::pair<std::string,std::string>( thisnam, cdocs.find(thisnam)->second) );
+     117             :   }
+     118         796 : }
+     119             : 
+     120      127329 : void Keywords::reserve( const std::string & t, const std::string & k, const std::string & d ) {
+     121      127329 :   plumed_assert( !exists(k) && !reserved(k) );
+     122      127329 :   std::string fd, lowkey=k;
+     123             :   // Convert to lower case
+     124     1078677 :   std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     125             : // Remove any underscore characters
+     126             :   for(unsigned i=0;; ++i) {
+     127      172466 :     std::size_t num=lowkey.find_first_of("_");
+     128      172466 :     if( num==std::string::npos ) break;
+     129       45137 :     lowkey.erase( lowkey.begin() + num, lowkey.begin() + num + 1 );
+     130       45137 :   }
+     131      127329 :   if( t=="vessel" ) {
+     132      141712 :     fd = d + " The final value can be referenced using <em>label</em>." + lowkey;
+     133      133376 :     if(d.find("flag")==std::string::npos) fd += ".  You can use multiple instances of this keyword i.e. " +
+     134      125040 :           k +"1, " + k + "2, " + k + "3...  The corresponding values are then "
+     135      125040 :           "referenced using <em>label</em>."+ lowkey +"-1,  <em>label</em>." + lowkey +
+     136      125040 :           "-2,  <em>label</em>." + lowkey + "-3...";
+     137       70856 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     138      141712 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("vessel")) );
+     139       56473 :   } else if( t=="numbered" ) {
+     140        6318 :     fd = d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     141        3159 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     142        6318 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("optional")) );
+     143             :   } else {
+     144             :     fd = d;
+     145       53314 :     if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     146       53314 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     147      106628 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     148       54817 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     149             :   }
+     150      127329 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     151      127329 :   reserved_keys.push_back(k);
+     152      127329 : }
+     153             : 
+     154        2118 : void Keywords::reserveFlag( const std::string & k, const bool def, const std::string & d ) {
+     155        2118 :   plumed_assert( !exists(k) && !reserved(k) );
+     156             :   std::string defstr;
+     157        2118 :   if( def ) { defstr="( default=on ) "; } else { defstr="( default=off ) "; }
+     158        4236 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     159       25931 :   std::string fd,lowkey=k; std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     160        2118 :   fd=defstr + d;
+     161        4236 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     162        2118 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     163           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     164        2118 :   reserved_keys.push_back(k);
+     165        2118 : }
+     166             : 
+     167       15681 : void Keywords::use( const std::string & k ) {
+     168       15681 :   plumed_massert( reserved(k), "the " + k + " keyword is not reserved");
+     169      199333 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     170      183652 :     if(reserved_keys[i]==k) keys.push_back( reserved_keys[i] );
+     171             :   }
+     172       15681 : }
+     173             : 
+     174        4679 : void Keywords::reset_style( const std::string & k, const std::string & style ) {
+     175        4679 :   plumed_massert( exists(k) || reserved(k), "no " + k + " keyword" );
+     176        4679 :   (types.find(k)->second).setStyle(style);
+     177        4679 :   if( (types.find(k)->second).isVessel() ) allowmultiple[k]=true;
+     178        4918 :   if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,style) );
+     179        4679 : }
+     180             : 
+     181      533817 : void Keywords::add( const std::string & t, const std::string & k, const std::string & d ) {
+     182     1601451 :   plumed_massert( !exists(k) && t!="flag" && !reserved(k) && t!="vessel", "keyword " + k + " has already been registered");
+     183             :   std::string fd;
+     184      533817 :   if( t=="numbered" ) {
+     185        3106 :     fd=d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     186        1553 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     187        3106 :     types.insert( std::pair<std::string,KeyType>(k, KeyType("optional")) );
+     188             :   } else {
+     189             :     fd=d;
+     190      532264 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     191     1064528 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     192      674137 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     193             :   }
+     194      551511 :   if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     195      533817 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     196      533817 :   keys.push_back(k);
+     197      533817 : }
+     198             : 
+     199      230553 : void Keywords::add( const std::string & t, const std::string & k, const std::string &  def, const std::string & d ) {
+     200      461106 :   plumed_assert( !exists(k) && !reserved(k) &&  (t=="compulsory" || t=="hidden" )); // An optional keyword can't have a default
+     201      230553 :   types.insert(  std::pair<std::string,KeyType>(k, KeyType(t)) );
+     202      461106 :   documentation.insert( std::pair<std::string,std::string>(k,"( default=" + def + " ) " + d) );
+     203      230553 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     204      230553 :   numdefs.insert( std::pair<std::string,std::string>(k,def) );
+     205      230553 :   keys.push_back(k);
+     206      230553 : }
+     207             : 
+     208      219537 : void Keywords::addFlag( const std::string & k, const bool def, const std::string & d ) {
+     209      219537 :   plumed_massert( !exists(k) && !reserved(k), "keyword " + k + " has already been registered");
+     210      219537 :   std::string defstr; plumed_massert( !def, "the second argument to addFlag must be false " + k );
+     211             :   defstr="( default=off ) ";
+     212      439074 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     213      439074 :   documentation.insert( std::pair<std::string,std::string>(k,defstr + d) );
+     214      219537 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     215           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     216      219537 :   keys.push_back(k);
+     217      219537 : }
+     218             : 
+     219        1585 : void Keywords::remove( const std::string & k ) {
+     220             :   bool found=false; unsigned j=0, n=0;
+     221             : 
+     222             :   while(true) {
+     223       17980 :     for(j=0; j<keys.size(); j++) if(keys[j]==k)break;
+     224       37620 :     for(n=0; n<reserved_keys.size(); n++) if(reserved_keys[n]==k)break;
+     225        3170 :     if(j<keys.size()) {
+     226        1491 :       keys.erase(keys.begin()+j);
+     227             :       found=true;
+     228        1679 :     } else if(n<reserved_keys.size()) {
+     229          94 :       reserved_keys.erase(reserved_keys.begin()+n);
+     230             :       found=true;
+     231             :     } else break;
+     232             :   }
+     233             :   // Delete documentation, type and so on from the description
+     234             :   types.erase(k); documentation.erase(k); allowmultiple.erase(k); booldefs.erase(k); numdefs.erase(k);
+     235        1585 :   plumed_massert(found,"You are trying to forbid " + k + " a keyword that isn't there"); // You have tried to forbid a keyword that isn't there
+     236        1585 : }
+     237             : 
+     238       12781 : bool Keywords::numbered( const std::string & k ) const {
+     239       25562 :   if( style( k,"atoms") ) return true;
+     240           0 :   plumed_massert( allowmultiple.count(k), "Did not find keyword " + k );
+     241       10526 :   return allowmultiple.find(k)->second;
+     242             : }
+     243             : 
+     244      827901 : bool Keywords::style( const std::string & k, const std::string & t ) const {
+     245      827901 :   if( getStyle(k)==t ) return true;
+     246             :   return false;
+     247             : }
+     248             : 
+     249      916902 : unsigned Keywords::size() const {
+     250      916902 :   return keys.size();
+     251             : }
+     252             : 
+     253       27663 : std::string Keywords::getKeyword( const unsigned i ) const {
+     254       27663 :   plumed_assert( i<size() );
+     255       27663 :   return keys[i];
+     256             : }
+     257             : 
+     258     1392419 : bool Keywords::exists( const std::string & k ) const {
+     259    14982399 :   for(unsigned i=0; i<keys.size(); ++i) {
+     260    13822984 :     if( keys[i]==k ) return true;
+     261             :   }
+     262             :   return false;
+     263             : }
+     264             : 
+     265     1133339 : bool Keywords::reserved( const std::string & k ) const {
+     266     2588147 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     267     1474793 :     if( reserved_keys[i]==k ) return true;
+     268             :   }
+     269             :   return false;
+     270             : }
+     271             : 
+     272           0 : void Keywords::print_template(const std::string& actionname, bool include_optional) const {
+     273             :   unsigned nkeys=0;
+     274             :   std::printf("%s",actionname.c_str());
+     275           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     276           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     277             :   }
+     278           0 :   if( nkeys>0 ) {
+     279           0 :     std::string prevtag="start";
+     280           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     281           0 :       if( (types.find(keys[i])->second).isAtomList() ) {
+     282           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     283           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second ) break;
+     284           0 :         if( (atomtags.find(keys[i])->second).find("residues")!=std::string::npos) std::printf(" %s=<residue selection>", keys[i].c_str() );
+     285             :         else std::printf(" %s=<atom selection>", keys[i].c_str() );
+     286           0 :         prevtag=atomtags.find(keys[i])->second;
+     287             :       }
+     288             :     }
+     289             :   }
+     290             :   nkeys=0;
+     291           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     292           0 :     if ( include_optional || \
+     293           0 :          (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     294             :   }
+     295           0 :   if( nkeys>0 ) {
+     296           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     297           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) {
+     298             :         std::string def;
+     299           0 :         if( getDefaultValue( keys[i], def) ) {
+     300             :           std::printf(" %s=%s ", keys[i].c_str(), def.c_str() );
+     301             :         } else {
+     302             :           std::printf(" %s=    ", keys[i].c_str() );
+     303             :         }
+     304           0 :       } else if (include_optional) {
+     305             :         // TG no defaults for optional keywords?
+     306             :         std::printf(" [%s]", keys[i].c_str() );
+     307             :       }
+     308             :     }
+     309             :   }
+     310             :   std::printf("\n");
+     311             :   std::flush(std::cout);
+     312           0 : }
+     313             : 
+     314         292 : void Keywords::print_vim() const {
+     315        4778 :   for(unsigned i=0; i<keys.size(); ++i) {
+     316        4486 :     if( (types.find(keys[i])->second).isFlag() ) {
+     317             :       std::printf( ",flag:%s", keys[i].c_str() );
+     318             :     } else {
+     319        3535 :       if( allowmultiple.find(keys[i])->second ) std::printf(",numbered:%s",keys[i].c_str() );
+     320             :       else std::printf(",option:%s",keys[i].c_str() );
+     321             :     }
+     322             :   }
+     323         292 :   std::fprintf(stdout, "\n%s", getHelpString().c_str() );
+     324         292 : }
+     325             : 
+     326           0 : void Keywords::print_html() const {
+     327             : 
+     328             : // This is the part that outputs the details of the components
+     329           0 :   if( cnames.size()>0 ) {
+     330             :     unsigned ndef=0;
+     331           0 :     for(unsigned i=0; i<cnames.size(); ++i) {
+     332           0 :       if(ckey.find(cnames[i])->second=="default") ndef++;
+     333             :     }
+     334             : 
+     335           0 :     if( ndef>0 ) {
+     336           0 :       std::cout<<"\\par Description of components\n\n";
+     337           0 :       std::cout<<cstring<<"\n\n";
+     338           0 :       std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     339             :       std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     340             :       unsigned nndef=0;
+     341           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     342             :         //plumed_assert( ckey.find(cnames[i])->second=="default" );
+     343           0 :         if( ckey.find(cnames[i])->second!="default" ) { nndef++; continue; }
+     344             :         std::printf("<tr>\n");
+     345             :         std::printf("<td width=15%%> <b> %s </b></td>\n",cnames[i].c_str() );
+     346             :         std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     347             :         std::printf("</tr>\n");
+     348             :       }
+     349           0 :       std::cout<<"</table>\n\n";
+     350           0 :       if( nndef>0 ) {
+     351           0 :         std::cout<<"In addition the following quantities can be calculated by employing the keywords listed below"<<std::endl;
+     352           0 :         std::cout<<"\n\n";
+     353           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     354             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     355           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     356           0 :           if( ckey.find(cnames[i])->second!="default") {
+     357             :             std::printf("<tr>\n");
+     358             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     359             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     360             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     361             :             std::printf("</tr>\n");
+     362             :           }
+     363             :         }
+     364           0 :         std::cout<<"</table>\n\n";
+     365             :       }
+     366             :     } else {
+     367             :       unsigned nregs=0;
+     368           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     369           0 :         if( exists(ckey.find(cnames[i])->second) ) nregs++;
+     370             :       }
+     371           0 :       if( nregs>0 ) {
+     372           0 :         std::cout<<"\\par Description of components\n\n";
+     373           0 :         std::cout<<cstring<<"\n\n";
+     374           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     375             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     376           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     377           0 :           if( exists(ckey.find(cnames[i])->second) ) {
+     378             :             std::printf("<tr>\n");
+     379             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     380             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     381             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     382             :             std::printf("</tr>\n");
+     383             :           }
+     384             :         }
+     385           0 :         std::cout<<"</table>\n\n";
+     386             :       }
+     387             :     }
+     388             :   }
+     389             : 
+     390             :   unsigned nkeys=0;
+     391           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     392           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     393             :   }
+     394           0 :   if( nkeys>0 ) {
+     395           0 :     if(isaction && isatoms) std::cout<<"\\par The atoms involved can be specified using\n\n";
+     396           0 :     else if(isaction) std::cout<<"\\par The data to analyze can be the output from another analysis algorithm\n\n";
+     397           0 :     else std::cout<<"\\par The input trajectory is specified using one of the following\n\n";
+     398           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     399           0 :     std::string prevtag="start"; unsigned counter=0;
+     400           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     401           0 :       if ( (types.find(keys[i])->second).isAtomList() ) {
+     402           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     403           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second && isaction ) {
+     404           0 :           std::cout<<"</table>\n\n";
+     405           0 :           if( isatoms ) std::cout<<"\\par Or alternatively by using\n\n";
+     406           0 :           else if( counter==0 ) { std::cout<<"\\par Alternatively data can be collected from the trajectory using \n\n"; counter++; }
+     407           0 :           else std::cout<<"\\par Lastly data collected in a previous analysis action can be reanalyzed by using the keyword \n\n";
+     408           0 :           std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     409             :         }
+     410           0 :         print_html_item( keys[i] );
+     411           0 :         prevtag=atomtags.find(keys[i])->second;
+     412             :       }
+     413             :     }
+     414           0 :     std::cout<<"</table>\n\n";
+     415             :   }
+     416             :   nkeys=0;
+     417           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     418           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     419             :   }
+     420           0 :   if( nkeys>0 ) {
+     421           0 :     if(isaction) std::cout<< "\\par Compulsory keywords\n\n";
+     422           0 :     else std::cout<<"\\par The following must be present\n\n";
+     423           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     424           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     425           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) print_html_item( keys[i] );
+     426             :     }
+     427           0 :     std::cout<<"</table>\n\n";
+     428             :   }
+     429             :   nkeys=0;
+     430           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     431           0 :     if ( (types.find(keys[i])->second).isFlag() || (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     432             :   }
+     433           0 :   if( nkeys>0 ) {
+     434           0 :     if(isaction) std::cout<<"\\par Options\n\n";
+     435           0 :     else std::cout<<"\\par The following options are available\n\n";
+     436           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     437           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     438           0 :       if ( (types.find(keys[i])->second).isFlag() ) print_html_item( keys[i] );
+     439             :     }
+     440           0 :     std::cout<<"\n";
+     441             :   }
+     442             :   nkeys=0;
+     443           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     444           0 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     445             :   }
+     446           0 :   if( nkeys>0 ) {
+     447           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     448           0 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) print_html_item( keys[i] );
+     449             :     }
+     450             :   }
+     451           0 :   std::cout<<"</table>\n\n";
+     452           0 : }
+     453             : 
+     454           0 : void Keywords::print_spelling() const {
+     455           0 :   for(unsigned i=0; i<keys.size(); ++i) std::printf("%s\n", keys[i].c_str() );
+     456           0 :   for(unsigned i=0; i<cnames.size(); ++i) std::printf("%s\n",cnames[i].c_str() );
+     457           0 : }
+     458             : 
+     459        7064 : std::string Keywords::getKeywordDocs( const std::string& key ) const {
+     460        7064 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     461        7064 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     462       14128 :   std::stringstream sstr; sstr<<std::setw(23)<<key<<" - ";
+     463        7064 :   unsigned nl=0; std::string blank=" ";
+     464      149960 :   for(unsigned i=0; i<w.size(); ++i) {
+     465      143434 :     nl+=w[i].length() + 1;
+     466      143434 :     if( nl>60 ) {
+     467       33114 :       sstr<<"\n"<<std::setw(23)<<blank<<"   "<<w[i]<<" "; nl=0;
+     468      132396 :     } else sstr<<w[i]<<" ";
+     469      143434 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     470             :   }
+     471       14128 :   sstr<<"\n"; return sstr.str();
+     472        7064 : }
+     473             : 
+     474         584 : std::string Keywords::getHelpString() const {
+     475             :   std::string helpstr; unsigned nkeys=0;
+     476        9556 :   for(unsigned i=0; i<keys.size(); ++i) {
+     477        8972 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     478             :   }
+     479         584 :   if( nkeys>0 ) {
+     480             :     helpstr += "The input trajectory can be in any of the following formats: \n\n";
+     481        5254 :     for(unsigned i=0; i<keys.size(); ++i) {
+     482        5534 :       if ( (types.find(keys[i])->second).isAtomList() ) helpstr += getKeywordDocs( keys[i] );
+     483             :     }
+     484             :   }
+     485             :   nkeys=0;
+     486        9556 :   for(unsigned i=0; i<keys.size(); ++i) {
+     487        8972 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     488             :   }
+     489             :   unsigned ncompulsory=nkeys;
+     490         584 :   if( nkeys>0 ) {
+     491             :     helpstr += "\nThe following arguments are compulsory: \n\n";
+     492        7824 :     for(unsigned i=0; i<keys.size(); ++i) {
+     493        9118 :       if ( (types.find(keys[i])->second).isCompulsory() ) helpstr += getKeywordDocs( keys[i] );
+     494             :     }
+     495             :   }
+     496             :   nkeys=0;
+     497        9556 :   for(unsigned i=0; i<keys.size(); ++i) {
+     498        8972 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     499             :   }
+     500         584 :   if( nkeys>0 ) {
+     501         518 :     if(ncompulsory>0) helpstr += "\nIn addition you may use the following options: \n\n";
+     502             :     else helpstr += "\nThe following options are available\n\n";
+     503        9126 :     for(unsigned i=0; i<keys.size(); ++i) {
+     504       10510 :       if ( (types.find(keys[i])->second).isFlag() ) helpstr += getKeywordDocs( keys[i] ).c_str();
+     505             :     }
+     506             :   }
+     507             :   nkeys=0;
+     508        9556 :   for(unsigned i=0; i<keys.size(); ++i) {
+     509       16134 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     510             :   }
+     511         584 :   if( nkeys>0 ) {
+     512        8318 :     for(unsigned i=0; i<keys.size(); ++i) {
+     513       16802 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) helpstr += getKeywordDocs( keys[i] );
+     514             :     }
+     515             :     helpstr += "\n";
+     516             :   }
+     517         584 :   return helpstr;
+     518             : }
+     519             : 
+     520           0 : void Keywords::print( Log& log ) const {
+     521           0 :   log.printf("%s", getHelpString().c_str() );
+     522           0 : }
+     523             : 
+     524           0 : void Keywords::print( FILE* out ) const {
+     525           0 :   fprintf( out,"%s", getHelpString().c_str() );
+     526           0 : }
+     527             : 
+     528           0 : std::string Keywords::getTooltip( const std::string& name ) const {
+     529           0 :   std::size_t dd=name.find_first_of("0123456789"); std::string kname=name.substr(0,dd);
+     530           0 :   if( !exists(kname) ) return "<b> could not find this keyword </b>";
+     531           0 :   std::string mystring, docstr = documentation.find(kname)->second;
+     532           0 :   if( types.find(kname)->second.isCompulsory() ) {
+     533             :     mystring += "<b>compulsory keyword ";
+     534           0 :     if( docstr.find("default")!=std::string::npos ) {
+     535           0 :       std::size_t bra = docstr.find_first_of(")"); mystring += docstr.substr(0,bra+1); docstr = docstr.substr(bra+1);
+     536             :     }
+     537             :     mystring += "</b>\n";
+     538             :   }
+     539           0 :   std::vector<std::string> w=Tools::getWords( docstr ); unsigned nl=0;
+     540           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     541           0 :     nl+=w[i].length() + 1;
+     542           0 :     if( nl>80 ) { mystring += w[i] + "\n"; nl=0; }
+     543           0 :     else { mystring += w[i] + " "; }
+     544           0 :     if( w[i].find(".")!=std::string::npos ) break; // Only write up the the first dot
+     545             :   }
+     546             :   return mystring;
+     547           0 : }
+     548             : 
+     549           0 : void Keywords::print_html_item( const std::string& key ) const {
+     550             :   std::printf("<tr>\n");
+     551             :   std::printf("<td width=15%%> <b> %s </b></td>\n",key.c_str() );
+     552             :   std::printf("<td> %s </td>\n",(documentation.find(key)->second).c_str() );
+     553             :   std::printf("</tr>\n");
+     554           0 : }
+     555             : 
+     556      419194 : std::string Keywords::get( const unsigned k ) const {
+     557      419194 :   plumed_assert( k<size() );
+     558      419194 :   return keys[k];
+     559             : }
+     560             : 
+     561       36898 : bool Keywords::getLogicalDefault(const std::string & key, bool& def ) const {
+     562       36898 :   if( booldefs.find(key)!=booldefs.end() ) {
+     563       36898 :     def=booldefs.find(key)->second;
+     564       36898 :     return true;
+     565             :   } else {
+     566             :     return false;
+     567             :   }
+     568             : }
+     569             : 
+     570       11123 : bool Keywords::getDefaultValue(const std::string & key, std::string& def ) const {
+     571       21893 :   plumed_assert( style(key,"compulsory") || style(key,"hidden") );
+     572             : 
+     573       11123 :   if( numdefs.find(key)!=numdefs.end() ) {
+     574        5738 :     def=numdefs.find(key)->second;
+     575        5738 :     return true;
+     576             :   } else {
+     577             :     return false;
+     578             :   }
+     579             : }
+     580             : 
+     581           0 : void Keywords::destroyData() {
+     582           0 :   keys.clear(); reserved_keys.clear(); types.clear();
+     583             :   allowmultiple.clear(); documentation.clear();
+     584             :   booldefs.clear(); numdefs.clear(); atomtags.clear();
+     585             :   ckey.clear(); cdocs.clear(); ckey.clear();
+     586           0 : }
+     587             : 
+     588        6758 : void Keywords::setComponentsIntroduction( const std::string& instr ) {
+     589        6758 :   cstring = instr;
+     590        6758 : }
+     591             : 
+     592       85623 : void Keywords::addOutputComponent( const std::string& name, const std::string& key, const std::string& descr ) {
+     593       85623 :   plumed_assert( !outputComponentExists( name, false ) );
+     594       85623 :   plumed_massert( name.find("-")==std::string::npos,"dash is reseved character in component names" );
+     595             : 
+     596       85623 :   std::size_t num2=name.find_first_of("_");
+     597       85623 :   if( num2!=std::string::npos ) {
+     598         318 :     char uu = '_'; plumed_massert( std::count(name.begin(),name.end(), uu)==1, "underscore is reserved character in component names and there should only be one");
+     599         318 :     plumed_massert( num2==0, "underscore is reserved character in component names that has special meaning");
+     600             :   }
+     601             : 
+     602       85623 :   ckey.insert( std::pair<std::string,std::string>(name,key) );
+     603       85623 :   cdocs.insert( std::pair<std::string,std::string>(name,descr) );
+     604       85623 :   cnames.push_back(name);
+     605       85623 : }
+     606             : 
+     607      119433 : bool Keywords::outputComponentExists( const std::string& name, const bool& custom ) const {
+     608      119433 :   if( custom && cstring.find("customize")!=std::string::npos ) return true;
+     609             : 
+     610             :   std::string sname;
+     611      115972 :   std::size_t num=name.find_first_of("-");
+     612      115972 :   std::size_t num2=name.find_last_of("_");
+     613             : 
+     614      117910 :   if( num2!=std::string::npos ) sname=name.substr(num2);
+     615      139969 :   else if( num!=std::string::npos ) sname=name.substr(0,num);
+     616             :   else sname=name;
+     617             : 
+     618     1101134 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     619     1015511 :     if( sname==cnames[i] ) return true;
+     620             :   }
+     621             :   return false;
+     622             : }
+     623             : 
+     624        4523 : std::string Keywords::getOutputComponentFlag( const std::string& name ) const {
+     625        4523 :   return ckey.find(name)->second;
+     626             : }
+     627             : 
+     628        2398 : std::string Keywords::getOutputComponentDescription( const std::string& name ) const {
+     629        2398 :   if( cstring.find("customized")!=std::string::npos ) return "the label of this action is set by user in the input. See documentation above.";
+     630             : 
+     631             :   bool found=false;
+     632       42138 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     633       39796 :     if( name==cnames[i] ) found=true;
+     634             :   }
+     635        2342 :   if( !found ) plumed_merror("could not find output component named " + name );
+     636        2342 :   return cdocs.find(name)->second;
+     637             : }
+     638             : 
+     639           0 : void Keywords::removeComponent( const std::string& name ) {
+     640             :   bool found=false;
+     641             : 
+     642             :   while(true) {
+     643             :     unsigned j;
+     644           0 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     645           0 :     if(j<cnames.size()) {
+     646           0 :       cnames.erase(cnames.begin()+j);
+     647             :       found=true;
+     648             :     } else break;
+     649           0 :   }
+     650             :   // Delete documentation, type and so on from the description
+     651             :   cdocs.erase(name); ckey.erase(name);
+     652           0 :   plumed_massert(found,"You are trying to remove " + name + " a component that isn't there");
+     653           0 : }
+     654             : 
+     655         222 : std::vector<std::string> Keywords::getOutputComponents() const {
+     656         222 :   return cnames;
+     657             : }
+     658             : 
+     659        4486 : std::string Keywords::getKeywordDescription( const std::string& key ) const {
+     660        8972 :   plumed_assert( exists( key ) ); return documentation.find(key)->second;
+     661             : }
+     662             : 
+     663             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func-sort-c.html b/coverage/tools/Keywords.h.func-sort-c.html new file mode 100644 index 0000000000..1022541fbb --- /dev/null +++ b/coverage/tools/Keywords.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev98697
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev832387
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func.html b/coverage/tools/Keywords.h.func.html new file mode 100644 index 0000000000..412e6a60e3 --- /dev/null +++ b/coverage/tools/Keywords.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev98697
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev832387
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.gcov.html b/coverage/tools/Keywords.h.gcov.html new file mode 100644 index 0000000000..67d725c4e0 --- /dev/null +++ b/coverage/tools/Keywords.h.gcov.html @@ -0,0 +1,260 @@ + + + + + + + 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-05-27 13:05: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       16332 :     bool isCompulsory() const { return (style==compulsory); }
+      44       22066 :     bool isFlag() const { return (style==flag); }
+      45       16846 :     bool isOptional() const { return (style==optional); }
+      46      618551 :     bool isAtomList() const { return (style==atoms); }
+      47       17905 :     bool isVessel() const { return (style==vessel); }
+      48      832387 :     std::string toString() const {
+      49      832387 :       if(style==compulsory) return "compulsory";
+      50      199530 :       else if(style==optional) return "optional";
+      51      159101 :       else if(style==atoms) return "atoms";
+      52      319669 :       else if(style==flag) return "flag";
+      53       74060 :       else if(style==hidden) return "hidden";
+      54       22570 :       else if(style==vessel) return "vessel";
+      55           0 :       else plumed_assert(0);
+      56             :       return "";
+      57             :     }
+      58             :   };
+      59             :   friend class Action;
+      60             : private:
+      61             : /// Is this an action or driver (this bool affects what style==atoms does in print)
+      62             :   bool isaction;
+      63             : /// This allows us to overwrite the behavior of the atoms type in analysis actions
+      64             :   bool isatoms;
+      65             : /// The names of the allowed keywords
+      66             :   std::vector<std::string> keys;
+      67             : /// The names of the reserved keywords
+      68             :   std::vector<std::string> reserved_keys;
+      69             : /// Whether the keyword is compulsory, optional...
+      70             :   std::map<std::string,KeyType> types;
+      71             : /// Do we allow stuff like key1, key2 etc
+      72             :   std::map<std::string,bool> allowmultiple;
+      73             : /// The documentation for the keywords
+      74             :   std::map<std::string,std::string> documentation;
+      75             : /// The default values for the flags (are they on or of)
+      76             :   std::map<std::string,bool> booldefs;
+      77             : /// The default values (if there are default values) for compulsory keywords
+      78             :   std::map<std::string,std::string> numdefs;
+      79             : /// The tags for atoms - we use this so the manual can differentiate between different ways of specifying atoms
+      80             :   std::map<std::string,std::string> atomtags;
+      81             : /// The string that should be printed out to describe how the components work for this particular action
+      82             :   std::string cstring;
+      83             : /// The names of all the possible components for an action
+      84             :   std::vector<std::string> cnames;
+      85             : /// The keyword that turns on a particular component
+      86             :   std::map<std::string,std::string> ckey;
+      87             : /// The documentation for a particular component
+      88             :   std::map<std::string,std::string> cdocs;
+      89             : /// Print the documentation for the jth keyword in html
+      90             :   void print_html_item( const std::string& ) const;
+      91             : public:
+      92             : /// Constructor
+      93       98697 :   Keywords() : isaction(true), isatoms(true) {}
+      94             : ///
+      95        8336 :   void isDriver() { isaction=false; }
+      96             : ///
+      97         149 :   void isAnalysis() { isatoms=false; }
+      98             : /// find out whether flag key is on or off by default.
+      99             :   bool getLogicalDefault(const std::string & key, bool& def ) const ;
+     100             : /// Get the value of the default for the keyword named key
+     101             :   bool getDefaultValue(const std::string & key, std::string& def ) const ;
+     102             : /// Return the number of defined keywords
+     103             :   unsigned size() const;
+     104             : /// Check if numbered keywords are allowed for this action
+     105             :   bool numbered( const std::string & k ) const ;
+     106             : /// Return the ith keyword
+     107             :   std::string getKeyword( const unsigned i ) const ;
+     108             : /// Get the documentation for a particular keyword
+     109             :   std::string getKeywordDocs( const std::string& key ) const ;
+     110             : /// Print the documentation to the log file (used by PLMD::Action::error)
+     111             :   void print( Log& log ) const ;
+     112             : /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
+     113             :   void print( FILE* out ) const ;
+     114             : /// Get the help string
+     115             :   std::string getHelpString() const ;
+     116             : /// Print a file containing the list of keywords for a particular action (used for spell checking)
+     117             :   void print_spelling() const ;
+     118             : /// Reserve a keyword
+     119             :   void reserve( const std::string & t, const std::string & k, const std::string & d );
+     120             : /// Reserve a flag
+     121             :   void reserveFlag( const std::string & k, const bool def, const std::string & d );
+     122             : /// Use one of the reserved keywords
+     123             :   void use( const std::string  & k );
+     124             : /// Get the ith keyword
+     125             :   std::string get( const unsigned k ) const ;
+     126             : /// Add a new keyword of type t with name k and description d
+     127             :   void add( const std::string & t, const std::string & k, const std::string & d );
+     128             : /// Add a new compulsory keyword (t must equal compulsory) with name k, default value def and description d
+     129             :   void add( const std::string & t, const std::string & k, const std::string & def, const std::string & d );
+     130             : /// Add a falg with name k that is by default on if def is true and off if def is false.  d should provide a description of the flag
+     131             :   void addFlag( const std::string & k, const bool def, const std::string & d );
+     132             : /// Remove the keyword with name k
+     133             :   void remove( const std::string & k );
+     134             : /// Check if there is a keyword with name k
+     135             :   bool exists( const std::string & k ) const ;
+     136             : /// Check the keyword k has been reserved
+     137             :   bool reserved( const std::string & k ) const ;
+     138             : /// Get the type for the keyword with string k
+     139             :   std::string getStyle( const std::string & k ) const ;
+     140             : /// Check if the keyword with name k has style t
+     141             :   bool style( const std::string & k, const std::string & t ) const ;
+     142             : /// Print an html version of the documentation
+     143             :   void print_html() const ;
+     144             : /// Print keywords in form readable by vim
+     145             :   void print_vim() const ;
+     146             : /// Print the template version for the documentation
+     147             :   void print_template( const std::string& actionname, bool include_optional) const ;
+     148             : /// Change the style of a keyword
+     149             :   void reset_style( const std::string & k, const std::string & style );
+     150             : /// Add keywords from one keyword object to another
+     151             :   void add( const Keywords& keys );
+     152             : /// Copy the keywords data
+     153             :   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+     154             :                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+     155             :                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+     156             :                  std::map<std::string,std::string>& cd ) const ;
+     157             : /// Clear everything from the keywords object.
+     158             : /// Not actually needed if your Keywords object is going out of scope.
+     159             :   void destroyData();
+     160             : /// Set the text that introduces how the components for this action are introduced
+     161             :   void setComponentsIntroduction( const std::string& instr );
+     162             : /// Add a potential component which can be output by this particular action
+     163             :   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
+     164             : /// Has a component with this name been added?
+     165             :   bool outputComponentExists( const std::string& name, const bool& custom ) const ;
+     166             : /// Get the flag that forces this component to be calculated
+     167             :   std::string getOutputComponentFlag( const std::string& name ) const ;
+     168             : /// Get the description of this component
+     169             :   std::string getOutputComponentDescription( const std::string& name ) const ;
+     170             : /// Get the full list of output components
+     171             :   std::vector<std::string> getOutputComponents() const ;
+     172             : /// Get the description of a particular keyword
+     173             :   std::string getKeywordDescription( const std::string& name ) const ;
+     174             : /// Remove a component with a particular name from the keywords
+     175             :   void removeComponent( const std::string& name );
+     176             : /// Reference to keys
+     177           0 :   std::vector<std::string> getKeys() const { return keys; }
+     178             : /// Get the description of a particular keyword
+     179             :   std::string getTooltip( const std::string& name ) const ;
+     180             : };
+     181             : 
+     182             : }
+     183             : 
+     184             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func-sort-c.html b/coverage/tools/LatticeReduction.cpp.func-sort-c.html new file mode 100644 index 0000000000..e5fa41cad3 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_13TensorGenericILj3ELj3EEE20632
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE20633
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_27311
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE47938
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func.html b/coverage/tools/LatticeReduction.cpp.func.html new file mode 100644 index 0000000000..5843e89115 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE20633
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE47938
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE20632
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_27311
_ZN4PLMD16LatticeReduction7reduce2ERNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD16LatticeReduction7reduce2ERNS_13VectorGenericILj3EEES3_S3_1
_ZN4PLMD16LatticeReduction9isReducedERKNS_13TensorGenericILj3ELj3EEE2
_ZN4PLMD16LatticeReduction9isReducedERKNS_13VectorGenericILj3EEES4_11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.gcov.html b/coverage/tools/LatticeReduction.cpp.gcov.html new file mode 100644 index 0000000000..e4f607c3cf --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + 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-05-27 13:05: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       47938 : void LatticeReduction::sort(Vector v[3]) {
+      32             :   const double onePlusEpsilon=(1.0+epsilon);
+      33             :   double m[3];
+      34       47938 :   m[0]=modulo2(v[0]);
+      35       47938 :   m[1]=modulo2(v[1]);
+      36       47938 :   m[2]=modulo2(v[2]);
+      37      335566 :   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       47938 :   plumed_assert(m[0]<=m[1]*onePlusEpsilon);
+      42       47938 :   plumed_assert(m[1]<=m[2]*onePlusEpsilon);
+      43       47938 : }
+      44             : 
+      45       27311 : void LatticeReduction::reduce(Vector&a,Vector&b) {
+      46             :   const double onePlusEpsilon=(1.0+epsilon);
+      47       27311 :   double ma=modulo2(a);
+      48       27311 :   double mb=modulo2(b);
+      49             :   unsigned counter=0;
+      50             :   while(true) {
+      51       27877 :     if(mb>ma) {
+      52             :       std::swap(a,b);
+      53             :       std::swap(ma,mb);
+      54             :     }
+      55       27877 :     a-=b*floor(dotProduct(a,b)/mb+0.5);
+      56       27877 :     ma=modulo2(a);
+      57       27877 :     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       27311 : }
+      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       20632 : void LatticeReduction::reduce(Tensor&t) {
+     112       20632 :   reduceFast(t);
+     113       20632 : }
+     114             : 
+     115       20633 : void LatticeReduction::reduceFast(Tensor&t) {
+     116             :   const double onePlusEpsilon=(1.0+epsilon);
+     117       82532 :   Vector v[3];
+     118       20633 :   v[0]=t.getRow(0);
+     119       20633 :   v[1]=t.getRow(1);
+     120       20633 :   v[2]=t.getRow(2);
+     121             :   unsigned counter=0;
+     122             :   while(true) {
+     123       27304 :     sort(v);
+     124       27304 :     reduce(v[0],v[1]);
+     125       27304 :     double b11=modulo2(v[0]);
+     126       27304 :     double b22=modulo2(v[1]);
+     127       27304 :     double b12=dotProduct(v[0],v[1]);
+     128       27304 :     double b13=dotProduct(v[0],v[2]);
+     129       27304 :     double b23=dotProduct(v[1],v[2]);
+     130       27304 :     double z=b11*b22-b12*b12;
+     131       27304 :     double y2=-(b11*b23-b12*b13)/z;
+     132       27304 :     double y1=-(b22*b13-b12*b23)/z;
+     133       27304 :     int x1min=floor(y1);
+     134       27304 :     int x1max=x1min+1;
+     135       27304 :     int x2min=floor(y2);
+     136       27304 :     int x2max=x2min+1;
+     137             :     bool first=true;
+     138             :     double mbest,mtrial;
+     139       27304 :     Vector trial,best;
+     140       81912 :     for(int x1=x1min; x1<=x1max; x1++)
+     141      163824 :       for(int x2=x2min; x2<=x2max; x2++) {
+     142      109216 :         trial=v[2]+x2*v[1]+x1*v[0];
+     143      109216 :         mtrial=modulo2(trial);
+     144      109216 :         if(first || mtrial<mbest) {
+     145             :           mbest=mtrial;
+     146       34848 :           best=trial;
+     147             :           first=false;
+     148             :         }
+     149             :       }
+     150       27304 :     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       20633 :   sort(v);
+     156       20633 :   t.setRow(0,v[0]);
+     157       20633 :   t.setRow(1,v[1]);
+     158       20633 :   t.setRow(2,v[2]);
+     159       20633 : }
+     160             : 
+     161             : 
+     162           1 : void LatticeReduction::reduceSlow(Tensor&t) {
+     163           4 :   Vector v[3];
+     164           1 :   v[0]=t.getRow(0);
+     165           1 :   v[1]=t.getRow(1);
+     166           1 :   v[2]=t.getRow(2);
+     167           1 :   reduce2(v[0],v[1],v[2]);
+     168           1 :   double e01=dotProduct(v[0],v[1]);
+     169           1 :   double e02=dotProduct(v[0],v[2]);
+     170           1 :   double e12=dotProduct(v[1],v[2]);
+     171           1 :   if(e01*e02*e12<0) {
+     172           0 :     int eps01=0; if(e01>0.0) eps01=1; else if(e01<0.0) eps01=-1;
+     173           0 :     int eps02=0; if(e02>0.0) eps02=1; else if(e02<0.0) eps02=-1;
+     174           0 :     Vector n=v[0]-eps01*v[1]-eps02*v[2];
+     175           0 :     int i=0; double mx=modulo2(v[i]);
+     176           0 :     for(int j=1; j<3; j++) {
+     177           0 :       double f=modulo2(v[j]);
+     178           0 :       if(f>mx) {
+     179             :         i=j;
+     180             :         mx=f;
+     181             :       }
+     182             :     }
+     183           0 :     if(modulo2(n)<mx) v[i]=n;
+     184             :   }
+     185           1 :   sort(v);
+     186           1 :   t.setRow(0,v[0]);
+     187           1 :   t.setRow(1,v[1]);
+     188           1 :   t.setRow(2,v[2]);
+     189           1 : }
+     190             : 
+     191           0 : bool LatticeReduction::isReduced2(const Vector&a,const Vector&b,const Vector &c) {
+     192           0 :   return isReduced(a,b) && isReduced(a,b) && isReduced(b,c);
+     193             : }
+     194             : 
+     195           2 : bool LatticeReduction::isReduced(const Tensor&t) {
+     196           8 :   Vector v[3];
+     197             :   double m[3];
+     198           2 :   v[0]=t.getRow(0);
+     199           2 :   v[1]=t.getRow(1);
+     200           2 :   v[2]=t.getRow(2);
+     201           8 :   for(int i=0; i<3; i++) m[i]=modulo2(v[i]);
+     202           2 :   if(!((m[0]<=m[1]) && m[1]<=m[2])) return false;
+     203             :   const int cut=5;
+     204          13 :   for(int i=-cut; i<=cut; i++) {
+     205          12 :     double mm=modulo2(v[1]+i*v[0]);
+     206          12 :     if(mm<m[1]) return false;
+     207         142 :     for(int j=-cut; j<=cut; j++) {
+     208         131 :       double mx=modulo2(v[2]+i*v[1]+j*v[0]);
+     209         131 :       if(mx<m[2])return false;
+     210             :     }
+     211             :   }
+     212             :   return true;
+     213             : }
+     214             : 
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func-sort-c.html b/coverage/tools/LinkCells.cpp.func-sort-c.html new file mode 100644 index 0000000000..8b26c9d435 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9LinkCells9getCutoffEv8
_ZN4PLMD9LinkCells9setCutoffERKd385
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE703
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1295
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE227239
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_227239
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409838
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409838
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE637077
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func.html b/coverage/tools/LinkCells.cpp.func.html new file mode 100644 index 0000000000..b8ecaa800b --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1295
_ZN4PLMD9LinkCells9setCutoffERKd385
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE703
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE637077
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE227239
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_227239
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409838
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409838
_ZNK4PLMD9LinkCells9getCutoffEv8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.gcov.html b/coverage/tools/LinkCells.cpp.gcov.html new file mode 100644 index 0000000000..fc76ca03c1 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + 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-05-27 13:05: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         703 : LinkCells::LinkCells( Communicator& cc ) :
+      29         703 :   comm(cc),
+      30         703 :   cutoffwasset(false),
+      31         703 :   link_cutoff(0.0),
+      32         703 :   ncells(3),
+      33        1406 :   nstride(3)
+      34             : {
+      35         703 : }
+      36             : 
+      37         385 : void LinkCells::setCutoff( const double& lcut ) {
+      38         385 :   cutoffwasset=true; link_cutoff=lcut;
+      39         385 : }
+      40             : 
+      41           8 : double LinkCells::getCutoff() const {
+      42           8 :   plumed_assert( cutoffwasset ); return link_cutoff;
+      43             : }
+      44             : 
+      45        1295 : void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ) {
+      46        1295 :   plumed_assert( cutoffwasset && pos.size()==indices.size() );
+      47             : 
+      48             :   // Must be able to check that pbcs are not nonsensical in some way?? -- GAT
+      49             : 
+      50             :   // Setup the pbc object by copying it from action
+      51        1295 :   mypbc.setBox( pbc.getBox() );
+      52             : 
+      53             :   // Setup the lists
+      54        1295 :   if( pos.size()!=allcells.size() ) {
+      55         313 :     allcells.resize( pos.size() ); lcell_lists.resize( pos.size() );
+      56             :   }
+      57             : 
+      58             :   {
+      59             : // This is the reciprocal lattice
+      60             : // notice that reciprocal.getRow(0) is a vector that is orthogonal to b and c
+      61             : // This allows to use linked cells in non orthorhomic boxes
+      62        1295 :     Tensor reciprocal(transpose(mypbc.getInvBox()));
+      63        1295 :     ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff );
+      64        1295 :     if( ncells[0]==0 ) ncells[0]=1;
+      65        1295 :     ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff );
+      66        1295 :     if( ncells[1]==0 ) ncells[1]=1;
+      67        1295 :     ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff );
+      68        1295 :     if( ncells[2]==0 ) ncells[2]=1;
+      69             :   }
+      70             :   // Setup the strides
+      71        1295 :   nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1];
+      72             : 
+      73             :   // Setup the storage for link cells
+      74        1295 :   unsigned ncellstot=ncells[0]*ncells[1]*ncells[2];
+      75        1295 :   if( lcell_tots.size()!=ncellstot ) {
+      76         303 :     lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot );
+      77             :   }
+      78             :   // Clear nlcells
+      79      299535 :   for(unsigned i=0; i<ncellstot; ++i) lcell_tots[i]=0;
+      80             :   // Clear allcells
+      81        1295 :   allcells.assign( allcells.size(), 0 );
+      82             : 
+      83             :   // Find out what cell everyone is in
+      84        1295 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      85      411133 :   for(unsigned i=rank; i<pos.size(); i+=size) {
+      86      409838 :     allcells[i]=findCell( pos[i] );
+      87      409838 :     lcell_tots[allcells[i]]++;
+      88             :   }
+      89             :   // And gather all this information on every node
+      90        1295 :   comm.Sum( allcells ); comm.Sum( lcell_tots );
+      91             : 
+      92             :   // Now prepare the link cell lists
+      93             :   unsigned tot=0;
+      94      299535 :   for(unsigned i=0; i<lcell_tots.size(); ++i) { lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; }
+      95        1295 :   plumed_assert( tot==pos.size() );
+      96             : 
+      97             :   // And setup the link cells properly
+      98      456412 :   for(unsigned j=0; j<pos.size(); ++j) {
+      99      455117 :     unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ];
+     100      455117 :     lcell_lists[ myind ] = indices[j];
+     101      455117 :     lcell_tots[allcells[j]]++;
+     102             :   }
+     103        1295 : }
+     104             : 
+     105             : #define LINKC_MIN(n) ((n<2)? 0 : -1)
+     106             : #define LINKC_MAX(n) ((n<3)? 1 : 2)
+     107             : #define LINKC_PBC(n,num) ((n<0)? num-1 : n%num )
+     108             : 
+     109      227239 : 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     1298325 :   for(int nx=LINKC_MIN(ncells[0]); nx<LINKC_MAX(ncells[0]); ++nx) {
+     113      433287 :     int xval = celn[0] + nx;
+     114      433287 :     xval=LINKC_PBC(xval,ncells[0])*nstride[0];
+     115     3144327 :     for(int ny=LINKC_MIN(ncells[1]); ny<LINKC_MAX(ncells[1]); ++ny) {
+     116     1049433 :       int yval = celn[1] + ny;
+     117     1049433 :       yval=LINKC_PBC(yval,ncells[1])*nstride[1];
+     118     8649248 :       for(int nz=LINKC_MIN(ncells[2]); nz<LINKC_MAX(ncells[2]); ++nz) {
+     119     2886542 :         int zval = celn[2] + nz;
+     120     2886542 :         zval=LINKC_PBC(zval,ncells[2])*nstride[2];
+     121             : 
+     122     2886542 :         unsigned mybox=xval+yval+zval; bool added=false;
+     123     2886542 :         for(unsigned k=0; k<ncells_required; ++k) {
+     124           0 :           if( mybox==cells_required[k] ) { added=true; break; }
+     125             :         }
+     126     2886542 :         if( !added ) { cells_required[ncells_required+nnew_cells]=mybox; nnew_cells++; }
+     127             :       }
+     128             :     }
+     129             :   }
+     130      227239 :   ncells_required += nnew_cells;
+     131      227239 : }
+     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      227239 : void LinkCells::retrieveAtomsInCells( const unsigned& ncells_required,
+     141             :                                       const std::vector<unsigned>& cells_required,
+     142             :                                       unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     143      227239 :   plumed_assert( natomsper==1 || natomsper==2 );  // This is really a bug. If you are trying to reuse this ask GAT for help
+     144     3113781 :   for(unsigned i=0; i<ncells_required; ++i) {
+     145     2886542 :     unsigned mybox=cells_required[i];
+     146   407341248 :     for(unsigned k=0; k<lcell_tots[mybox]; ++k) {
+     147   404454706 :       unsigned myatom = lcell_lists[lcell_starts[mybox]+k];
+     148   404454706 :       if( myatom!=atoms[0] ) { // Ideally would provide an option to not do this
+     149   404273206 :         atoms[natomsper]=myatom;
+     150   404273206 :         natomsper++;
+     151             :       }
+     152             :     }
+     153             :   }
+     154      227239 : }
+     155             : 
+     156      637077 : std::array<unsigned,3> LinkCells::findMyCell( const Vector& pos ) const {
+     157      637077 :   Vector fpos=mypbc.realToScaled( pos );
+     158             :   std::array<unsigned,3> celn;
+     159     2548308 :   for(unsigned j=0; j<3; ++j) {
+     160     1911231 :     celn[j] = std::floor( ( Tools::pbc(fpos[j]) + 0.5 ) * ncells[j] );
+     161     1911231 :     plumed_assert( celn[j]>=0 && celn[j]<ncells[j] ); // Check that atom is in box
+     162             :   }
+     163      637077 :   return celn;
+     164             : }
+     165             : 
+     166      409838 : unsigned LinkCells::convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const {
+     167      409838 :   return nx*nstride[0] + ny*nstride[1] + nz*nstride[2];
+     168             : }
+     169             : 
+     170      409838 : unsigned LinkCells::findCell( const Vector& pos ) const {
+     171      409838 :   std::array<unsigned,3> celn( findMyCell(pos ) );
+     172      409838 :   return convertIndicesToIndex( celn[0], celn[1], celn[2] );
+     173             : }
+     174             : 
+     175             : 
+     176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func-sort-c.html b/coverage/tools/LinkCells.h.func-sort-c.html new file mode 100644 index 0000000000..de278edbcf --- /dev/null +++ b/coverage/tools/LinkCells.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func.html b/coverage/tools/LinkCells.h.func.html new file mode 100644 index 0000000000..cc12232308 --- /dev/null +++ b/coverage/tools/LinkCells.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.gcov.html b/coverage/tools/LinkCells.h.gcov.html new file mode 100644 index 0000000000..bbba74749d --- /dev/null +++ b/coverage/tools/LinkCells.h.gcov.html @@ -0,0 +1,175 @@ + + + + + + + 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-05-27 13:05: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        1940 :   return cutoffwasset;
+      90             : }
+      91             : 
+      92             : inline
+      93             : unsigned LinkCells::getNumberOfCells() const {
+      94      227239 :   return ncells[0]*ncells[1]*ncells[2];
+      95             : }
+      96             : 
+      97             : }
+      98             : 
+      99             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func-sort-c.html b/coverage/tools/LoopUnroller.h.func-sort-c.html new file mode 100644 index 0000000000..a4e5ea9447 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func-sort-c.html @@ -0,0 +1,280 @@ + + + + + + + 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-05-27 13:05:14Functions:5252100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd48194355
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd59077181
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd59077181
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd59077181
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd59081185
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd59081185
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd61377631
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd106155620
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd106155620
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166491732
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166491732
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd554623549
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd554623549
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd785291901
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd785291901
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1266687419
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1266687419
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1790236473
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1790236473
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1979447196
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1979447196
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func.html b/coverage/tools/LoopUnroller.h.func.html new file mode 100644 index 0000000000..c3383046b4 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func.html @@ -0,0 +1,280 @@ + + + + + + + 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-05-27 13:05: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_addEPdPKd1790236473
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166491732
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1979447196
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd106155620
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1266687419
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd785291901
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd554623549
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1790236473
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166491732
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1979447196
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd106155620
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1266687419
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd785291901
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd554623549
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd48194355
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd61377631
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd59081185
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd59081185
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd59077181
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd59077181
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42880312
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd154207316
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63425
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd47075253
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd59077181
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.gcov.html b/coverage/tools/LoopUnroller.h.gcov.html new file mode 100644 index 0000000000..954629a1c7 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.gcov.html @@ -0,0 +1,236 @@ + + + + + + + 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-05-27 13:05: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  1501036644 : void LoopUnroller<n>::_zero(double*d) {
+      78   946413095 :   LoopUnroller<n-1>::_zero(d);
+      79  1501036644 :   d[n-1]=0.0;
+      80  1501036644 : }
+      81             : 
+      82             : template<>
+      83             : inline
+      84             : void LoopUnroller<1>::_zero(double*d) {
+      85   555172469 :   d[0]=0.0;
+      86             : }
+      87             : 
+      88             : template<unsigned n>
+      89  3837754818 : void LoopUnroller<n>::_add(double*d,const double*a) {
+      90  2047518345 :   LoopUnroller<n-1>::_add(d,a);
+      91  3837754818 :   d[n-1]+=a[n-1];
+      92  3837754818 : }
+      93             : 
+      94             : template<>
+      95             : inline
+      96             : void LoopUnroller<1>::_add(double*d,const double*a) {
+      97  1790236473 :   d[0]+=a[0];
+      98             : }
+      99             : 
+     100             : template<unsigned n>
+     101  2816945458 : void LoopUnroller<n>::_sub(double*d,const double*a) {
+     102  1550258039 :   LoopUnroller<n-1>::_sub(d,a);
+     103  2816945458 :   d[n-1]-=a[n-1];
+     104  2816945458 : }
+     105             : 
+     106             : template<>
+     107             : inline
+     108             : void LoopUnroller<1>::_sub(double*d,const double*a) {
+     109  1266687419 :   d[0]-=a[0];
+     110             : }
+     111             : 
+     112             : template<unsigned n>
+     113  4884138288 : void LoopUnroller<n>::_mul(double*d,const double s) {
+     114  2904691092 :   LoopUnroller<n-1>::_mul(d,s);
+     115  4884138288 :   d[n-1]*=s;
+     116  4884138288 : }
+     117             : 
+     118             : template<>
+     119             : inline
+     120             : void LoopUnroller<1>::_mul(double*d,const double s) {
+     121  1979447196 :   d[0]*=s;
+     122             : }
+     123             : 
+     124             : template<unsigned n>
+     125   212691790 : void LoopUnroller<n>::_neg(double*d,const double*a ) {
+     126   106536170 :   LoopUnroller<n-1>::_neg(d,a);
+     127   212691790 :   d[n-1]=-a[n-1];
+     128   212691790 : }
+     129             : 
+     130             : template<>
+     131             : inline
+     132             : void LoopUnroller<1>::_neg(double*d,const double*a) {
+     133   106155620 :   d[0]=-a[0];
+     134             : }
+     135             : 
+     136             : template<unsigned n>
+     137  1571702904 : double LoopUnroller<n>::_sum2(const double*d) {
+     138  1571702904 :   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   785291901 :   return d[0]*d[0];
+     145             : }
+     146             : 
+     147             : template<unsigned n>
+     148   332983464 : double LoopUnroller<n>::_dot(const double*d,const double*v) {
+     149   332983464 :   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   166491732 :   return d[0]*v[0];
+     156             : }
+     157             : 
+     158             : }
+     159             : 
+     160             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func-sort-c.html b/coverage/tools/Matrix.h.func-sort-c.html new file mode 100644 index 0000000000..4c0de20ba3 --- /dev/null +++ b/coverage/tools/Matrix.h.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func.html b/coverage/tools/Matrix.h.func.html new file mode 100644 index 0000000000..9d76f4740b --- /dev/null +++ b/coverage/tools/Matrix.h.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Matrix.h.gcov.html b/coverage/tools/Matrix.h.gcov.html new file mode 100644 index 0000000000..bf439e6090 --- /dev/null +++ b/coverage/tools/Matrix.h.gcov.html @@ -0,0 +1,490 @@ + + + + + + + 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-05-27 13:05: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     9736586 : 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    10723152 :   explicit Matrix(const unsigned nr=0, const unsigned nc=0 )  : sz(nr*nc), rw(nr), cl(nc), data(nr*nc) {}
+      91         259 :   Matrix(const Matrix<T>& t) : sz(t.sz), rw(t.rw), cl(t.cl), data(t.data) {}
+      92             :   /// Resize the matrix
+      93         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      232782 :     if(j<n) if(eigenvecs(i,j)<0.0) for(j=0; j<n; j++) eigenvecs(i,j)*=-1;
+     256             :   }
+     257             :   return 0;
+     258             : }
+     259             : 
+     260           1 : template <typename T> int pseudoInvert( const Matrix<T>& A, Matrix<double>& pseudoinverse ) {
+     261           1 :   std::vector<double> da(A.sz);
+     262             :   unsigned k=0;
+     263             :   // Transfer the matrix to the local array
+     264      250501 :   for (unsigned i=0; i<A.cl; ++i) for (unsigned j=0; j<A.rw; ++j) da[k++]=static_cast<double>( A(j,i) );
+     265             : 
+     266           1 :   int nsv, info, nrows=A.rw, ncols=A.cl;
+     267           1 :   if(A.rw>A.cl) {nsv=A.cl;} else {nsv=A.rw;}
+     268             : 
+     269             :   // Create some containers for stuff from single value decomposition
+     270           1 :   std::vector<double> S(nsv);
+     271           1 :   std::vector<double> U(nrows*nrows);
+     272           1 :   std::vector<double> VT(ncols*ncols);
+     273           1 :   std::vector<int> iwork(8*nsv);
+     274             : 
+     275             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     276           1 :   int lwork=-1;
+     277           1 :   std::vector<double> work(1);
+     278           1 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     279           1 :   if(info!=0) return info;
+     280             : 
+     281             :   // Retrieve correct sizes for work and rellocate
+     282           1 :   lwork=(int) work[0]; work.resize(lwork);
+     283             : 
+     284             :   // This does the singular value decomposition
+     285           1 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     286           1 :   if(info!=0) return info;
+     287             : 
+     288             :   // Compute the tolerance on the singular values ( machine epsilon * number of singular values * maximum singular value )
+     289         500 :   double tol; tol=S[0]; for(int i=1; i<nsv; ++i) { if( S[i]>tol ) { tol=S[i]; } } tol*=nsv*epsilon;
+     290             : 
+     291             :   // Get the inverses of the singlular values
+     292           1 :   Matrix<double> Si( ncols, nrows ); Si=0.0;
+     293         501 :   for(int i=0; i<nsv; ++i) { if( S[i]>tol ) { Si(i,i)=1./S[i]; } else { Si(i,i)=0.0; } }
+     294             : 
+     295             :   // Now extract matrices for pseudoinverse
+     296           1 :   Matrix<double> V( ncols, ncols ), UT( nrows, nrows ), tmp( ncols, nrows );
+     297      250501 :   k=0; for(int i=0; i<nrows; ++i) { for(int j=0; j<nrows; ++j) { UT(i,j)=U[k++]; } }
+     298      250501 :   k=0; for(int i=0; i<ncols; ++i) { for(int j=0; j<ncols; ++j) { V(i,j)=VT[k++]; } }
+     299             : 
+     300             :   // And do matrix algebra to construct the pseudoinverse
+     301           1 :   if( pseudoinverse.rw!=ncols || pseudoinverse.cl!=nrows ) pseudoinverse.resize( ncols, nrows );
+     302           1 :   mult( V, Si, tmp ); mult( tmp, UT, pseudoinverse );
+     303             : 
+     304             :   return 0;
+     305             : }
+     306             : 
+     307        9383 : template <typename T> int Invert( const Matrix<T>& A, Matrix<double>& inverse ) {
+     308             : 
+     309        9383 :   if( A.isSymmetric()==1 ) {
+     310             :     // GAT -- I only ever use symmetric matrices so I can invert them like this.
+     311             :     // I choose to do this as I have had problems with the more general way of doing this that
+     312             :     // is implemented below.
+     313        9326 :     std::vector<double> eval(A.rw); Matrix<double> evec(A.rw,A.cl), tevec(A.rw,A.cl);
+     314        9326 :     int err; err=diagMat( A, eval, evec );
+     315        9326 :     if(err!=0) return err;
+     316       64900 :     for (unsigned i=0; i<A.rw; ++i) for (unsigned j=0; j<A.cl; ++j) tevec(i,j)=evec(j,i)/eval[j];
+     317        9326 :     mult(tevec,evec,inverse);
+     318             :   } else {
+     319          57 :     std::vector<double> da(A.sz);
+     320          57 :     std::vector<int> ipiv(A.cl);
+     321          57 :     unsigned k=0; int n=A.rw, info;
+     322         399 :     for(unsigned i=0; i<A.cl; ++i) for(unsigned j=0; j<A.rw; ++j) da[k++]=static_cast<double>( A(j,i) );
+     323             : 
+     324          57 :     plumed_lapack_dgetrf(&n,&n,da.data(),&n,ipiv.data(),&info);
+     325          57 :     if(info!=0) return info;
+     326             : 
+     327          57 :     int lwork=-1;
+     328          57 :     std::vector<double> work(A.cl);
+     329          57 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     330          57 :     if(info!=0) return info;
+     331             : 
+     332          57 :     lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     333          57 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     334          57 :     if(info!=0) return info;
+     335             : 
+     336          57 :     if( inverse.cl!=A.cl || inverse.rw!=A.rw ) { inverse.resize(A.rw,A.cl); }
+     337         399 :     k=0; for(unsigned i=0; i<A.rw; ++i) for(unsigned j=0; j<A.cl; ++j) inverse(j,i)=da[k++];
+     338             :   }
+     339             : 
+     340             :   return 0;
+     341             : }
+     342             : 
+     343         446 : template <typename T> void cholesky( const Matrix<T>& A, Matrix<T>& B ) {
+     344             : 
+     345         446 :   plumed_assert( A.rw==A.cl && A.isSymmetric() );
+     346             :   Matrix<T> L(A.rw,A.cl); L=0.;
+     347         446 :   std::vector<T> D(A.rw,0.);
+     348        1047 :   for(unsigned i=0; i<A.rw; ++i) {
+     349         601 :     L(i,i)=static_cast<T>( 1 );
+     350         756 :     for (unsigned j=0; j<i; ++j) {
+     351         155 :       L(i,j)=A(i,j);
+     352         155 :       for (unsigned k=0; k<j; ++k) L(i,j)-=L(i,k)*L(j,k)*D[k];
+     353         155 :       if (D[j]!=0.) L(i,j)/=D[j]; else L(i,j)=static_cast<T>( 0 );
+     354             :     }
+     355         601 :     D[i]=A(i,i);
+     356         756 :     for (unsigned k=0; k<i; ++k) D[i]-=L(i,k)*L(i,k)*D[k];
+     357             :   }
+     358             : 
+     359        1047 :   for(unsigned i=0; i<A.rw; ++i) D[i]=(D[i]>0.?std::sqrt(D[i]):0.);
+     360         446 :   if( B.rw!=A.rw || B.cl!=A.cl ) { B.resize( A.rw, A.cl); }
+     361        1803 :   B=0.; for(unsigned i=0; i<A.rw; ++i) for(unsigned j=0; j<=i; ++j) B(i,j)+=L(i,j)*D[j];
+     362         446 : }
+     363             : 
+     364             : template <typename T> void chol_elsolve( const Matrix<T>& M, const std::vector<T>& b, std::vector<T>& y ) {
+     365             : 
+     366             :   plumed_assert( M.rw==M.cl && M(0,1)==0.0 && b.size()==M.rw );
+     367             :   if( y.size()!=M.rw ) { y.resize( M.rw ); }
+     368             :   for(unsigned i=0; i<M.rw; ++i) {
+     369             :     y[i]=b[i];
+     370             :     for(unsigned j=0; j<i; ++j) y[i]-=M(i,j)*y[j];
+     371             :     y[i]*=1.0/M(i,i);
+     372             :   }
+     373             : }
+     374             : 
+     375          46 : template <typename T> int logdet( const Matrix<T>& M, double& ldet ) {
+     376             :   // Check matrix is square and symmetric
+     377          46 :   plumed_assert( M.rw==M.cl || M.isSymmetric() );
+     378             : 
+     379          46 :   std::vector<double> da(M.sz);
+     380             :   unsigned k=0;
+     381          46 :   std::vector<double> evals(M.cl);
+     382             :   // Transfer the matrix to the local array
+     383         578 :   for (unsigned i=0; i<M.rw; ++i) for (unsigned j=0; j<M.cl; ++j) da[k++]=static_cast<double>( M(j,i) );
+     384             : 
+     385          46 :   int n=M.cl; int lwork=-1, liwork=-1, info, m, one=1;
+     386          46 :   std::vector<double> work(M.rw);
+     387          46 :   std::vector<int> iwork(M.rw);
+     388          46 :   double vl, vu, abstol=0.0;
+     389          46 :   std::vector<int> isup(2*M.rw);
+     390          46 :   std::vector<double> evecs(M.sz);
+     391          46 :   plumed_lapack_dsyevr("N", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     392             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     393             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     394          46 :   if (info!=0) return info;
+     395             : 
+     396             :   // Retrieve correct sizes for work and iwork then reallocate
+     397          46 :   lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     398          46 :   liwork=iwork[0]; iwork.resize(liwork);
+     399             : 
+     400          46 :   plumed_lapack_dsyevr("N", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     401             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     402             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     403          46 :   if (info!=0) return info;
+     404             : 
+     405             :   // Transfer the eigenvalues and eigenvectors to the output
+     406         180 :   ldet=0; for(unsigned i=0; i<M.cl; i++) { ldet+=log(evals[i]); }
+     407             : 
+     408             :   return 0;
+     409             : }
+     410             : 
+     411             : 
+     412             : 
+     413             : }
+     414             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html new file mode 100644 index 0000000000..f38ffe0c32 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05:14Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j5433
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj5433
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj5433
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj16897856
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27681477
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27681477
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27681477
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj35212356
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func.html b/coverage/tools/MatrixSquareBracketsAccess.h.func.html new file mode 100644 index 0000000000..fa88314ece --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05:14Functions:1818100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27681477
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27681477
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j5433
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27681477
_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_rowixEj5433
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj5433
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html new file mode 100644 index 0000000000..c5c002da40 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html @@ -0,0 +1,214 @@ + + + + + + + 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-05-27 13:05: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        5433 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
+     101        5433 :   t(t),i(i) {}
+     102             : 
+     103             : template<class T,class C,class I,class J>
+     104    82566763 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
+     105    82566763 :   t(t),i(i) {}
+     106             : 
+     107             : template<class T,class C,class I,class J>
+     108        5433 : 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        5433 :   return (*static_cast<const T*>(&t))(i,j);
+     113             : }
+     114             : 
+     115             : template<class T,class C,class I,class J>
+     116    82566763 : 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    82566763 :   return (*static_cast<T*>(&t))(i,j);
+     121             : }
+     122             : 
+     123             : template<class T,class C,class I,class J>
+     124    82566763 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
+     125    82566763 :   return Row(*this,i);
+     126             : }
+     127             : 
+     128             : template<class T,class C,class I,class J>
+     129        5433 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
+     130        5433 :   return Const_row(*this,i);
+     131             : }
+     132             : 
+     133             : }
+     134             : 
+     135             : 
+     136             : #endif
+     137             : 
+     138             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func-sort-c.html b/coverage/tools/Minimise1DBrent.h.func-sort-c.html new file mode 100644 index 0000000000..c360bd15c7 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func.html b/coverage/tools/Minimise1DBrent.h.func.html new file mode 100644 index 0000000000..7002fd0cf1 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.gcov.html b/coverage/tools/Minimise1DBrent.h.gcov.html new file mode 100644 index 0000000000..109a97a409 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.gcov.html @@ -0,0 +1,271 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func-sort-c.html b/coverage/tools/MinimiseBase.h.func-sort-c.html new file mode 100644 index 0000000000..f8398136ec --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func-sort-c.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func.html b/coverage/tools/MinimiseBase.h.func.html new file mode 100644 index 0000000000..c6b077f66d --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func.html @@ -0,0 +1,144 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.gcov.html b/coverage/tools/MinimiseBase.h.gcov.html new file mode 100644 index 0000000000..1b3b560de0 --- /dev/null +++ b/coverage/tools/MinimiseBase.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + 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-05-27 13:05: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        2413 : class F1dim {
+      31             : private:
+      32             : /// This is the pointer to the member function in the energy
+      33             : /// calculating class that calculates the energy
+      34             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der ) const ;
+      35             :   typedef double(FCLASS::*engfnc_pointer)( const std::vector<double>& p, std::vector<double>& der ) ;
+      36             : /// Pointer to the vector containing an initial position on the vector
+      37             :   const std::vector<double>& p;
+      38             : /// The direction of the vector we are minimising along
+      39             :   const std::vector<double>& dir;
+      40             : /// Tempory vector that holds a point at which we want to calculate the energy
+      41             :   std::vector<double> pt;
+      42             : /// Vector that holds the derivatives at the point at which we calculate the energy (these are not used)
+      43             :   std::vector<double> fake_der;
+      44             : /// Class containging the function in the class
+      45             :   FCLASS* func;
+      46             : /// Member of class that calculates the energy we are trying to mnimise
+      47             :   engf_pointer calc;
+      48             : /// Member of class that calcualtes the energy we are trying to minimise
+      49             :   engfnc_pointer calc2;
+      50             : public:
+      51             :   explicit F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 );
+      52             : /// Calculate the energy at \f$\mathbf{p} + xt*\mathbf{dir}\f$
+      53             :   double getEng( const double& xt );
+      54             : };
+      55             : 
+      56             : template <class FCLASS>
+      57        2413 : F1dim<FCLASS>::F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 ):
+      58        2413 :   p(pp),
+      59        2413 :   dir(dd),
+      60        2413 :   pt(pp.size()),
+      61        2413 :   fake_der(pp.size()),
+      62        2413 :   func(ff),
+      63        2413 :   calc(cc),
+      64        2413 :   calc2(cc2)
+      65             : {
+      66        2413 :   plumed_assert( calc || calc2 );
+      67        2413 : }
+      68             : 
+      69             : template <class FCLASS>
+      70       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             : }
+     108             : 
+     109             : template <class FCLASS>
+     110         897 : double MinimiseBase<FCLASS>::calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc ) {
+     111         897 :   return (myclass_func->*myfunc)( p, der );
+     112             : }
+     113             : 
+     114             : }
+     115             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func-sort-c.html b/coverage/tools/MolDataClass.cpp.func-sort-c.html new file mode 100644 index 0000000000..49ffa00e3c --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func.html b/coverage/tools/MolDataClass.cpp.func.html new file mode 100644 index 0000000000..9f18a07f1e --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.gcov.html b/coverage/tools/MolDataClass.cpp.gcov.html new file mode 100644 index 0000000000..3aa935f171 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.gcov.html @@ -0,0 +1,663 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func-sort-c.html b/coverage/tools/MultiValue.cpp.func-sort-c.html new file mode 100644 index 0000000000..d57ee07c49 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue6resizeERKmS2_41860
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
_ZN4PLMD10MultiValueC2ERKmS2_360241
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502652
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1869892
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2099217
_ZN4PLMD10MultiValue8clearAllEv2099217
_ZN4PLMD10MultiValue5clearERKj8343013
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func.html b/coverage/tools/MultiValue.cpp.func.html new file mode 100644 index 0000000000..9f5a72cb86 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1869892
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2099217
_ZN4PLMD10MultiValue5clearERKj8343013
_ZN4PLMD10MultiValue6resizeERKmS2_41860
_ZN4PLMD10MultiValue8clearAllEv2099217
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502652
_ZN4PLMD10MultiValueC2ERKmS2_360241
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.gcov.html b/coverage/tools/MultiValue.cpp.gcov.html new file mode 100644 index 0000000000..52b70653aa --- /dev/null +++ b/coverage/tools/MultiValue.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + 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-05-27 13:05: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      360241 : MultiValue::MultiValue( const size_t& nvals, const size_t& nder ):
+      27      360241 :   values(nvals),
+      28      360241 :   nderivatives(nder),
+      29      360241 :   derivatives(nvals*nder),
+      30      360241 :   tmpval(0),
+      31      360241 :   tmpder(nder),
+      32      720482 :   atLeastOneSet(false)
+      33             : {
+      34      360241 :   std::vector<unsigned> myind( nder );
+      35    10704348 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      36      360241 :   hasDerivatives.createIndexListFromVector( myind );
+      37      360241 : }
+      38             : 
+      39       41860 : void MultiValue::resize( const size_t& nvals, const size_t& nder ) {
+      40       41860 :   values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
+      41       41860 :   tmpder.resize( nder ); hasDerivatives.clear(); std::vector<unsigned> myind( nder );
+      42    10858510 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      43       41860 :   hasDerivatives.createIndexListFromVector( myind );
+      44       41860 :   atLeastOneSet=false;
+      45       41860 : }
+      46             : 
+      47     2099217 : void MultiValue::clearAll() {
+      48     2099217 :   if( atLeastOneSet && !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      49    10442230 :   for(unsigned i=0; i<values.size(); ++i) clear(i);
+      50     2099217 :   clearTemporyDerivatives(); hasDerivatives.deactivateAll(); atLeastOneSet=false;
+      51     2099217 : }
+      52             : 
+      53     8343013 : void MultiValue::clear( const unsigned& ival ) {
+      54     8343013 :   values[ival]=0;
+      55     8343013 :   unsigned base=ival*nderivatives, ndert=hasDerivatives.getNumberActive();
+      56   311771833 :   for(unsigned i=0; i<ndert; ++i) derivatives[ base+hasDerivatives[i] ]=0.;
+      57     8343013 : }
+      58             : 
+      59     2099217 : void MultiValue::clearTemporyDerivatives() {
+      60     2099217 :   unsigned ndert=hasDerivatives.getNumberActive(); tmpval=0.;
+      61    82074873 :   for(unsigned i=0; i<ndert; ++i) tmpder[ hasDerivatives[i] ]=0.;
+      62     2099217 : }
+      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.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func-sort-c.html b/coverage/tools/MultiValue.h.func-sort-c.html new file mode 100644 index 0000000000..dee3aa54da --- /dev/null +++ b/coverage/tools/MultiValue.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd35718834
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145616121
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1359057968
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func.html b/coverage/tools/MultiValue.h.func.html new file mode 100644 index 0000000000..13218074d2 --- /dev/null +++ b/coverage/tools/MultiValue.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1359057968
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145616121
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd35718834
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.gcov.html b/coverage/tools/MultiValue.h.gcov.html new file mode 100644 index 0000000000..28b1789fd8 --- /dev/null +++ b/coverage/tools/MultiValue.h.gcov.html @@ -0,0 +1,317 @@ + + + + + + + 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-05-27 13:05: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   172403995 :   return values.size();
+     112             : }
+     113             : 
+     114             : inline
+     115             : unsigned MultiValue::getNumberOfDerivatives() const {
+     116    30913737 :   return nderivatives; //derivatives.ncols();
+     117             : }
+     118             : 
+     119             : inline
+     120             : double MultiValue::get( const unsigned& ival ) const {
+     121             :   plumed_dbg_assert( ival<=values.size() );
+     122   173450831 :   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     1829663 :   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    62235725 :   values[ival]+=val;
+     135             : }
+     136             : 
+     137             : inline
+     138  1359057968 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     139  1359057968 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     140  1359057968 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
+     141  1359057968 : }
+     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   145616121 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     157   145616121 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     158   145616121 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der;
+     159   145616121 : }
+     160             : 
+     161             : 
+     162             : inline
+     163             : double MultiValue::getDerivative( const unsigned& ival, const unsigned& jder ) const {
+     164             :   plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
+     165   535798761 :   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     1621315 :   return hasDerivatives.updateComplete();
+     177             : }
+     178             : 
+     179             : inline
+     180             : void MultiValue::emptyActiveMembers() {
+     181      932900 :   hasDerivatives.emptyActiveMembers();
+     182             : }
+     183             : 
+     184             : inline
+     185             : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
+     186    32661660 :   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      876595 :   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      919465 :   return indices;
+     223             : }
+     224             : 
+     225             : inline
+     226             : std::vector<unsigned>& MultiValue::getSortIndices() {
+     227      448077 :   return sort_indices;
+     228             : }
+     229             : 
+     230             : inline
+     231             : std::vector<Vector>& MultiValue::getAtomVector() {
+     232      678824 :   return tmp_atoms;
+     233             : }
+     234             : 
+     235             : inline
+     236             : bool MultiValue::isActive( const unsigned& ind ) const {
+     237   423958368 :   return hasDerivatives.isActive( ind );
+     238             : }
+     239             : 
+     240             : }
+     241             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func-sort-c.html b/coverage/tools/NeighborList.cpp.func-sort-c.html new file mode 100644 index 0000000000..ae5b35b9d5 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func.html b/coverage/tools/NeighborList.cpp.func.html new file mode 100644 index 0000000000..06883f2647 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.gcov.html b/coverage/tools/NeighborList.cpp.gcov.html new file mode 100644 index 0000000000..8788b94d44 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func-sort-c.html b/coverage/tools/NeighborList.h.func-sort-c.html new file mode 100644 index 0000000000..00b9fea838 --- /dev/null +++ b/coverage/tools/NeighborList.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborListD2Ev284
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func.html b/coverage/tools/NeighborList.h.func.html new file mode 100644 index 0000000000..4f46741703 --- /dev/null +++ b/coverage/tools/NeighborList.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborListD2Ev284
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.gcov.html b/coverage/tools/NeighborList.h.gcov.html new file mode 100644 index 0000000000..2456acb2c0 --- /dev/null +++ b/coverage/tools/NeighborList.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func-sort-c.html b/coverage/tools/OFile.cpp.func-sort-c.html new file mode 100644 index 0000000000..aa06fd2707 --- /dev/null +++ b/coverage/tools/OFile.cpp.func-sort-c.html @@ -0,0 +1,192 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-05-27 13:05:14Functions:293096.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3327
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3610
_ZNK4PLMD5OFile12checkRestartEv3646
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE5905
_ZN4PLMD5OFile5flushEv8753
_ZN4PLMD5OFileC1Ev14650
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27848
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd538348
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE805268
_ZN4PLMD5OFileC2Ev805268
_ZN4PLMD5OFile8fmtFieldEv825789
_ZN4PLMD5OFile10printFieldEv3929842
_ZN4PLMD5OFile7llwriteEPKcm5460517
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6074528
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14601947
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15531588
_ZN4PLMD5OFile6printfEPKcz23588119
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37423941
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func.html b/coverage/tools/OFile.cpp.func.html new file mode 100644 index 0000000000..d5738b2fc5 --- /dev/null +++ b/coverage/tools/OFile.cpp.func.html @@ -0,0 +1,192 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-05-27 13:05:14Functions:293096.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3327
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd538348
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37423941
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15531588
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6074528
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile10printFieldEv3929842
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE805268
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE5905
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27848
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3610
_ZN4PLMD5OFile5flushEv8753
_ZN4PLMD5OFile6printfEPKcz23588119
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile7llwriteEPKcm5460517
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14601947
_ZN4PLMD5OFile8fmtFieldEv825789
_ZN4PLMD5OFileC1Ev14650
_ZN4PLMD5OFileC2Ev805268
_ZNK4PLMD5OFile12checkRestartEv3646
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.gcov.html b/coverage/tools/OFile.cpp.gcov.html new file mode 100644 index 0000000000..96286cf554 --- /dev/null +++ b/coverage/tools/OFile.cpp.gcov.html @@ -0,0 +1,512 @@ + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-05-27 13:05:14Functions:293096.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OFile.h"
+      23             : #include "Exception.h"
+      24             : #include "core/Action.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "Communicator.h"
+      28             : #include "Tools.h"
+      29             : #include <cstdarg>
+      30             : #include <cstring>
+      31             : 
+      32             : #include <iostream>
+      33             : #include <string>
+      34             : #include <cstdlib>
+      35             : #include <cerrno>
+      36             : 
+      37             : #include <memory>
+      38             : #include <utility>
+      39             : 
+      40             : #ifdef __PLUMED_HAS_ZLIB
+      41             : #include <zlib.h>
+      42             : #endif
+      43             : 
+      44             : namespace PLMD {
+      45             : 
+      46     5460517 : size_t OFile::llwrite(const char*ptr,size_t s) {
+      47             :   size_t r;
+      48     5460517 :   if(linked) return linked->llwrite(ptr,s);
+      49     5460465 :   if(! (comm && comm->Get_rank()>0)) {
+      50     4636249 :     if(!fp) plumed_merror("writing on uninitialized File");
+      51     4636249 :     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     4634986 :       r=std::fwrite(ptr,1,s,fp);
+      59             :     }
+      60             :   }
+      61     5460465 :   if(comm) {
+      62             : //  This barrier is apparently useless since it comes
+      63             : //  just before a Bcast.
+      64             : //
+      65             : //  Anyway, it looks like it is solving an issue that appeared on
+      66             : //  TRAVIS (at least on my laptop) so I add it here.
+      67             : //  GB
+      68     4603431 :     comm->Barrier();
+      69     4603431 :     comm->Bcast(r,0);
+      70             :   }
+      71             : 
+      72     5460465 :   return r;
+      73             : }
+      74             : 
+      75      819918 : OFile::OFile():
+      76      819918 :   linked(NULL),
+      77      819918 :   fieldChanged(false),
+      78      819918 :   backstring("bck"),
+      79      819918 :   enforceRestart_(false),
+      80      819918 :   enforceBackup_(false)
+      81             : {
+      82      819918 :   fmtField();
+      83      819918 :   buflen=1;
+      84      819918 :   actual_buffer_length=0;
+      85      819918 :   buffer.resize(buflen);
+      86             : // these are set to zero to avoid valgrind errors
+      87     1639836 :   for(int i=0; i<buflen; ++i) buffer[i]=0;
+      88             : // these are set to zero to avoid valgrind errors
+      89      819918 :   buffer_string.resize(1000,0);
+      90      819918 : }
+      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      805268 : OFile& OFile::setLinePrefix(const std::string&l) {
+     100      805268 :   linePrefix=l;
+     101      805268 :   return *this;
+     102             : }
+     103             : 
+     104    23588119 : int OFile::printf(const char*fmt,...) {
+     105             :   va_list arg;
+     106    23588119 :   va_start(arg, fmt);
+     107    23588119 :   int r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     108    23588119 :   va_end(arg);
+     109    23588119 :   if(r>=buflen-actual_buffer_length) {
+     110             :     int newlen=buflen;
+     111       47782 :     while(newlen<=r+actual_buffer_length) newlen*=2;
+     112       16019 :     std::vector<char> newbuf(newlen);
+     113       16019 :     std::memmove(newbuf.data(),buffer.data(),buflen);
+     114     3288347 :     for(int k=buflen; k<newlen; k++) newbuf[k]=0;
+     115             :     std::swap(buffer,newbuf);
+     116       16019 :     buflen=newlen;
+     117             :     va_list arg;
+     118       16019 :     va_start(arg, fmt);
+     119       16019 :     r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     120       16019 :     va_end(arg);
+     121             :   }
+     122    23588119 :   plumed_massert(r>-1 && r<buflen-actual_buffer_length,"error using fmt string " + std::string(fmt));
+     123             : 
+     124             : // Line is buffered until newline, then written with a PLUMED: prefix
+     125             :   char*p1=buffer.data();
+     126             :   char*p2;
+     127             : // newline is only searched in the just added portion:
+     128    23588119 :   char*psearch=p1+actual_buffer_length;
+     129    23588119 :   actual_buffer_length+=r;
+     130    28811928 :   while((p2=std::strchr(psearch,'\n'))) {
+     131     5223809 :     if(linePrefix.length()>0) llwrite(linePrefix.c_str(),linePrefix.length());
+     132     5223809 :     llwrite(p1,p2-p1+1);
+     133     5223809 :     actual_buffer_length-=(p2-p1)+1;
+     134     5223809 :     p1=p2+1;
+     135             :     psearch=p1;
+     136             :   };
+     137    23588119 :   if(buffer.data()!=p1) std::memmove(buffer.data(),p1,actual_buffer_length);
+     138    23588119 :   return r;
+     139             : }
+     140             : 
+     141       27848 : OFile& OFile::addConstantField(const std::string&name) {
+     142             :   Field f;
+     143             :   f.name=name;
+     144       27848 :   const_fields.push_back(f);
+     145       27848 :   return *this;
+     146             : }
+     147             : 
+     148             : 
+     149        3202 : OFile& OFile::clearFields() {
+     150        3202 :   fields.clear();
+     151        3202 :   const_fields.clear();
+     152        3202 :   previous_fields.clear();
+     153        3202 :   return *this;
+     154             : }
+     155             : 
+     156    14601947 : OFile& OFile::fmtField(const std::string&fmt) {
+     157    14601947 :   this->fieldFmt=fmt;
+     158    14601947 :   return *this;
+     159             : }
+     160             : 
+     161      825789 : OFile& OFile::fmtField() {
+     162      825789 :   this->fieldFmt="%23.16lg";
+     163      825789 :   return *this;
+     164             : }
+     165             : 
+     166    15531588 : 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    15531588 :   if(std::isnan(v)) v=std::numeric_limits<double>::quiet_NaN();
+     171             :   std::snprintf(buffer_string.data(),buffer_string.size(),fieldFmt.c_str(),v);
+     172    15531588 :   printField(name,buffer_string.data());
+     173    15531588 :   return *this;
+     174             : }
+     175             : 
+     176     6074528 : OFile& OFile::printField(const std::string&name,int v) {
+     177             :   std::snprintf(buffer_string.data(),buffer_string.size()," %d",v);
+     178     6074528 :   printField(name,buffer_string.data());
+     179     6074528 :   return *this;
+     180             : }
+     181             : 
+     182           1 : OFile& OFile::printField(const std::string&name,long int v) {
+     183             :   std::snprintf(buffer_string.data(),buffer_string.size()," %ld",v);
+     184           1 :   printField(name,buffer_string.data());
+     185           1 :   return *this;
+     186             : }
+     187             : 
+     188           0 : OFile& OFile::printField(const std::string&name,long long int v) {
+     189             :   std::snprintf(buffer_string.data(),buffer_string.size()," %lld",v);
+     190           0 :   printField(name,buffer_string.data());
+     191           0 :   return *this;
+     192             : }
+     193             : 
+     194          31 : OFile& OFile::printField(const std::string&name,unsigned v) {
+     195             :   std::snprintf(buffer_string.data(),buffer_string.size()," %u",v);
+     196          31 :   printField(name,buffer_string.data());
+     197          31 :   return *this;
+     198             : }
+     199             : 
+     200           1 : OFile& OFile::printField(const std::string&name,long unsigned v) {
+     201             :   std::snprintf(buffer_string.data(),buffer_string.size()," %lu",v);
+     202           1 :   printField(name,buffer_string.data());
+     203           1 :   return *this;
+     204             : }
+     205             : 
+     206          47 : OFile& OFile::printField(const std::string&name,long long unsigned v) {
+     207             :   std::snprintf(buffer_string.data(),buffer_string.size()," %llu",v);
+     208          47 :   printField(name,buffer_string.data());
+     209          47 :   return *this;
+     210             : }
+     211             : 
+     212    37423941 : OFile& OFile::printField(const std::string&name,const std::string & v) {
+     213             :   unsigned i;
+     214   190174315 :   for(i=0; i<const_fields.size(); i++) if(const_fields[i].name==name) break;
+     215    37423941 :   if(i>=const_fields.size()) {
+     216             :     Field field;
+     217             :     field.name=name;
+     218             :     field.value=v;
+     219    16647223 :     fields.push_back(field);
+     220             :   } else {
+     221    20776718 :     if(const_fields[i].value!=v) fieldChanged=true;
+     222             :     const_fields[i].value=v;
+     223             :   }
+     224    37423941 :   return *this;
+     225             : }
+     226             : 
+     227        5905 : OFile& OFile::setupPrintValue( Value *val ) {
+     228        5905 :   if( val->isPeriodic() ) {
+     229         480 :     addConstantField("min_" + val->getName() );
+     230         960 :     addConstantField("max_" + val->getName() );
+     231             :   }
+     232        5905 :   return *this;
+     233             : }
+     234             : 
+     235      538348 : OFile& OFile::printField( Value* val, const double& v ) {
+     236      538348 :   printField( val->getName(), v );
+     237      538348 :   if( val->isPeriodic() ) {
+     238       12973 :     std::string min, max; val->getDomain( min, max );
+     239       12973 :     printField( "min_" + val->getName(), min );
+     240       25946 :     printField("max_" + val->getName(), max );
+     241             :   }
+     242      538348 :   return *this;
+     243             : }
+     244             : 
+     245     3929842 : OFile& OFile::printField() {
+     246             :   bool reprint=false;
+     247     3929842 :   if(fieldChanged || fields.size()!=previous_fields.size()) {
+     248             :     reprint=true;
+     249    20512897 :   } else for(unsigned i=0; i<fields.size(); i++) {
+     250    16589024 :       if( previous_fields[i].name!=fields[i].name ||
+     251    16589022 :           (fields[i].constant && fields[i].value!=previous_fields[i].value) ) {
+     252             :         reprint=true;
+     253             :         break;
+     254             :       }
+     255             :     }
+     256     3929842 :   if(reprint) {
+     257        5969 :     printf("#! FIELDS");
+     258       64172 :     for(unsigned i=0; i<fields.size(); i++) printf(" %s",fields[i].name.c_str());
+     259        5969 :     printf("\n");
+     260       33753 :     for(unsigned i=0; i<const_fields.size(); i++) {
+     261       27784 :       printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str());
+     262       27784 :       printf("\n");
+     263             :     }
+     264             :   }
+     265    20577065 :   for(unsigned i=0; i<fields.size(); i++) printf("%s",fields[i].value.c_str());
+     266     3929842 :   printf("\n");
+     267     3929842 :   previous_fields=fields;
+     268     3929842 :   fields.clear();
+     269     3929842 :   fieldChanged=false;
+     270     3929842 :   return *this;
+     271             : }
+     272             : 
+     273         121 : void OFile::setBackupString( const std::string& str ) {
+     274         121 :   backstring=str;
+     275         121 : }
+     276             : 
+     277          36 : void OFile::backupAllFiles( const std::string& str ) {
+     278          36 :   if(str=="/dev/null") return;
+     279          36 :   plumed_assert( backstring!="bck" && !checkRestart());
+     280          36 :   size_t found=str.find_last_of("/\\");
+     281          36 :   std::string filename = appendSuffix(str,getSuffix());
+     282          36 :   std::string directory=filename.substr(0,found+1);
+     283          36 :   std::string file=filename.substr(found+1);
+     284          36 :   if( FileExist(filename) ) backupFile("bck", filename);
+     285          36 :   for(int i=0;; i++) {
+     286          36 :     std::string num; Tools::convert(i,num);
+     287          72 :     std::string filestr = directory + backstring + "." + num + "." + file;
+     288          36 :     if( !FileExist(filestr) ) break;
+     289           0 :     backupFile( "bck", filestr);
+     290           0 :   }
+     291             : }
+     292             : 
+     293        3327 : void OFile::backupFile( const std::string& bstring, const std::string& fname ) {
+     294        3327 :   if(fname=="/dev/null") return;
+     295        3173 :   int maxbackup=100;
+     296        3173 :   if(std::getenv("PLUMED_MAXBACKUP")) Tools::convert(std::getenv("PLUMED_MAXBACKUP"),maxbackup);
+     297        3173 :   if(maxbackup>0 && (!comm || comm->Get_rank()==0)) {
+     298        2701 :     FILE* ff=std::fopen(const_cast<char*>(fname.c_str()),"r");
+     299        2701 :     if(ff) {
+     300             :       // no exception here
+     301          65 :       std::fclose(ff);
+     302             :       std::string backup;
+     303          65 :       size_t found=fname.find_last_of("/\\");
+     304          65 :       std::string directory=fname.substr(0,found+1);
+     305          65 :       std::string file=fname.substr(found+1);
+     306          65 :       for(int i=0;; i++) {
+     307             :         std::string num;
+     308          65 :         Tools::convert(i,num);
+     309          65 :         if(i>maxbackup) plumed_merror("cannot backup file "+file+" maximum number of backup is "+num+"\n");
+     310         130 :         backup=directory+bstring +"."+num+"."+file;
+     311          65 :         FILE* fff=std::fopen(backup.c_str(),"r");
+     312             :         // no exception here
+     313          65 :         if(!fff) break;
+     314           0 :         else std::fclose(fff);
+     315           0 :       }
+     316          65 :       int check=rename(fname.c_str(),backup.c_str());
+     317          65 :       plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322        3610 : OFile& OFile::open(const std::string&path) {
+     323        3610 :   plumed_assert(!cloned);
+     324        3610 :   eof=false;
+     325        3610 :   err=false;
+     326        3610 :   fp=NULL;
+     327        3610 :   gzfp=NULL;
+     328        3610 :   this->path=path;
+     329        7220 :   this->path=appendSuffix(path,getSuffix());
+     330        3610 :   if(checkRestart()) {
+     331         283 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"a");
+     332         283 :     mode="a";
+     333         566 :     if(Tools::extension(this->path)=="gz") {
+     334             : #ifdef __PLUMED_HAS_ZLIB
+     335          12 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"a9");
+     336             : #else
+     337             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     338             : #endif
+     339             :     }
+     340             :   } else {
+     341        3327 :     backupFile( backstring, this->path );
+     342        3327 :     if(comm)comm->Barrier();
+     343        3327 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"w");
+     344        3327 :     mode="w";
+     345        6654 :     if(Tools::extension(this->path)=="gz") {
+     346             : #ifdef __PLUMED_HAS_ZLIB
+     347          13 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     348             : #else
+     349             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     350             : #endif
+     351             :     }
+     352             :   }
+     353        3610 :   if(plumed) plumed->insertFile(*this);
+     354        3610 :   return *this;
+     355             : }
+     356             : 
+     357         135 : OFile& OFile::rewind() {
+     358             : // we use here "hard" rewind, which means close/reopen
+     359             : // the reason is that normal rewind does not work when in append mode
+     360             : // moreover, we can take a backup of the file
+     361         135 :   plumed_assert(fp);
+     362         135 :   clearFields();
+     363             : 
+     364         135 :   if(!comm || comm->Get_rank()==0) {
+     365         104 :     std::string fname=this->path;
+     366         104 :     size_t found=fname.find_last_of("/\\");
+     367         104 :     std::string directory=fname.substr(0,found+1);
+     368         104 :     std::string file=fname.substr(found+1);
+     369         208 :     std::string backup=directory+backstring +".last."+file;
+     370         104 :     int check=rename(fname.c_str(),backup.c_str());
+     371         104 :     plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     372             :   }
+     373             : 
+     374         135 :   if(comm) comm->Barrier();
+     375             : 
+     376         135 :   if(gzfp) {
+     377             : #ifdef __PLUMED_HAS_ZLIB
+     378          15 :     gzclose((gzFile)gzfp);
+     379             :     // no exception here
+     380          15 :     gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     381             : #endif
+     382             :   } else {
+     383         120 :     std::fclose(fp);
+     384             :     // no exception here
+     385         120 :     fp=std::fopen(const_cast<char*>(path.c_str()),"w");
+     386             :   }
+     387         135 :   return *this;
+     388             : }
+     389             : 
+     390        8753 : FileBase& OFile::flush() {
+     391        8753 :   if(heavyFlush) {
+     392        3909 :     if(gzfp) {
+     393             : #ifdef __PLUMED_HAS_ZLIB
+     394           9 :       gzclose(gzFile(gzfp));
+     395             :       // no exception here
+     396           9 :       gzfp=(void*)gzopen(const_cast<char*>(path.c_str()),"a");
+     397             : #endif
+     398             :     } else {
+     399        3900 :       std::fclose(fp);
+     400             :       // no exception here
+     401        3900 :       fp=std::fopen(const_cast<char*>(path.c_str()),"a");
+     402             :     }
+     403             :   } else {
+     404        4844 :     FileBase::flush();
+     405             :     // if(gzfp) gzflush(gzFile(gzfp),Z_FINISH);
+     406             :     // for some reason flushing with Z_FINISH has problems on linux
+     407             :     // I thus use this (incomplete) flush
+     408             : #ifdef __PLUMED_HAS_ZLIB
+     409        4844 :     if(gzfp) gzflush(gzFile(gzfp),Z_FULL_FLUSH);
+     410             : #endif
+     411             :   }
+     412        8753 :   return *this;
+     413             : }
+     414             : 
+     415        3646 : bool OFile::checkRestart()const {
+     416        3646 :   if(enforceRestart_) return true;
+     417        3645 :   else if(enforceBackup_) return false;
+     418        2501 :   else if(action) return action->getRestart();
+     419         219 :   else if(plumed) return plumed->getRestart();
+     420             :   else return false;
+     421             : }
+     422             : 
+     423           1 : OFile& OFile::enforceRestart() {
+     424           1 :   enforceRestart_=true;
+     425           1 :   enforceBackup_=false;
+     426           1 :   return *this;
+     427             : }
+     428             : 
+     429        1144 : OFile& OFile::enforceBackup() {
+     430        1144 :   enforceBackup_=true;
+     431        1144 :   enforceRestart_=false;
+     432        1144 :   return *this;
+     433             : }
+     434             : 
+     435             : 
+     436             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func-sort-c.html b/coverage/tools/OFile.h.func-sort-c.html new file mode 100644 index 0000000000..e1e8783e67 --- /dev/null +++ b/coverage/tools/OFile.h.func-sort-c.html @@ -0,0 +1,500 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_5
_ZN4PLMDlsIA62_cEERNS_5OFileES3_RKT_7
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA56_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA61_cEERNS_5OFileES3_RKT_9
_ZN4PLMDlsIA59_cEERNS_5OFileES3_RKT_10
_ZN4PLMDlsIA53_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA100_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA57_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA66_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA68_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA69_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA108_cEERNS_5OFileES3_RKT_30
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA9_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
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_108
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_113
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_119
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_158
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_169
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_176
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_202
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_243
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_252
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_440
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_542
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_963
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_984
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1008
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1009
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_1011
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1017
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1022
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1034
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1110
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1137
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_1214
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1247
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1365
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1427
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1677
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2027
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2400
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7147
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_7274
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45554
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46433
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46751
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47477
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_213020
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_283938
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_375008
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func.html b/coverage/tools/OFile.h.func.html new file mode 100644 index 0000000000..a7bd13fd80 --- /dev/null +++ b/coverage/tools/OFile.h.func.html @@ -0,0 +1,500 @@ + + + + + + + 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-05-27 13:05: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_1011
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_963
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1137
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1247
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_1214
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1677
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46433
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_243
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2027
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_79
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1110
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_158
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1034
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_119
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_375008
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_252
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_65
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_542
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_202
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_440
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1365
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1427
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1022
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_7274
_ZN4PLMDlsIA47_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA50_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA52_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA53_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA54_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA56_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA57_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_5
_ZN4PLMDlsIA59_cEERNS_5OFileES3_RKT_10
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46751
_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_1008
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7147
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2400
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_108
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47477
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsINS_14ActionRegisterEEERNS_5OFileES3_RKT_1
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_984
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1009
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1017
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_213020
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_169
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_176
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_283938
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.gcov.html b/coverage/tools/OFile.h.gcov.html new file mode 100644 index 0000000000..f311d593d7 --- /dev/null +++ b/coverage/tools/OFile.h.gcov.html @@ -0,0 +1,362 @@ + + + + + + + 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-05-27 13:05: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::vector<char> buffer_string;
+     158             : /// Internal buffer (generic use)
+     159             :   std::vector<char> buffer;
+     160             : /// Internal buffer length
+     161             :   int buflen;
+     162             : /// This variables stores the actual buffer length
+     163             :   int actual_buffer_length;
+     164             : /// Class identifying a single field for fielded output
+     165    50127448 :   class Field:
+     166             :     public FieldBase {
+     167             :   };
+     168             : /// Low-level write
+     169             :   std::size_t llwrite(const char*,std::size_t);
+     170             : /// True if fields has changed.
+     171             : /// This could be due to a change in the list of fields or a reset
+     172             : /// of a nominally constant field
+     173             :   bool fieldChanged;
+     174             : /// Format for fields writing
+     175             :   std::string fieldFmt;
+     176             : /// All the previously defined variable fields
+     177             :   std::vector<Field> previous_fields;
+     178             : /// All the defined variable fields
+     179             :   std::vector<Field> fields;
+     180             : /// All the defined constant fields
+     181             :   std::vector<Field> const_fields;
+     182             : /// Prefix for line (e.g. "PLUMED: ")
+     183             :   std::string linePrefix;
+     184             : /// Temporary ostringstream for << output
+     185             :   std::ostringstream oss;
+     186             : /// The string used for backing up files
+     187             :   std::string backstring;
+     188             : /// Find field index given name
+     189             :   unsigned findField(const std::string&name)const;
+     190             : /// check if we are restarting
+     191             :   bool checkRestart()const;
+     192             : /// True if restart behavior should be forced
+     193             :   bool enforceRestart_;
+     194             : /// True if backup behavior (i.e. non restart) should be forced
+     195             :   bool enforceBackup_;
+     196             : public:
+     197             : /// Constructor
+     198             :   OFile();
+     199             : /// Allows overloading of link
+     200             :   using FileBase::link;
+     201             : /// Allows overloading of open
+     202             :   using FileBase::open;
+     203             : /// Allows linking this OFile to another one.
+     204             : /// In this way, everything written to this OFile will be immediately
+     205             : /// written on the linked OFile. Notice that a OFile should
+     206             : /// be either opened explicitly, linked to a FILE or linked to a OFile
+     207             :   OFile& link(OFile&);
+     208             : /// Set the string name to be used for automatic backup
+     209             :   void setBackupString( const std::string& );
+     210             : /// Backup a file by giving it a different name
+     211             :   void backupFile( const std::string& bstring, const std::string& fname );
+     212             : /// This backs up all the files that would have been created with the
+     213             : /// name str.  It is used in analysis when you are not restarting.  Analysis
+     214             : /// output files at different times, which are names analysis.0.<filename>,
+     215             : /// analysis.1.<filename> and <filename>, are backed up to bck.0.analysis.0.<filename>,
+     216             : /// bck.0.analysis.1.<filename> and bck.0.<filename>
+     217             :   void backupAllFiles( const std::string& str );
+     218             : /// Opens the file using automatic append/backup
+     219             :   OFile& open(const std::string&name) override;
+     220             : /// Set the prefix for output.
+     221             : /// Typically "PLUMED: ". Notice that lines with a prefix cannot
+     222             : /// be parsed using fields in a IFile.
+     223             :   OFile& setLinePrefix(const std::string&);
+     224             : /// Set the format for writing double precision fields
+     225             :   OFile& fmtField(const std::string&);
+     226             : /// Reset the format for writing double precision fields to its default
+     227             :   OFile& fmtField();
+     228             : /// Set the value of a double precision field
+     229             :   OFile& printField(const std::string&,double);
+     230             : /// Set the value of a int type field
+     231             :   OFile& printField(const std::string&,int);
+     232             :   OFile& printField(const std::string&,long int);
+     233             :   OFile& printField(const std::string&,long long int);
+     234             :   OFile& printField(const std::string&,unsigned);
+     235             :   OFile& printField(const std::string&,long unsigned);
+     236             :   OFile& printField(const std::string&,long long unsigned);
+     237             : /// Set the value of a string field
+     238             :   OFile& printField(const std::string&,const std::string&);
+     239             : ///
+     240             :   OFile& addConstantField(const std::string&);
+     241             : /// Used to setup printing of values
+     242             :   OFile& setupPrintValue( Value *val );
+     243             : /// Print a value
+     244             :   OFile& printField( Value* val, const double& v );
+     245             :   /** Close a line.
+     246             :   Typically used as
+     247             :   \verbatim
+     248             :     of.printField("a",a).printField("b",b).printField();
+     249             :   \endverbatim
+     250             :   */
+     251             :   OFile& printField();
+     252             :   /**
+     253             :   Resets the list of fields.
+     254             :   As it is only possible to add new constant fields (addConstantField()),
+     255             :   this method can be used to clean the field list.
+     256             :   */
+     257             :   OFile& clearFields();
+     258             : /// Formatted output with explicit format - a la printf
+     259             :   int printf(const char*fmt,...);
+     260             : /// Formatted output with << operator
+     261             :   template <class T>
+     262             :   friend OFile& operator<<(OFile&,const T &);
+     263             : /// Rewind a file
+     264             :   OFile&rewind();
+     265             : /// Flush a file
+     266             :   FileBase&flush() override;
+     267             : /// Enforce restart, also if the attached plumed object is not restarting.
+     268             : /// Useful for tests
+     269             :   OFile&enforceRestart();
+     270             : /// Enforce backup, even if the attached plumed object is restarting.
+     271             :   OFile&enforceBackup();
+     272             : };
+     273             : 
+     274             : /// Write using << syntax
+     275             : template <class T>
+     276     1480978 : OFile& operator<<(OFile&of,const T &t) {
+     277     1480978 :   of.oss<<t;
+     278     1480978 :   of.printf("%s",of.oss.str().c_str());
+     279     1480978 :   of.oss.str("");
+     280     1480978 :   return of;
+     281             : }
+     282             : 
+     283             : 
+     284             : }
+     285             : 
+     286             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func-sort-c.html b/coverage/tools/OpenMP.cpp.func-sort-c.html new file mode 100644 index 0000000000..9d24b4cd2d --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP13setNumThreadsEj0
_ZN4PLMD6OpenMP16getCachelineSizeEv55762
_ZN4PLMD6OpenMP13getNumThreadsEv1840372
_ZN4PLMDL13getOpenMPVarsEv1896134
_ZN4PLMD6OpenMP12getThreadNumEv6263516
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func.html b/coverage/tools/OpenMP.cpp.func.html new file mode 100644 index 0000000000..20b5021734 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05:14Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP12getThreadNumEv6263516
_ZN4PLMD6OpenMP13getNumThreadsEv1840372
_ZN4PLMD6OpenMP13setNumThreadsEj0
_ZN4PLMD6OpenMP16getCachelineSizeEv55762
_ZN4PLMDL13getOpenMPVarsEv1896134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.gcov.html b/coverage/tools/OpenMP.cpp.gcov.html new file mode 100644 index 0000000000..d16aa918f8 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.gcov.html @@ -0,0 +1,154 @@ + + + + + + + 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-05-27 13:05: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     1896134 : static OpenMPVars & getOpenMPVars() {
+      41             :   static OpenMPVars vars;
+      42     1896134 :   return vars;
+      43             : }
+      44             : 
+      45           0 : void OpenMP::setNumThreads(const unsigned nt) {
+      46           0 :   getOpenMPVars().num_threads=nt;
+      47           0 : }
+      48             : 
+      49       55762 : unsigned OpenMP::getCachelineSize() {
+      50       55762 :   if(!getOpenMPVars().cache_set) {
+      51         800 :     if(std::getenv("PLUMED_CACHELINE_SIZE")) Tools::convert(std::getenv("PLUMED_CACHELINE_SIZE"),getOpenMPVars().cacheline_size);
+      52         800 :     getOpenMPVars().cache_set = true;
+      53             :   }
+      54       55762 :   return getOpenMPVars().cacheline_size;
+      55             : }
+      56             : 
+      57     1840372 : unsigned OpenMP::getNumThreads() {
+      58     1840372 :   if(!getOpenMPVars().nt_env_set) {
+      59         800 :     if(std::getenv("PLUMED_NUM_THREADS")) Tools::convert(std::getenv("PLUMED_NUM_THREADS"),getOpenMPVars().num_threads);
+      60         800 :     getOpenMPVars().nt_env_set = true;
+      61             :   }
+      62     1840372 :   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.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func-sort-c.html b/coverage/tools/OpenMP.h.func-sort-c.html new file mode 100644 index 0000000000..5ad6b913af --- /dev/null +++ b/coverage/tools/OpenMP.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjRKSt6vectorIT_SaIS5_EE450
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j27208
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjPKT_j27547
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func.html b/coverage/tools/OpenMP.h.func.html new file mode 100644 index 0000000000..ab3aa9aafb --- /dev/null +++ b/coverage/tools/OpenMP.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjPKT_j27547
_ZN4PLMD6OpenMP17getGoodNumThreadsINS_13VectorGenericILj3EEEEEjRKSt6vectorIT_SaIS5_EE450
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j27208
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.gcov.html b/coverage/tools/OpenMP.h.gcov.html new file mode 100644 index 0000000000..eb0fed18ad --- /dev/null +++ b/coverage/tools/OpenMP.h.gcov.html @@ -0,0 +1,154 @@ + + + + + + + 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-05-27 13:05: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       54755 : 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       54755 :   unsigned m=n*sizeof(T)/(2*getCachelineSize());
+      62       54755 :   unsigned numThreads=getNumThreads();
+      63       54755 :   if(m>=numThreads) m=numThreads;
+      64             :   else m=1;
+      65       54755 :   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.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func-sort-c.html b/coverage/tools/PDB.cpp.func-sort-c.html new file mode 100644 index 0000000000..d318708833 --- /dev/null +++ b/coverage/tools/PDB.cpp.func-sort-c.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-05-27 13:05:14Functions:364481.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxVecEv12
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZN4PLMD3PDB11addBlockEndERKj17
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE27
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE34
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_161
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE244
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd323
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv474
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1337
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd2069
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2216
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11608
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE38554
_ZNK4PLMD3PDB12getOccupancyEv38558
_ZNK4PLMD3PDB7getBetaEv38558
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48690
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151942
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166259
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE493287
_ZNK4PLMD3PDB14getAtomNumbersEv722721
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd1502798
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6870274
_ZNK4PLMD3PDB12getPositionsEv23534547
_ZNK4PLMD3PDB4sizeEv216516274
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func.html b/coverage/tools/PDB.cpp.func.html new file mode 100644 index 0000000000..40ce0fa2d6 --- /dev/null +++ b/coverage/tools/PDB.cpp.func.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-05-27 13:05:14Functions:364481.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB11addBlockEndERKj17
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE27
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE34
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd1502798
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE493287
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd2069
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd323
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1337
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6870274
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE38554
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE249
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_161
_ZNK4PLMD3PDB12getOccupancyEv38558
_ZNK4PLMD3PDB12getPositionsEv23534547
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE244
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB14getAtomNumbersEv722721
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151942
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48690
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11608
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE166259
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv474
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2216
_ZNK4PLMD3PDB4sizeEv216516274
_ZNK4PLMD3PDB7getBetaEv38558
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB9getBoxVecEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.gcov.html b/coverage/tools/PDB.cpp.gcov.html new file mode 100644 index 0000000000..5137d55de5 --- /dev/null +++ b/coverage/tools/PDB.cpp.gcov.html @@ -0,0 +1,826 @@ + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-05-27 13:05:14Functions:364481.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PDB.h"
+      23             : #include "Tools.h"
+      24             : #include "Log.h"
+      25             : #include "h36.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include "core/GenericMolInfo.h"
+      29             : #include "Tensor.h"
+      30             : 
+      31             : //+PLUMEDOC INTERNAL pdbreader
+      32             : /*
+      33             : PLUMED can use the PDB format in several places
+      34             : 
+      35             : - To read molecular structure (\ref MOLINFO).
+      36             : - To read reference conformations (\ref RMSD, but also many other methods in \ref dists, \ref FIT_TO_TEMPLATE, etc).
+      37             : 
+      38             : The implemented PDB reader expects a file formatted correctly according to the
+      39             : [PDB standard](http://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html).
+      40             : In particular, the following columns are read from ATOM records
+      41             : \verbatim
+      42             : columns | content
+      43             : 1-6     | record name (ATOM or HETATM)
+      44             : 7-11    | serial number of the atom (starting from 1)
+      45             : 13-16   | atom name
+      46             : 18-20   | residue name
+      47             : 22      | chain id
+      48             : 23-26   | residue number
+      49             : 31-38   | x coordinate
+      50             : 39-46   | y coordinate
+      51             : 47-54   | z coordinate
+      52             : 55-60   | occupancy
+      53             : 61-66   | beta factor
+      54             : \endverbatim
+      55             : PLUMED parser is slightly more permissive than the official PDB format
+      56             : in the fact that the format of real numbers is not fixed. In other words,
+      57             : any real number that can be parsed is OK and the dot can be placed anywhere. However,
+      58             : __columns are interpret strictly__. A sample PDB should look like the following
+      59             : \verbatim
+      60             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      61             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      62             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+      63             : \endverbatim
+      64             : 
+      65             : Notice that serial numbers need not to be consecutive. In the three-line example above,
+      66             : only the coordinates of three atoms are provided. This is perfectly legal and indicates PLUMED
+      67             : that information about these atoms only is available. This could be both for structural
+      68             : information in \ref MOLINFO, where the other atoms would have no name assigned, and for
+      69             : reference structures used in \ref RMSD, where only the provided atoms would be used to compute RMSD.
+      70             : 
+      71             : \par Occupancy and beta factors
+      72             : 
+      73             : PLUMED reads also occupancy and beta factors that however are given a very special meaning.
+      74             : In cases where the PDB structure is used as a reference for an alignment (that's the case
+      75             : for instance in \ref RMSD and in \ref FIT_TO_TEMPLATE), the occupancy column is used
+      76             : to provide the weight of each atom in the alignment. In cases where, perhaps after alignment,
+      77             : the displacement between running coordinates and the provided PDB is computed, the beta factors
+      78             : are used as weight for the displacement.
+      79             : Since setting the weights to zero is the same as __not__ including an atom in the alignment or
+      80             : displacement calculation, the two following reference files would be equivalent when used in an \ref RMSD
+      81             : calculation. First file:
+      82             : \verbatim
+      83             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      84             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      85             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  0.00  0.00
+      86             : \endverbatim
+      87             : Second file:
+      88             : \verbatim
+      89             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      90             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      91             : \endverbatim
+      92             : However notice that many extra atoms with zero weight might slow down the calculation, so
+      93             : removing lines is better than setting their weights to zero.
+      94             : In addition, weights for alignment need not to be equivalent to weights for displacement.
+      95             : Starting with PLUMED 2.7, if all the weights are set to zero they will be normalized to be equal to the
+      96             : inverse of the number of involved atoms. This means that it will be possible to use files with
+      97             : the weight columns set to zero obtaining a meaningful result. In previous PLUMED versions,
+      98             : setting all weights to zero was resulting in an error instead.
+      99             : 
+     100             : 
+     101             : \par Systems with more than 100k atoms
+     102             : 
+     103             : Notice that it very likely does not make any sense to compute the \ref RMSD or any other structural
+     104             : deviation __using__ so many atoms. However, if the protein for which you want to compute \ref RMSD
+     105             : has atoms with large serial numbers (e.g. because it is located __after__ solvent in the sorted list of atoms)
+     106             : you might end up with troubles with the limitations of the PDB format. Indeed, since there are 5
+     107             : columns available for atom serial number, this number cannot be larger than 99999.
+     108             : In addition, providing \ref MOLINFO with names associated to atoms with a serial larger than 99999 would be impossible.
+     109             : 
+     110             : Since PLUMED 2.4 we allow [hybrid 36](http://cci.lbl.gov/hybrid_36/) format to be used to specify atom numbers.
+     111             : This format is not particularly widespread, but has the nice feature that it provides a one-to-one mapping
+     112             : between numbers up to approximately 80 millions and strings with 5 characters, plus it is backward compatible
+     113             : for numbers smaller than 100000. This is not true for notations like the hex notation exported by VMD.
+     114             : Using the hybrid 36 format, the ATOM records for atom ranging from 99997 to 100002 would read like these:
+     115             : \verbatim
+     116             : ATOM  99997  Ar      X   1      45.349  38.631  15.116  1.00  1.00
+     117             : ATOM  99998  Ar      X   1      46.189  38.631  15.956  1.00  1.00
+     118             : ATOM  99999  Ar      X   1      46.189  39.471  15.116  1.00  1.00
+     119             : ATOM  A0000  Ar      X   1      45.349  39.471  15.956  1.00  1.00
+     120             : ATOM  A0000  Ar      X   1      45.349  38.631  16.796  1.00  1.00
+     121             : ATOM  A0001  Ar      X   1      46.189  38.631  17.636  1.00  1.00
+     122             : \endverbatim
+     123             : There are tools that can be found to translate from integers to strings and back using hybrid 36 format
+     124             : (a simple python script can be found [here](https://sourceforge.net/p/cctbx/code/HEAD/tree/trunk/iotbx/pdb/hybrid_36.py)).
+     125             : In addition, as of PLUMED 2.5, we provide a \ref pdbrenumber "command line tool" that can be used to renumber atoms in a PDB file.
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : 
+     131             : namespace PLMD {
+     132             : 
+     133          27 : void PDB::setAtomNumbers( const std::vector<AtomNumber>& atoms ) {
+     134          27 :   positions.resize( atoms.size() ); occupancy.resize( atoms.size() );
+     135          27 :   beta.resize( atoms.size() ); numbers.resize( atoms.size() );
+     136         210 :   for(unsigned i=0; i<atoms.size(); ++i) { numbers[i]=atoms[i]; beta[i]=1.0; occupancy[i]=1.0; }
+     137          27 : }
+     138             : 
+     139          34 : void PDB::setArgumentNames( const std::vector<std::string>& argument_names ) {
+     140          34 :   argnames.resize( argument_names.size() );
+     141          98 :   for(unsigned i=0; i<argument_names.size(); ++i) {
+     142             :     argnames[i]=argument_names[i];
+     143          64 :     arg_data.insert( std::pair<std::string,double>( argnames[i], 0.0 ) );
+     144             :   }
+     145          34 : }
+     146             : 
+     147     1504260 : bool PDB::getArgumentValue( const std::string& name, double& value ) const {
+     148             :   std::map<std::string,double>::const_iterator it = arg_data.find(name);
+     149     1504260 :   if( it!=arg_data.end() ) { value = it->second; return true; }
+     150             :   return false;
+     151             : }
+     152             : 
+     153      493287 : void PDB::setAtomPositions( const std::vector<Vector>& pos ) {
+     154      493287 :   plumed_assert( pos.size()==positions.size() );
+     155      519464 :   for(unsigned i=0; i<positions.size(); ++i) positions[i]=pos[i];
+     156      493287 : }
+     157             : 
+     158     1502798 : void PDB::setArgumentValue( const std::string& argname, const double& val ) {
+     159             :   // First set the value of the value of the argument in the map
+     160     1502798 :   arg_data.find(argname)->second = val;
+     161     1502798 : }
+     162             : 
+     163             : // bool PDB::hasRequiredProperties( const std::vector<std::string>& inproperties ){
+     164             : //   bool hasprop=false;
+     165             : //   for(unsigned i=0;i<remark.size();++i){
+     166             : //       if( remark[i].find("PROPERTIES=")!=std::string::npos){ hasprop=true; break; }
+     167             : //   }
+     168             : //   if( !hasprop ){
+     169             : //       std::string mypropstr="PROPERTIES=" + inproperties[0];
+     170             : //       for(unsigned i=1;i<inproperties.size();++i) mypropstr += "," + inproperties[i];
+     171             : //       remark.push_back( mypropstr );
+     172             : //   }
+     173             : //   // Now check that all required properties are there
+     174             : //   for(unsigned i=0;i<inproperties.size();++i){
+     175             : //       hasprop=false;
+     176             : //       for(unsigned j=0;j<remark.size();++j){
+     177             : //           if( remark[j].find(inproperties[i]+"=")!=std::string::npos){ hasprop=true; break; }
+     178             : //       }
+     179             : //       if( !hasprop ) return false;
+     180             : //   }
+     181             : //   return true;
+     182             : // }
+     183             : 
+     184          17 : void PDB::addBlockEnd( const unsigned& end ) {
+     185          17 :   block_ends.push_back( end );
+     186          17 : }
+     187             : 
+     188         474 : unsigned PDB::getNumberOfAtomBlocks()const {
+     189         474 :   return block_ends.size();
+     190             : }
+     191             : 
+     192          14 : const std::vector<unsigned> & PDB::getAtomBlockEnds()const {
+     193          14 :   return block_ends;
+     194             : }
+     195             : 
+     196    23534547 : const std::vector<Vector> & PDB::getPositions()const {
+     197    23534547 :   return positions;
+     198             : }
+     199             : 
+     200           0 : void PDB::setPositions(const std::vector<Vector> &v ) {
+     201           0 :   plumed_assert( v.size()==positions.size() );
+     202           0 :   positions=v;
+     203           0 : }
+     204             : 
+     205       38558 : const std::vector<double> & PDB::getOccupancy()const {
+     206       38558 :   return occupancy;
+     207             : }
+     208             : 
+     209       38558 : const std::vector<double> & PDB::getBeta()const {
+     210       38558 :   return beta;
+     211             : }
+     212             : 
+     213        1337 : void PDB::addRemark( std::vector<std::string>& v1 ) {
+     214        1337 :   Tools::parse(v1,"TYPE",mtype);
+     215        1337 :   Tools::parseVector(v1,"ARG",argnames);
+     216        3747 :   for(unsigned i=0; i<v1.size(); ++i) {
+     217        2410 :     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         546 :       flags.push_back(v1[i]);
+     225             :     }
+     226             :   }
+     227        1337 : }
+     228             : 
+     229           8 : bool PDB::hasFlag( const std::string& fname ) const {
+     230           8 :   for(unsigned i=0; i<flags.size(); ++i) {
+     231           0 :     if( flags[i]==fname ) return true;
+     232             :   }
+     233             :   return false;
+     234             : }
+     235             : 
+     236             : 
+     237      722721 : const std::vector<AtomNumber> & PDB::getAtomNumbers()const {
+     238      722721 :   return numbers;
+     239             : }
+     240             : 
+     241           0 : const Vector & PDB::getBoxAxs()const {
+     242           0 :   return BoxXYZ;
+     243             : }
+     244             : 
+     245           0 : const Vector & PDB::getBoxAng()const {
+     246           0 :   return BoxABG;
+     247             : }
+     248             : 
+     249          12 : const Tensor & PDB::getBoxVec()const {
+     250          12 :   return Box;
+     251             : }
+     252             : 
+     253     6870274 : std::string PDB::getAtomName(AtomNumber a)const {
+     254             :   const auto p=number2index.find(a);
+     255     6870274 :   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     6870274 :   } else return atomsymb[p->second];
+     259             : }
+     260             : 
+     261      166259 : unsigned PDB::getResidueNumber(AtomNumber a)const {
+     262             :   const auto p=number2index.find(a);
+     263      166259 :   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      166259 :   } else return residue[p->second];
+     267             : }
+     268             : 
+     269      151942 : std::string PDB::getResidueName(AtomNumber a) const {
+     270             :   const auto p=number2index.find(a);
+     271      151942 :   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      151942 :   } else return residuenames[p->second];
+     275             : }
+     276             : 
+     277   216516274 : unsigned PDB::size()const {
+     278   216516274 :   return positions.size();
+     279             : }
+     280             : 
+     281        2069 : bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale) {
+     282             :   //cerr<<file<<endl;
+     283             :   bool file_is_alive=false;
+     284        2069 :   if(naturalUnits) scale=1.0;
+     285             :   std::string line;
+     286             :   fpos_t pos; bool between_ters=true;
+     287      275284 :   while(Tools::getline(fp,line)) {
+     288             :     //cerr<<line<<"\n";
+     289      275066 :     fgetpos (fp,&pos);
+     290     1969071 :     while(line.length()<80) line.push_back(' ');
+     291      275066 :     std::string record=line.substr(0,6);
+     292      275066 :     std::string serial=line.substr(6,5);
+     293      275066 :     std::string atomname=line.substr(12,4);
+     294      275066 :     std::string residuename=line.substr(17,3);
+     295      275066 :     std::string chainID=line.substr(21,1);
+     296      275066 :     std::string resnum=line.substr(22,4);
+     297      275066 :     std::string x=line.substr(30,8);
+     298      275066 :     std::string y=line.substr(38,8);
+     299      275066 :     std::string z=line.substr(46,8);
+     300      275066 :     std::string occ=line.substr(54,6);
+     301      275066 :     std::string bet=line.substr(60,6);
+     302      275066 :     std::string BoxX=line.substr(6,9);
+     303      275066 :     std::string BoxY=line.substr(15,9);
+     304      275066 :     std::string BoxZ=line.substr(24,9);
+     305      275066 :     std::string BoxA=line.substr(33,7);
+     306      275066 :     std::string BoxB=line.substr(40,7);
+     307      275066 :     std::string BoxG=line.substr(47,7);
+     308      275066 :     Tools::trim(record);
+     309      275066 :     if(record=="TER") { between_ters=false; block_ends.push_back( positions.size() ); }
+     310      275066 :     if(record=="END") { file_is_alive=true;  break;}
+     311      273352 :     if(record=="ENDMDL") { file_is_alive=true;  break;}
+     312      273215 :     if(record=="REMARK") {
+     313        2674 :       std::vector<std::string> v1;  v1=Tools::getWords(line.substr(6));
+     314        1337 :       addRemark( v1 );
+     315        1337 :     }
+     316      273215 :     if(record=="CRYST1") {
+     317          68 :       Tools::convert(BoxX,BoxXYZ[0]);
+     318          68 :       Tools::convert(BoxY,BoxXYZ[1]);
+     319          68 :       Tools::convert(BoxZ,BoxXYZ[2]);
+     320          68 :       Tools::convert(BoxA,BoxABG[0]);
+     321          68 :       Tools::convert(BoxB,BoxABG[1]);
+     322          68 :       Tools::convert(BoxG,BoxABG[2]);
+     323          68 :       BoxXYZ*=scale;
+     324          68 :       double cosA=std::cos(BoxABG[0]*pi/180.);
+     325          68 :       double cosB=std::cos(BoxABG[1]*pi/180.);
+     326          68 :       double cosG=std::cos(BoxABG[2]*pi/180.);
+     327          68 :       double sinG=std::sin(BoxABG[2]*pi/180.);
+     328         272 :       for (unsigned i=0; i<3; i++) {Box[i][0]=0.; Box[i][1]=0.; Box[i][2]=0.;}
+     329          68 :       Box[0][0]=BoxXYZ[0];
+     330          68 :       Box[1][0]=BoxXYZ[1]*cosG;
+     331          68 :       Box[1][1]=BoxXYZ[1]*sinG;
+     332          68 :       Box[2][0]=BoxXYZ[2]*cosB;
+     333          68 :       Box[2][1]=(BoxXYZ[2]*BoxXYZ[1]*cosA-Box[2][0]*Box[1][0])/Box[1][1];
+     334          68 :       Box[2][2]=std::sqrt(BoxXYZ[2]*BoxXYZ[2]-Box[2][0]*Box[2][0]-Box[2][1]*Box[2][1]);
+     335             :     }
+     336      275261 :     if(record=="ATOM" || record=="HETATM") {
+     337             :       between_ters=true;
+     338             :       AtomNumber a;
+     339      271169 :       unsigned resno=0; // GB: when resnum string is not present, we set res number to zero
+     340             :       double o,b;
+     341      271169 :       Vector p;
+     342             :       {
+     343             :         int result;
+     344      271169 :         auto trimmed=serial;
+     345      271169 :         Tools::trim(trimmed);
+     346      271231 :         while(trimmed.length()<5) trimmed = std::string(" ") + trimmed;
+     347      271169 :         const char* errmsg = h36::hy36decode(5, trimmed.c_str(),trimmed.length(), &result);
+     348      271169 :         if(errmsg) {
+     349           0 :           std::string msg(errmsg);
+     350           0 :           plumed_merror(msg);
+     351             :         }
+     352      271169 :         a.setSerial(result);
+     353             :       }
+     354             : 
+     355             :       // allow skipping residue number
+     356             :       {
+     357      271169 :         auto trimmed=resnum;
+     358      271169 :         Tools::trim(trimmed);
+     359      271169 :         if(trimmed.length()>0) {
+     360             :           int result;
+     361      271169 :           while(trimmed.length()<4) trimmed = std::string(" ") + trimmed;
+     362      271169 :           const char* errmsg = h36::hy36decode(4, trimmed.c_str(),trimmed.length(), &result);
+     363      271169 :           if(errmsg) {
+     364           0 :             std::string msg(errmsg);
+     365           0 :             plumed_merror(msg);
+     366             :           }
+     367      271169 :           resno=result;
+     368             :         }
+     369             :       }
+     370             : 
+     371      271169 :       Tools::convert(occ,o);
+     372      271169 :       Tools::convert(bet,b);
+     373      271169 :       Tools::convert(x,p[0]);
+     374      271169 :       Tools::convert(y,p[1]);
+     375      271169 :       Tools::convert(z,p[2]);
+     376             :       // scale into nm
+     377      271169 :       p*=scale;
+     378      271169 :       numbers.push_back(a);
+     379      271169 :       number2index[a]=positions.size();
+     380      271169 :       std::size_t startpos=atomname.find_first_not_of(" \t");
+     381      271169 :       std::size_t endpos=atomname.find_last_not_of(" \t");
+     382      271169 :       atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
+     383      271169 :       residue.push_back(resno);
+     384      271169 :       chain.push_back(chainID);
+     385      271169 :       occupancy.push_back(o);
+     386      271169 :       beta.push_back(b);
+     387      271169 :       positions.push_back(p);
+     388      271169 :       residuenames.push_back(residuename);
+     389             :     }
+     390             :   }
+     391        2069 :   if( between_ters ) block_ends.push_back( positions.size() );
+     392        2069 :   return file_is_alive;
+     393             : }
+     394             : 
+     395         323 : bool PDB::read(const std::string&file,bool naturalUnits,double scale) {
+     396         323 :   FILE* fp=std::fopen(file.c_str(),"r");
+     397         323 :   if(!fp) return false;
+     398             : // call fclose when exiting this function
+     399         321 :   auto deleter=[](FILE* f) { std::fclose(f); };
+     400             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     401         321 :   readFromFilepointer(fp,naturalUnits,scale);
+     402             :   return true;
+     403             : }
+     404             : 
+     405         244 : void PDB::getChainNames( std::vector<std::string>& chains ) const {
+     406         244 :   chains.resize(0);
+     407         244 :   chains.push_back( chain[0] );
+     408      500977 :   for(unsigned i=1; i<size(); ++i) {
+     409      500733 :     if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
+     410             :   }
+     411         244 : }
+     412             : 
+     413       11608 : void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
+     414             :   bool inres=false, foundchain=false;
+     415    30321511 :   for(unsigned i=0; i<size(); ++i) {
+     416    30309903 :     if( chain[i]==chainname ) {
+     417    26640541 :       if(!inres) {
+     418       11608 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     419       11608 :         res_start=residue[i];
+     420             :       }
+     421             :       inres=true; foundchain=true;
+     422     3669362 :     } else if( inres && chain[i]!=chainname ) {
+     423             :       inres=false;
+     424       11094 :       res_end=residue[i-1];
+     425             :     }
+     426             :   }
+     427       11608 :   if(inres) res_end=residue[size()-1];
+     428       11608 : }
+     429             : 
+     430         161 : void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
+     431             :   bool inres=false, foundchain=false;
+     432      434018 :   for(unsigned i=0; i<size(); ++i) {
+     433      433857 :     if( chain[i]==chainname ) {
+     434       90643 :       if(!inres) {
+     435         161 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     436         161 :         a_start=numbers[i];
+     437             :       }
+     438             :       inres=true; foundchain=true;
+     439      343214 :     } else if( inres && chain[i]!=chainname ) {
+     440             :       inres=false;
+     441          74 :       a_end=numbers[i-1];
+     442             :     }
+     443             :   }
+     444         161 :   if(inres) a_end=numbers[size()-1];
+     445         161 : }
+     446             : 
+     447        5958 : std::string PDB::getResidueName( const unsigned& resnum ) const {
+     448     7317600 :   for(unsigned i=0; i<size(); ++i) {
+     449     7317600 :     if( residue[i]==resnum ) return residuenames[i];
+     450             :   }
+     451           0 :   std::string num; Tools::convert( resnum, num );
+     452           0 :   plumed_merror("residue " + num + " not found" );
+     453             : }
+     454             : 
+     455       48690 : std::string PDB::getResidueName(const unsigned& resnum,const std::string& chainid ) const {
+     456    62791939 :   for(unsigned i=0; i<size(); ++i) {
+     457    62840809 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) return residuenames[i];
+     458             :   }
+     459           0 :   std::string num; Tools::convert( resnum, num );
+     460           0 :   plumed_merror("residue " + num + " not found in chain " + chainid );
+     461             : }
+     462             : 
+     463             : 
+     464       13260 : AtomNumber PDB::getNamedAtomFromResidue( const std::string& aname, const unsigned& resnum ) const {
+     465    16347180 :   for(unsigned i=0; i<size(); ++i) {
+     466    16347180 :     if( residue[i]==resnum && atomsymb[i]==aname ) return numbers[i];
+     467             :   }
+     468           0 :   std::string num; Tools::convert( resnum, num );
+     469           0 :   plumed_merror("residue " + num + " does not contain an atom named " + aname );
+     470             : }
+     471             : 
+     472        2216 : AtomNumber PDB::getNamedAtomFromResidueAndChain( const std::string& aname, const unsigned& resnum, const std::string& chainid ) const {
+     473     1070584 :   for(unsigned i=0; i<size(); ++i) {
+     474     1072800 :     if( residue[i]==resnum && atomsymb[i]==aname && ( chainid=="*" || chain[i]==chainid) ) return numbers[i];
+     475             :   }
+     476           0 :   std::string num; Tools::convert( resnum, num );
+     477           0 :   plumed_merror("residue " + num + " from chain " + chainid + " does not contain an atom named " + aname );
+     478             : }
+     479             : 
+     480       34246 : std::vector<AtomNumber> PDB::getAtomsInResidue(const unsigned& resnum,const std::string& chainid)const {
+     481             :   std::vector<AtomNumber> tmp;
+     482    91444766 :   for(unsigned i=0; i<size(); ++i) {
+     483    91931870 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) tmp.push_back(numbers[i]);
+     484             :   }
+     485       34246 :   if(tmp.size()==0) {
+     486           0 :     std::string num; Tools::convert( resnum, num );
+     487           0 :     plumed_merror("Cannot find residue " + num + " from chain " + chainid  );
+     488             :   }
+     489       34246 :   return tmp;
+     490             : }
+     491             : 
+     492           0 : std::vector<AtomNumber> PDB::getAtomsInChain(const std::string& chainid)const {
+     493             :   std::vector<AtomNumber> tmp;
+     494           0 :   for(unsigned i=0; i<size(); ++i) {
+     495           0 :     if( chainid=="*" || chain[i]==chainid ) tmp.push_back(numbers[i]);
+     496             :   }
+     497           0 :   if(tmp.size()==0) {
+     498           0 :     plumed_merror("Cannot find atoms from chain " + chainid  );
+     499             :   }
+     500           0 :   return tmp;
+     501             : }
+     502             : 
+     503        4638 : std::string PDB::getChainID(const unsigned& resnumber) const {
+     504     5689172 :   for(unsigned i=0; i<size(); ++i) {
+     505     5689172 :     if(resnumber==residue[i]) return chain[i];
+     506             :   }
+     507           0 :   plumed_merror("Not enough residues in pdb input file");
+     508             : }
+     509             : 
+     510           0 : std::string PDB::getChainID(AtomNumber a) const {
+     511             :   const auto p=number2index.find(a);
+     512           0 :   if(p==number2index.end()) {
+     513           0 :     std::string num; Tools::convert( a.serial(), num );
+     514           0 :     plumed_merror("Chain for atom " + num + " not found" );
+     515             :   }
+     516           0 :   return chain[p->second];
+     517             : }
+     518             : 
+     519           0 : bool PDB::checkForResidue( const std::string& name ) const {
+     520           0 :   for(unsigned i=0; i<size(); ++i) {
+     521           0 :     if( residuenames[i]==name ) return true;
+     522             :   }
+     523             :   return false;
+     524             : }
+     525             : 
+     526           0 : bool PDB::checkForAtom( const std::string& name ) const {
+     527           0 :   for(unsigned i=0; i<size(); ++i) {
+     528           0 :     if( atomsymb[i]==name ) return true;
+     529             :   }
+     530             :   return false;
+     531             : }
+     532             : 
+     533         249 : bool PDB::checkForAtom( AtomNumber a ) const {
+     534             :   const auto p=number2index.find(a);
+     535         249 :   return (p!=number2index.end());
+     536             : }
+     537             : 
+     538           0 : Log& operator<<(Log& ostr, const PDB&  pdb) {
+     539             :   const std::size_t bufferlen=1000;
+     540             :   char buffer[bufferlen];
+     541           0 :   for(unsigned i=0; i<pdb.positions.size(); i++) {
+     542           0 :     std::snprintf(buffer,bufferlen,"ATOM %3u %8.3f %8.3f %8.3f\n",pdb.numbers[i].serial(),pdb.positions[i][0],pdb.positions[i][1],pdb.positions[i][2]);
+     543           0 :     ostr<<buffer;
+     544             :   }
+     545           0 :   return ostr;
+     546             : }
+     547             : 
+     548       38554 : Vector PDB::getPosition(AtomNumber a)const {
+     549             :   const auto p=number2index.find(a);
+     550       38554 :   if(p==number2index.end()) plumed_merror("atom not available");
+     551       38554 :   else return positions[p->second];
+     552             : }
+     553             : 
+     554     2539432 : std::vector<std::string> PDB::getArgumentNames()const {
+     555     2539432 :   return argnames;
+     556             : }
+     557             : 
+     558          10 : std::string PDB::getMtype() const {
+     559          10 :   return mtype;
+     560             : }
+     561             : 
+     562         497 : void PDB::print( const double& lunits, GenericMolInfo* mymoldat, OFile& ofile, const std::string& fmt ) {
+     563         497 :   if( argnames.size()>0 ) {
+     564         476 :     ofile.printf("REMARK ARG=%s", argnames[0].c_str() );
+     565        1744 :     for(unsigned i=1; i<argnames.size(); ++i) ofile.printf(",%s",argnames[i].c_str() );
+     566         476 :     ofile.printf("\n"); ofile.printf("REMARK ");
+     567             :   }
+     568             :   std::string descr2;
+     569         497 :   if(fmt.find("-")!=std::string::npos) {
+     570           0 :     descr2="%s=" + fmt + " ";
+     571             :   } else {
+     572             :     // This ensures numbers are left justified (i.e. next to the equals sign
+     573         497 :     std::size_t psign=fmt.find("%");
+     574         497 :     plumed_assert( psign!=std::string::npos );
+     575         994 :     descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     576             :   }
+     577        2241 :   for(std::map<std::string,double>::iterator it=arg_data.begin(); it!=arg_data.end(); ++it) ofile.printf( descr2.c_str(),it->first.c_str(), it->second );
+     578         497 :   if( argnames.size()>0 ) ofile.printf("\n");
+     579         497 :   if( !mymoldat ) {
+     580        2263 :     for(unsigned i=0; i<positions.size(); ++i) {
+     581             :       std::array<char,6> at;
+     582             :       {
+     583        1769 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     584        1769 :         plumed_assert(msg==nullptr) << msg;
+     585        1769 :         at[5]=0;
+     586             :       }
+     587             :       std::array<char,5> res;
+     588             :       {
+     589        1769 :         const char* msg = h36::hy36encode(4,i,&res[0]);
+     590        1769 :         plumed_assert(msg==nullptr) << msg;
+     591        1769 :         res[4]=0;
+     592             :       }
+     593        1769 :       ofile.printf("ATOM  %s  X   RES  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     594             :                    &at[0], &res[0],
+     595        1769 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     596             :                    occupancy[i], beta[i] );
+     597             :     }
+     598             :   } else {
+     599          69 :     for(unsigned i=0; i<positions.size(); ++i) {
+     600             :       std::array<char,6> at;
+     601             :       {
+     602          66 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     603          66 :         plumed_assert(msg==nullptr) << msg;
+     604          66 :         at[5]=0;
+     605             :       }
+     606             :       std::array<char,5> res;
+     607             :       {
+     608          66 :         const char* msg = h36::hy36encode(4,mymoldat->getResidueNumber(numbers[i]),&res[0]);
+     609          66 :         plumed_assert(msg==nullptr) << msg;
+     610          66 :         res[4]=0;
+     611             :       }
+     612          66 :       ofile.printf("ATOM  %s %-4s %3s  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     613         132 :                    &at[0], mymoldat->getAtomName(numbers[i]).c_str(),
+     614          66 :                    mymoldat->getResidueName(numbers[i]).c_str(), &res[0],
+     615          66 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     616             :                    occupancy[i], beta[i] );
+     617             :     }
+     618             :   }
+     619         497 :   ofile.printf("END\n");
+     620         497 : }
+     621             : 
+     622       37562 : bool PDB::allowedResidue( const std::string& type, const std::string& residuename ) const {
+     623       37562 :   if( type=="protein" ) {
+     624       37562 :     if(residuename=="ALA") return true;
+     625       35552 :     else if(residuename=="ARG") return true;
+     626       33312 :     else if(residuename=="ASN") return true;
+     627       31392 :     else if(residuename=="ASP") return true;
+     628       29712 :     else if(residuename=="CYS") return true;
+     629       29582 :     else if(residuename=="GLN") return true;
+     630       26782 :     else if(residuename=="GLU") return true;
+     631       25522 :     else if(residuename=="GLY") return true;
+     632       23702 :     else if(residuename=="HIS") return true;
+     633       23702 :     else if(residuename=="ILE") return true;
+     634       21452 :     else if(residuename=="LEU") return true;
+     635       17462 :     else if(residuename=="LYS") return true;
+     636       14762 :     else if(residuename=="MET") return true;
+     637       13162 :     else if(residuename=="PHE") return true;
+     638       10522 :     else if(residuename=="PRO") return true;
+     639        8542 :     else if(residuename=="SER") return true;
+     640        7112 :     else if(residuename=="THR") return true;
+     641        5762 :     else if(residuename=="TRP") return true;
+     642        5762 :     else if(residuename=="TYR") return true;
+     643        4382 :     else if(residuename=="VAL") return true;
+     644             : // Terminal groups
+     645        1492 :     else if(residuename=="ACE") return true;
+     646        1492 :     else if(residuename=="NME") return true;
+     647        1492 :     else if(residuename=="NH2") return true;
+     648             : // Alternative residue names in common force fields
+     649        1492 :     else if(residuename=="GLH") return true; // neutral GLU
+     650        1492 :     else if(residuename=="ASH") return true; // neutral ASP
+     651        1492 :     else if(residuename=="HID") return true; // HIS-D amber
+     652        1492 :     else if(residuename=="HSD") return true; // HIS-D charmm
+     653        1492 :     else if(residuename=="HIE") return true; // HIS-E amber
+     654        1112 :     else if(residuename=="HSE") return true; // HIS-E charmm
+     655        1112 :     else if(residuename=="HIP") return true; // HIS-P amber
+     656        1112 :     else if(residuename=="HSP") return true; // HIS-P charmm
+     657             : // Weird amino acids
+     658        1112 :     else if(residuename=="NLE") return true;
+     659        1112 :     else if(residuename=="SFO") return true;
+     660        1112 :     else return false;
+     661           0 :   } else if( type=="dna" ) {
+     662           0 :     if(residuename=="A") return true;
+     663           0 :     else if(residuename=="A5") return true;
+     664           0 :     else if(residuename=="A3") return true;
+     665           0 :     else if(residuename=="AN") return true;
+     666           0 :     else if(residuename=="G") return true;
+     667           0 :     else if(residuename=="G5") return true;
+     668           0 :     else if(residuename=="G3") return true;
+     669           0 :     else if(residuename=="GN") return true;
+     670           0 :     else if(residuename=="T") return true;
+     671           0 :     else if(residuename=="T5") return true;
+     672           0 :     else if(residuename=="T3") return true;
+     673           0 :     else if(residuename=="TN") return true;
+     674           0 :     else if(residuename=="C") return true;
+     675           0 :     else if(residuename=="C5") return true;
+     676           0 :     else if(residuename=="C3") return true;
+     677           0 :     else if(residuename=="CN") return true;
+     678           0 :     else if(residuename=="DA") return true;
+     679           0 :     else if(residuename=="DA5") return true;
+     680           0 :     else if(residuename=="DA3") return true;
+     681           0 :     else if(residuename=="DAN") return true;
+     682           0 :     else if(residuename=="DG") return true;
+     683           0 :     else if(residuename=="DG5") return true;
+     684           0 :     else if(residuename=="DG3") return true;
+     685           0 :     else if(residuename=="DGN") return true;
+     686           0 :     else if(residuename=="DT") return true;
+     687           0 :     else if(residuename=="DT5") return true;
+     688           0 :     else if(residuename=="DT3") return true;
+     689           0 :     else if(residuename=="DTN") return true;
+     690           0 :     else if(residuename=="DC") return true;
+     691           0 :     else if(residuename=="DC5") return true;
+     692           0 :     else if(residuename=="DC3") return true;
+     693           0 :     else if(residuename=="DCN") return true;
+     694           0 :     else return false;
+     695           0 :   } else if( type=="rna" ) {
+     696           0 :     if(residuename=="A") return true;
+     697           0 :     else if(residuename=="A5") return true;
+     698           0 :     else if(residuename=="A3") return true;
+     699           0 :     else if(residuename=="AN") return true;
+     700           0 :     else if(residuename=="G") return true;
+     701           0 :     else if(residuename=="G5") return true;
+     702           0 :     else if(residuename=="G3") return true;
+     703           0 :     else if(residuename=="GN") return true;
+     704           0 :     else if(residuename=="U") return true;
+     705           0 :     else if(residuename=="U5") return true;
+     706           0 :     else if(residuename=="U3") return true;
+     707           0 :     else if(residuename=="UN") return true;
+     708           0 :     else if(residuename=="C") return true;
+     709           0 :     else if(residuename=="C5") return true;
+     710           0 :     else if(residuename=="C3") return true;
+     711           0 :     else if(residuename=="CN") return true;
+     712           0 :     else if(residuename=="RA") return true;
+     713           0 :     else if(residuename=="RA5") return true;
+     714           0 :     else if(residuename=="RA3") return true;
+     715           0 :     else if(residuename=="RAN") return true;
+     716           0 :     else if(residuename=="RG") return true;
+     717           0 :     else if(residuename=="RG5") return true;
+     718           0 :     else if(residuename=="RG3") return true;
+     719           0 :     else if(residuename=="RGN") return true;
+     720           0 :     else if(residuename=="RU") return true;
+     721           0 :     else if(residuename=="RU5") return true;
+     722           0 :     else if(residuename=="RU3") return true;
+     723           0 :     else if(residuename=="RUN") return true;
+     724           0 :     else if(residuename=="RC") return true;
+     725           0 :     else if(residuename=="RC5") return true;
+     726           0 :     else if(residuename=="RC3") return true;
+     727           0 :     else if(residuename=="RCN") return true;
+     728           0 :     else return false;
+     729           0 :   } else if( type=="water" ) {
+     730           0 :     if(residuename=="SOL") return true;
+     731           0 :     if(residuename=="WAT") return true;
+     732           0 :     return false;
+     733           0 :   } else if( type=="ion" ) {
+     734           0 :     if(residuename=="IB+") return true;
+     735           0 :     if(residuename=="CA") return true;
+     736           0 :     if(residuename=="CL") return true;
+     737           0 :     if(residuename=="NA") return true;
+     738           0 :     if(residuename=="MG") return true;
+     739           0 :     if(residuename=="K") return true;
+     740           0 :     if(residuename=="RB") return true;
+     741           0 :     if(residuename=="CS") return true;
+     742           0 :     if(residuename=="LI") return true;
+     743           0 :     if(residuename=="ZN") return true;
+     744           0 :     return false;
+     745             :   }
+     746             :   return false;
+     747             : }
+     748             : 
+     749             : }
+     750             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func-sort-c.html b/coverage/tools/Pbc.cpp.func-sort-c.html new file mode 100644 index 0000000000..f63e7cb405 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv2174
_ZNK4PLMD3Pbc13isOrthorombicEv8526
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_St6vectorINS_13VectorGenericILj3EEESaIS3_EE20630
_ZNK4PLMD3Pbc6getBoxEv42335
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE71263
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220663
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZN4PLMD3PbcC2Ev822494
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1219963
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi208705009
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func.html b/coverage/tools/Pbc.cpp.func.html new file mode 100644 index 0000000000..11a2549e95 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE71263
_ZN4PLMD3PbcC2Ev822494
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_St6vectorINS_13VectorGenericILj3EEESaIS3_EE20630
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1219963
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZNK4PLMD3Pbc13isOrthorombicEv8526
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj220663
_ZNK4PLMD3Pbc6getBoxEv42335
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi208705009
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv2174
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.gcov.html b/coverage/tools/Pbc.cpp.gcov.html new file mode 100644 index 0000000000..eac79b38e9 --- /dev/null +++ b/coverage/tools/Pbc.cpp.gcov.html @@ -0,0 +1,323 @@ + + + + + + + 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-05-27 13:05: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      822494 : Pbc::Pbc():
+      33    12337410 :   type(unset)
+      34             : {
+      35      822494 :   box.zero();
+      36      822494 :   invBox.zero();
+      37      822494 : }
+      38             : 
+      39       20630 : void Pbc::buildShifts(std::vector<Vector> shifts[2][2][2])const {
+      40             :   const double small=1e-28;
+      41             : 
+      42             : // clear all shifts
+      43      309450 :   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      825200 :   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      557010 :         const int ishift[3]= {l,m,n};
+      51      557010 :         Vector dshift(l,m,n);
+      52             : 
+      53             : // count how many components are != 0
+      54             :         unsigned count=0;
+      55     2228040 :         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      647898 :         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      371340 :         Vector cosdir=matmul(reduced,transpose(reduced),dshift);
+      66      371340 :         double dp=dotProduct(dshift,cosdir);
+      67      371340 :         double ref=modulo2(dshift)*modulo2(cosdir);
+      68      371340 :         if(std::fabs(ref-dp*dp)<small) continue;
+      69             : 
+      70             : // here we start pruning depending on the sign of the scaled coordinate
+      71     4206780 :         for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {
+      72             : 
+      73     2243616 :               const int block[3]= {2*i-1,2*j-1,2*k-1};
+      74             : 
+      75             : // skip cases where shift would bring too far from origin
+      76             :               bool skip=false;
+      77     8974464 :               for(int s=0; s<3; s++) if(ishift[s]*block[s]>0) skip=true;
+      78     2534702 :               if(skip) continue;
+      79             :               skip=true;
+      80     3066608 :               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     2299956 :                 if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
+      84             :               }
+      85      766652 :               if(skip)continue;
+      86             : 
+      87             : // if we arrive to this point, shift is eligible and is added to the list
+      88      951132 :               shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
+      89             :             }
+      90             :       }
+      91       20630 : }
+      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       71263 : void Pbc::setBox(const Tensor&b) {
+     116       71263 :   box=b;
+     117             : // detect type:
+     118             :   const double epsilon=1e-28;
+     119             : 
+     120       71263 :   type=unset;
+     121       71263 :   double det=box.determinant();
+     122       71263 :   if(det*det<epsilon) return;
+     123             : 
+     124             :   bool cxy=false;
+     125             :   bool cxz=false;
+     126             :   bool cyz=false;
+     127       65176 :   if(box(0,1)*box(0,1)<epsilon && box(1,0)*box(1,0)<epsilon) cxy=true;
+     128       65176 :   if(box(0,2)*box(0,2)<epsilon && box(2,0)*box(2,0)<epsilon) cxz=true;
+     129       65176 :   if(box(1,2)*box(1,2)<epsilon && box(2,1)*box(2,1)<epsilon) cyz=true;
+     130             : 
+     131       65176 :   invBox=box.inverse();
+     132             : 
+     133       65176 :   if(cxy && cxz && cyz) type=orthorombic;
+     134       20630 :   else type=generic;
+     135             : 
+     136       65176 :   if(type==orthorombic) {
+     137       44546 :     reduced=box;
+     138       44546 :     invReduced=inverse(reduced);
+     139      178184 :     for(unsigned i=0; i<3; i++) {
+     140      133638 :       diag[i]=box[i][i];
+     141      133638 :       hdiag[i]=0.5*box[i][i];
+     142      133638 :       mdiag[i]=-0.5*box[i][i];
+     143             :     }
+     144             :   } else {
+     145       20630 :     reduced=box;
+     146       20630 :     LatticeReduction::reduce(reduced);
+     147       20630 :     invReduced=inverse(reduced);
+     148       20630 :     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      220663 : void Pbc::apply(std::vector<Vector>& dlist, unsigned max_index) const {
+     159      220663 :   if (max_index==0) max_index=dlist.size();
+     160      220663 :   if(type==unset) {
+     161             :     // do nothing
+     162      214239 :   } 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  1603605381 :     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      220663 : }
+     179             : 
+     180   208705009 : Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const {
+     181   208705009 :   Vector d=delta(v1,v2);
+     182   208705009 :   if(type==unset) {
+     183             :     // do nothing
+     184   184840816 :   } 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   546059116 :     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   208705009 :   return d;
+     225             : }
+     226             : 
+     227     1219963 : Vector Pbc::realToScaled(const Vector&d)const {
+     228     1219963 :   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        8526 : bool Pbc::isOrthorombic()const {
+     236        8526 :   return type==orthorombic;
+     237             : }
+     238             : 
+     239       42335 : const Tensor& Pbc::getBox()const {
+     240       42335 :   return box;
+     241             : }
+     242             : 
+     243        2174 : const Tensor& Pbc::getInvBox()const {
+     244        2174 :   return invBox;
+     245             : }
+     246             : 
+     247             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func-sort-c.html b/coverage/tools/Pbc.h.func-sort-c.html new file mode 100644 index 0000000000..f10659a6dc --- /dev/null +++ b/coverage/tools/Pbc.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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:33100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func.html b/coverage/tools/Pbc.h.func.html new file mode 100644 index 0000000000..4fa679bdfe --- /dev/null +++ b/coverage/tools/Pbc.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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:33100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.gcov.html b/coverage/tools/Pbc.h.gcov.html new file mode 100644 index 0000000000..dcb8d485cb --- /dev/null +++ b/coverage/tools/Pbc.h.gcov.html @@ -0,0 +1,188 @@ + + + + + + + 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:33100.0 %
Date:2024-05-27 13:05: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        2403 : 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   201867289 :   return distance(v1,v2,NULL);
+     103             : }
+     104             : 
+     105             : inline
+     106             : bool Pbc::isSet()const {
+     107       14258 :   return type!=unset;
+     108             : }
+     109             : 
+     110             : }
+     111             : 
+     112             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func-sort-c.html b/coverage/tools/PlumedHandle.cpp.func-sort-c.html new file mode 100644 index 0000000000..b607b32de6 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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:223562.9 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func.html b/coverage/tools/PlumedHandle.cpp.func.html new file mode 100644 index 0000000000..8eaea708a4 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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:223562.9 %
Date:2024-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.gcov.html b/coverage/tools/PlumedHandle.cpp.gcov.html new file mode 100644 index 0000000000..138d7954a8 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + 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:223562.9 %
Date:2024-05-27 13:05: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             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 1
+      39             : #include "../wrapper/Plumed.h"
+      40             : 
+      41             : namespace PLMD
+      42             : {
+      43             : 
+      44             : 
+      45          11 : PlumedHandle::PlumedHandle():
+      46          11 :   local(Tools::make_unique<PlumedMain>())
+      47             : {
+      48          11 : }
+      49             : 
+      50           1 : PlumedHandle::PlumedHandle(const char* kernel)
+      51             : #ifdef __PLUMED_HAS_DLOPEN
+      52             :   :
+      53           1 :   loaded(plumed_c2v(plumed_create_dlopen(kernel)))
+      54             : {
+      55             :   if(!plumed_valid(plumed_v2c(loaded))) {
+      56             :     // this is necessary to make sure loaded is properly destroyed
+      57           0 :     plumed_finalize(plumed_v2c(loaded));
+      58           0 :     plumed_error() << "You are trying to dynamically load a kernel, but the path " << kernel <<" could not be opened";
+      59             :   }
+      60           1 : }
+      61             : #else
+      62             : {
+      63             :   plumed_error() << "You are trying to dynamically load a kernel, but PLUMED was compiled without dlopen";
+      64             : }
+      65             : #endif
+      66             : 
+      67          12 : PlumedHandle::~PlumedHandle() {
+      68          12 :   if(loaded) plumed_finalize(plumed_v2c(loaded));
+      69          12 : }
+      70             : 
+      71           1 : PlumedHandle PlumedHandle::dlopen(const char* path) {
+      72           1 :   return PlumedHandle(path);
+      73             : }
+      74             : 
+      75        1476 : void PlumedHandle::cmd(const std::string & key,const TypesafePtr & ptr) {
+      76        1476 :   if(local) {
+      77        2508 :     local->cmd(key.c_str(),ptr);
+      78         222 :   } else if(loaded) {
+      79             :     plumed_safeptr safe;
+      80         222 :     safe.ptr=ptr.getRaw();
+      81         222 :     safe.nelem=ptr.getNelem();
+      82         222 :     safe.shape=const_cast<std::size_t*>(ptr.getShape());
+      83         222 :     safe.flags=ptr.getFlags();
+      84         222 :     safe.opt=nullptr;
+      85         222 :     plumed_cmd(plumed_v2c(loaded),key.c_str(),safe);
+      86           0 :   } else plumed_error() << "should never arrive here (either one or the other should work)";
+      87        1476 : }
+      88             : 
+      89           0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept:
+      90             :   local(std::move(other.local)),
+      91           0 :   loaded(other.loaded)
+      92             : {
+      93           0 :   other.loaded=nullptr;
+      94           0 : }
+      95             : 
+      96           0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept {
+      97           0 :   if(this!=&other) {
+      98           0 :     if(loaded) plumed_finalize(plumed_v2c(loaded));
+      99             :     local=std::move(other.local);
+     100           0 :     loaded=other.loaded;
+     101           0 :     other.loaded=nullptr;
+     102             :   }
+     103           0 :   return *this;
+     104             : }
+     105             : 
+     106             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func-sort-c.html b/coverage/tools/RMSD.cpp.func-sort-c.html new file mode 100644 index 0000000000..12e29e01dd --- /dev/null +++ b/coverage/tools/RMSD.cpp.func-sort-c.html @@ -0,0 +1,392 @@ + + + + + + + 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-05-27 13:05: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_b172
_ZN4PLMD12RMSDCoreData18getPositionsCenterEv210
_ZN4PLMD4RMSD16calc_FitElementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EERS5_RS3_RKb210
_ZN4PLMD4RMSD5clearEv471
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb672
_ZN4PLMD4RMSD18calc_Rot_DRotDRr01ERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERSt5arrayISB_IS9_Lm3EELm3EEb1092
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb1092
_ZN4PLMD4RMSD3setERKNS_3PDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1108
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb1575
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1575
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb1575
_ZN4PLMD12RMSDCoreData37getRotationMatrixReferenceToPositionsEv1764
_ZN4PLMD12RMSDCoreData20getCenteredReferenceEv4985
_ZN4PLMD12RMSDCoreData30getAlignedPositionsToReferenceEv4985
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb4985
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb4985
_ZN4PLMD12RMSDCoreData20getCenteredPositionsEv5195
_ZN4PLMD12RMSDCoreData22getDRotationDPositionsEb5195
_ZN4PLMD12RMSDCoreData37getRotationMatrixPositionsToReferenceEv5195
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb6960
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD4RMSD12getReferenceEv45192
_ZN4PLMD4RMSD27calculateWithCloseStructureERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RKNS_13TensorGenericILj3ELj3EEESC_RSt5arrayISD_ISA_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46767
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE46783
_ZN4PLMD4RMSDC2Ev46809
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv50850
_ZN4PLMD12RMSDCoreData11getDistanceEb52152
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b192638
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b332887
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b356282
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func.html b/coverage/tools/RMSD.cpp.func.html new file mode 100644 index 0000000000..f207df97ff --- /dev/null +++ b/coverage/tools/RMSD.cpp.func.html @@ -0,0 +1,392 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD4RMSDC2Ev46809
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b172
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb4985
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b2
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b192638
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b112
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b356282
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb4985
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b1
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb1092
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b332887
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.gcov.html b/coverage/tools/RMSD.cpp.gcov.html new file mode 100644 index 0000000000..5041f7135d --- /dev/null +++ b/coverage/tools/RMSD.cpp.gcov.html @@ -0,0 +1,1548 @@ + + + + + + + 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-05-27 13:05: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       46809 : RMSD::RMSD() : alignmentMethod(SIMPLE),reference_center_is_calculated(false),reference_center_is_removed(false),positions_center_is_calculated(false),positions_center_is_removed(false) {}
+      33             : 
+      34             : ///
+      35             : /// general method to set all the rmsd property at once by using a pdb where occupancy column sets the weights for the atoms involved in the
+      36             : /// alignment and beta sets the weight that are used for calculating the displacement.
+      37             : ///
+      38        1108 : void RMSD::set(const PDB&pdb, const std::string & mytype, bool remove_center, bool normalize_weights ) {
+      39             : 
+      40        1108 :   set(pdb.getOccupancy(),pdb.getBeta(),pdb.getPositions(),mytype,remove_center,normalize_weights);
+      41             : 
+      42        1108 : }
+      43        1575 : void RMSD::set(const std::vector<double> & align, const std::vector<double> & displace, const std::vector<Vector> & reference, const std::string & mytype, bool remove_center, bool normalize_weights ) {
+      44             : 
+      45        1575 :   setReference(reference); // this by default remove the com and assumes uniform weights
+      46        1575 :   setAlign(align, normalize_weights, remove_center); // this recalculates the com with weights. If remove_center=false then it restore the center back
+      47        1575 :   setDisplace(displace, normalize_weights);  // this is does not affect any calculation of the weights
+      48        1575 :   setType(mytype);
+      49             : 
+      50        1575 : }
+      51             : 
+      52       46767 : void RMSD::setType(const std::string & mytype) {
+      53             : 
+      54       46767 :   alignmentMethod=SIMPLE; // initialize with the simplest case: no rotation
+      55       46767 :   if (mytype=="SIMPLE") {
+      56           0 :     alignmentMethod=SIMPLE;
+      57             :   }
+      58       46767 :   else if (mytype=="OPTIMAL") {
+      59       46767 :     alignmentMethod=OPTIMAL;
+      60             :   }
+      61           0 :   else if (mytype=="OPTIMAL-FAST") {
+      62           0 :     alignmentMethod=OPTIMAL_FAST;
+      63             :   }
+      64           0 :   else plumed_merror("unknown RMSD type" + mytype);
+      65             : 
+      66       46767 : }
+      67             : 
+      68         471 : void RMSD::clear() {
+      69             :   reference.clear();
+      70         471 :   reference_center.zero();
+      71         471 :   reference_center_is_calculated=false;
+      72         471 :   reference_center_is_removed=false;
+      73             :   align.clear();
+      74             :   displace.clear();
+      75         471 :   positions_center.zero();
+      76         471 :   positions_center_is_calculated=false;
+      77         471 :   positions_center_is_removed=false;
+      78         471 : }
+      79             : 
+      80           5 : std::string RMSD::getMethod() {
+      81             :   std::string mystring;
+      82           5 :   switch(alignmentMethod) {
+      83           0 :   case SIMPLE: mystring.assign("SIMPLE"); break;
+      84           5 :   case OPTIMAL: mystring.assign("OPTIMAL"); break;
+      85           0 :   case OPTIMAL_FAST: mystring.assign("OPTIMAL-FAST"); break;
+      86             :   }
+      87           5 :   return mystring;
+      88             : }
+      89             : ///
+      90             : /// this calculates the center of mass for the reference and removes it from the reference itself
+      91             : /// considering uniform weights for alignment
+      92             : ///
+      93       46783 : void RMSD::setReference(const std::vector<Vector> & reference) {
+      94       46783 :   unsigned n=reference.size();
+      95       46783 :   this->reference=reference;
+      96       46783 :   plumed_massert(align.empty(),"you should first clear() an RMSD object, then set a new reference");
+      97       46783 :   plumed_massert(displace.empty(),"you should first clear() an RMSD object, then set a new reference");
+      98       46783 :   align.resize(n,1.0/n);
+      99       46783 :   displace.resize(n,1.0/n);
+     100      673845 :   for(unsigned i=0; i<n; i++) reference_center+=this->reference[i]*align[i];
+     101             :   #pragma omp simd
+     102      627062 :   for(unsigned i=0; i<n; i++) this->reference[i]-=reference_center;
+     103       46783 :   reference_center_is_calculated=true;
+     104       46783 :   reference_center_is_removed=true;
+     105       46783 : }
+     106       45192 : std::vector<Vector> RMSD::getReference() {
+     107       45192 :   return reference;
+     108             : }
+     109             : ///
+     110             : /// the alignment weights are here normalized to 1 and  the center of the reference is removed accordingly
+     111             : ///
+     112        1575 : void RMSD::setAlign(const std::vector<double> & align, bool normalize_weights, bool remove_center) {
+     113        1575 :   unsigned n=reference.size();
+     114        1575 :   plumed_massert(this->align.size()==align.size(),"mismatch in dimension of align/displace arrays");
+     115        1575 :   this->align=align;
+     116        1575 :   if(normalize_weights) {
+     117             :     double w=0.0;
+     118        3140 :     #pragma omp simd reduction(+:w)
+     119       39333 :     for(unsigned i=0; i<n; i++) w+=this->align[i];
+     120        1570 :     if(w>epsilon) {
+     121        1570 :       double inv=1.0/w;
+     122             :       #pragma omp simd
+     123       39333 :       for(unsigned i=0; i<n; i++) this->align[i]*=inv;
+     124             :     } else {
+     125           0 :       double inv=1.0/n;
+     126             :       #pragma omp simd
+     127           0 :       for(unsigned i=0; i<n; i++) this->align[i]=inv;
+     128             :     }
+     129             :   }
+     130             :   // recalculate the center anyway
+     131             :   // just remove the center if that is asked
+     132             :   // if the center was removed before, then add it and store the new one
+     133        1575 :   if(reference_center_is_removed) {
+     134        1575 :     plumed_massert(reference_center_is_calculated," seems that the reference center has been removed but not calculated and stored!");
+     135        1575 :     addCenter(reference,reference_center);
+     136             :   }
+     137        1575 :   reference_center=calculateCenter(reference,this->align);
+     138        1575 :   reference_center_is_calculated=true;
+     139        1575 :   if(remove_center) {
+     140        1570 :     removeCenter(reference,reference_center);
+     141        1570 :     reference_center_is_removed=true;
+     142             :   } else {
+     143           5 :     reference_center_is_removed=false;
+     144             :   }
+     145        1575 : }
+     146           0 : std::vector<double> RMSD::getAlign() {
+     147           0 :   return align;
+     148             : }
+     149             : ///
+     150             : /// here the weigth for normalized weighths are normalized and set
+     151             : ///
+     152        1575 : void RMSD::setDisplace(const std::vector<double> & displace, bool normalize_weights) {
+     153        1575 :   unsigned n=reference.size();
+     154        1575 :   plumed_massert(this->displace.size()==displace.size(),"mismatch in dimension of align/displace arrays");
+     155        1575 :   this->displace=displace;
+     156        1575 :   if(normalize_weights) {
+     157             :     double w=0.0;
+     158        3140 :     #pragma omp simd reduction(+:w)
+     159       39333 :     for(unsigned i=0; i<n; i++) w+=this->displace[i];
+     160        1570 :     if(w>epsilon) {
+     161        1570 :       double inv=1.0/w;
+     162             :       #pragma omp simd
+     163       39333 :       for(unsigned i=0; i<n; i++) this->displace[i]*=inv;
+     164             :     } else {
+     165           0 :       double inv=1.0/n;
+     166             :       #pragma omp simd
+     167           0 :       for(unsigned i=0; i<n; i++) this->displace[i]=inv;
+     168             :     }
+     169             :   }
+     170        1575 : }
+     171           0 : std::vector<double> RMSD::getDisplace() {
+     172           0 :   return displace;
+     173             : }
+     174             : ///
+     175             : /// This is the main workhorse for rmsd that decides to use specific optimal alignment versions
+     176             : ///
+     177      332887 : double RMSD::calculate(const std::vector<Vector> & positions,std::vector<Vector> &derivatives, bool squared)const {
+     178             : 
+     179             :   double ret=0.;
+     180             : 
+     181      332887 :   switch(alignmentMethod) {
+     182             :   case SIMPLE : {
+     183             :     //  do a simple alignment without rotation
+     184           0 :     std::vector<Vector> displacement( derivatives.size() );
+     185           0 :     ret=simpleAlignment(align,displace,positions,reference,derivatives,displacement,squared);
+     186             :     break;
+     187           0 :   } case OPTIMAL_FAST : {
+     188             :     // this is calling the fastest option:
+     189           0 :     if(align==displace) ret=optimalAlignment<false,true>(align,displace,positions,reference,derivatives,squared);
+     190           0 :     else                ret=optimalAlignment<false,false>(align,displace,positions,reference,derivatives,squared);
+     191             :     break;
+     192             : 
+     193      332887 :   } case OPTIMAL : {
+     194             :     // this is the fast routine but in the "safe" mode, which gives less numerical error:
+     195      332887 :     if(align==displace) ret=optimalAlignment<true,true>(align,displace,positions,reference,derivatives,squared);
+     196           1 :     else ret=optimalAlignment<true,false>(align,displace,positions,reference,derivatives,squared);
+     197             :     break;
+     198             :   }
+     199             :   }
+     200             : 
+     201      332887 :   return ret;
+     202             : 
+     203             : }
+     204             : 
+     205             : 
+     206             : /// convenience method for calculating the standard derivatives and the derivative of the rmsd respect to the reference position
+     207           1 : double RMSD::calc_DDistDRef( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, const bool squared  ) {
+     208             :   double ret=0.;
+     209           1 :   switch(alignmentMethod) {
+     210           0 :   case SIMPLE:
+     211           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     212             :     break;
+     213           0 :   case OPTIMAL_FAST:
+     214           0 :     if(align==displace) ret=optimalAlignment_DDistDRef<false,true>(align,displace,positions,reference,derivatives,DDistDRef, squared);
+     215           0 :     else                ret=optimalAlignment_DDistDRef<false,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     216             :     break;
+     217           1 :   case OPTIMAL:
+     218           1 :     if(align==displace) ret=optimalAlignment_DDistDRef<true,true>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     219           1 :     else                ret=optimalAlignment_DDistDRef<true,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     220             :     break;
+     221             :   }
+     222           1 :   return ret;
+     223             : 
+     224             : }
+     225             : 
+     226             : /// convenience method for calculating the standard derivatives and the derivative of the rmsd respect to the reference position without the matrix contribution
+     227             : /// as required by SOMA
+     228           0 : double RMSD::calc_SOMA( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, const bool squared  ) {
+     229             :   double ret=0.;
+     230           0 :   switch(alignmentMethod) {
+     231           0 :   case SIMPLE:
+     232           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     233             :     break;
+     234           0 :   case OPTIMAL_FAST:
+     235           0 :     if(align==displace) ret=optimalAlignment_SOMA<false,true>(align,displace,positions,reference,derivatives,DDistDRef, squared);
+     236           0 :     else                ret=optimalAlignment_SOMA<false,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     237             :     break;
+     238           0 :   case OPTIMAL:
+     239           0 :     if(align==displace) ret=optimalAlignment_SOMA<true,true>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     240           0 :     else                ret=optimalAlignment_SOMA<true,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     241             :     break;
+     242             :   }
+     243           0 :   return ret;
+     244             : 
+     245             : }
+     246             : 
+     247           0 : double RMSD::calc_DDistDRef_Rot_DRotDPos( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, Tensor & Rot, Matrix<std::vector<Vector> > &DRotDPos, const bool squared  ) {
+     248             :   double ret=0.;
+     249           0 :   switch(alignmentMethod) {
+     250           0 :   case SIMPLE:
+     251           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     252             :     break;
+     253           0 :   case OPTIMAL_FAST:
+     254           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos<false,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos,  squared);
+     255           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos<false,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     256             :     break;
+     257           0 :   case OPTIMAL:
+     258           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos<true,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     259           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos<true,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     260             :     break;
+     261             :   }
+     262           0 :   return ret;
+     263             : }
+     264             : 
+     265           0 : double RMSD::calc_DDistDRef_Rot_DRotDPos_DRotDRef( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, Tensor & Rot, Matrix<std::vector<Vector> > &DRotDPos,  Matrix<std::vector<Vector> > &DRotDRef, const bool squared  ) {
+     266             :   double ret=0.;
+     267           0 :   switch(alignmentMethod) {
+     268           0 :   case SIMPLE:
+     269           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     270             :     break;
+     271           0 :   case OPTIMAL_FAST:
+     272           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<false,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef,   squared);
+     273           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<false,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef,  squared);
+     274             :     break;
+     275           0 :   case OPTIMAL:
+     276           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<true,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef, squared);
+     277           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<true,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef, squared);
+     278             :     break;
+     279             :   }
+     280           0 :   return ret;
+     281             : }
+     282             : 
+     283        1092 : double RMSD::calc_Rot_DRotDRr01( const std::vector<Vector>& positions, Tensor & Rotation, std::array<std::array<Tensor,3>,3> & DRotDRr01, const bool squared) {
+     284             :   double ret=0.;
+     285        1092 :   switch(alignmentMethod) {
+     286           0 :   case SIMPLE:
+     287           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     288             :     break;
+     289           0 :   case OPTIMAL_FAST:
+     290           0 :     if(align==displace) ret=optimalAlignment_Rot_DRotDRr01<false,true>(align,displace,positions,reference, Rotation, DRotDRr01,   squared);
+     291           0 :     else                ret=optimalAlignment_Rot_DRotDRr01<false,false>(align,displace,positions,reference, Rotation, DRotDRr01,  squared);
+     292             :     break;
+     293        1092 :   case OPTIMAL:
+     294        1092 :     if(align==displace) ret=optimalAlignment_Rot_DRotDRr01<true,true>(align,displace,positions,reference, Rotation, DRotDRr01, squared);
+     295           0 :     else                ret=optimalAlignment_Rot_DRotDRr01<true,false>(align,displace,positions,reference, Rotation, DRotDRr01, squared);
+     296             :     break;
+     297             :   }
+     298        1092 :   return ret;
+     299             : }
+     300             : 
+     301         672 : double RMSD::calc_Rot( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, Tensor & Rotation, const bool squared) {
+     302             :   double ret=0.;
+     303         672 :   switch(alignmentMethod) {
+     304           0 :   case SIMPLE:
+     305           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     306             :     break;
+     307           0 :   case OPTIMAL_FAST:
+     308           0 :     if(align==displace) ret=optimalAlignment_Rot<false,true>(align,displace,positions,reference,derivatives, Rotation, squared);
+     309           0 :     else                ret=optimalAlignment_Rot<false,false>(align,displace,positions,reference,derivatives, Rotation, squared);
+     310             :     break;
+     311         672 :   case OPTIMAL:
+     312         672 :     if(align==displace) ret=optimalAlignment_Rot<true,true>(align,displace,positions,reference,derivatives, Rotation, squared);
+     313           0 :     else                ret=optimalAlignment_Rot<true,false>(align,displace,positions,reference,derivatives, Rotation, squared);
+     314             :     break;
+     315             :   }
+     316         672 :   return ret;
+     317             : }
+     318             : 
+     319       45192 : double RMSD::calculateWithCloseStructure( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01, const bool squared) {
+     320             :   double ret=0.;
+     321       45192 :   switch(alignmentMethod) {
+     322           0 :   case SIMPLE:
+     323           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     324             :     break;
+     325           0 :   case OPTIMAL_FAST:
+     326           0 :     if(align==displace) ret=optimalAlignmentWithCloseStructure<false,true>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     327           0 :     else                ret=optimalAlignmentWithCloseStructure<false,false>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     328             :     break;
+     329       45192 :   case OPTIMAL:
+     330       45192 :     if(align==displace) ret=optimalAlignmentWithCloseStructure<true,true>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     331           0 :     else                ret=optimalAlignmentWithCloseStructure<true,false>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     332             :     break;
+     333             :   }
+     334       45192 :   return ret;
+     335             : }
+     336             : 
+     337        4985 : double RMSD::calc_PCAelements( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos,std::vector<Vector>  & alignedpositions, std::vector<Vector> & centeredpositions, std::vector<Vector> &centeredreference, const bool& squared  ) const {
+     338             :   double ret=0.;
+     339        4985 :   switch(alignmentMethod) {
+     340           0 :   case SIMPLE:
+     341           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     342             :     break;
+     343           0 :   case OPTIMAL_FAST:
+     344           0 :     if(align==displace) ret=optimalAlignment_PCA<false,true>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     345           0 :     else                ret=optimalAlignment_PCA<false,false>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     346             :     break;
+     347        4985 :   case OPTIMAL:
+     348        4985 :     if(align==displace) ret=optimalAlignment_PCA<true,true>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     349           0 :     else                ret=optimalAlignment_PCA<true,false>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     350             :     break;
+     351             :   }
+     352        4985 :   return ret;
+     353             : }
+     354             : 
+     355             : 
+     356         210 : double RMSD::calc_FitElements( const std::vector<Vector>& positions, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos, std::vector<Vector> & centeredpositions, Vector &center_positions, const bool& squared  ) {
+     357             :   double ret=0.;
+     358         210 :   switch(alignmentMethod) {
+     359           0 :   case SIMPLE:
+     360           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     361             :     break;
+     362           0 :   case OPTIMAL_FAST:
+     363           0 :     if(align==displace)ret=optimalAlignment_Fit<false,true>(align,displace,positions,reference, Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     364           0 :     else               ret=optimalAlignment_Fit<false,false>(align,displace,positions,reference, Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     365             :     break;
+     366         210 :   case OPTIMAL:
+     367         210 :     if(align==displace)ret=optimalAlignment_Fit<true,true>(align,displace,positions,reference,Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     368          60 :     else               ret=optimalAlignment_Fit<true,false>(align,displace,positions,reference,Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     369             :     break;
+     370             :   }
+     371         210 :   return ret;
+     372             : }
+     373             : 
+     374             : 
+     375             : 
+     376             : 
+     377             : 
+     378             : 
+     379         172 : double RMSD::simpleAlignment(const  std::vector<double>  & align,
+     380             :                              const  std::vector<double>  & displace,
+     381             :                              const std::vector<Vector> & positions,
+     382             :                              const std::vector<Vector> & reference,
+     383             :                              std::vector<Vector>  & derivatives,
+     384             :                              std::vector<Vector>  & displacement,
+     385             :                              bool squared)const {
+     386             : 
+     387             :   double dist(0);
+     388         172 :   unsigned n=reference.size();
+     389             : 
+     390         172 :   Vector apositions;
+     391         172 :   Vector areference;
+     392         172 :   Vector dpositions;
+     393         172 :   Vector dreference;
+     394             : 
+     395        3997 :   for(unsigned i=0; i<n; i++) {
+     396        3825 :     double aw=align[i];
+     397        3825 :     double dw=displace[i];
+     398        3825 :     apositions+=positions[i]*aw;
+     399        3825 :     areference+=reference[i]*aw;
+     400        3825 :     dpositions+=positions[i]*dw;
+     401        3825 :     dreference+=reference[i]*dw;
+     402             :   }
+     403             : 
+     404         172 :   Vector shift=((apositions-areference)-(dpositions-dreference));
+     405        3997 :   for(unsigned i=0; i<n; i++) {
+     406        3825 :     displacement[i]=(positions[i]-apositions)-(reference[i]-areference);
+     407        3825 :     dist+=displace[i]*displacement[i].modulo2();
+     408        3825 :     derivatives[i]=2*(displace[i]*displacement[i]+align[i]*shift);
+     409             :   }
+     410             : 
+     411         172 :   if(!squared) {
+     412             :     // sqrt
+     413         118 :     dist=std::sqrt(dist);
+     414             :     ///// sqrt on derivatives
+     415        3637 :     for(unsigned i=0; i<n; i++) {derivatives[i]*=(0.5/dist);}
+     416             :   }
+     417         172 :   return dist;
+     418             : }
+     419             : 
+     420             : // this below enable the standard case for rmsd where the rmsd is calculated and the derivative of rmsd respect to positions is retrieved
+     421             : // additionally this assumes that the com of the reference is already subtracted.
+     422             : #define OLDRMSD
+     423             : #ifdef OLDRMSD
+     424             : // notice that in the current implementation the safe argument only makes sense for
+     425             : // align==displace
+     426             : template <bool safe,bool alEqDis>
+     427      549034 : double RMSD::optimalAlignment(const  std::vector<double>  & align,
+     428             :                               const  std::vector<double>  & displace,
+     429             :                               const std::vector<Vector> & positions,
+     430             :                               const std::vector<Vector> & reference,
+     431             :                               std::vector<Vector>  & derivatives, bool squared)const {
+     432      549034 :   const unsigned n=reference.size();
+     433             : // This is the trace of positions*positions + reference*reference
+     434             :   double rr00(0);
+     435             :   double rr11(0);
+     436             : // This is positions*reference
+     437      549034 :   Tensor rr01;
+     438             : 
+     439      549034 :   derivatives.resize(n);
+     440             : 
+     441      549034 :   Vector cpositions;
+     442             : 
+     443             : // first expensive loop: compute centers
+     444    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     445    21816039 :     double w=align[iat];
+     446    21816039 :     cpositions+=positions[iat]*w;
+     447             :   }
+     448             : 
+     449             : // second expensive loop: compute second moments wrt centers
+     450    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     451    21816039 :     double w=align[iat];
+     452    21816039 :     rr00+=dotProduct(positions[iat]-cpositions,positions[iat]-cpositions)*w;
+     453    21813863 :     rr11+=dotProduct(reference[iat],reference[iat])*w;
+     454    21816039 :     rr01+=Tensor(positions[iat]-cpositions,reference[iat])*w;
+     455             :   }
+     456             : 
+     457      549034 :   Tensor4d m;
+     458             : 
+     459      549034 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     460      549034 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     461      549034 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     462      549034 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     463      549034 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+     464      549034 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+     465      549034 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+     466      549034 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+     467      549034 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+     468      549034 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+     469      549034 :   m[1][0] = m[0][1];
+     470      549034 :   m[2][0] = m[0][2];
+     471      549034 :   m[2][1] = m[1][2];
+     472      549034 :   m[3][0] = m[0][3];
+     473      549034 :   m[3][1] = m[1][3];
+     474      549034 :   m[3][2] = m[2][3];
+     475             : 
+     476    11529714 :   Tensor dm_drr01[4][4];
+     477             :   if(!alEqDis) {
+     478         114 :     dm_drr01[0][0] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,-1.0);
+     479         114 :     dm_drr01[1][1] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,+1.0);
+     480         114 :     dm_drr01[2][2] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,+1.0);
+     481         114 :     dm_drr01[3][3] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,-1.0);
+     482         114 :     dm_drr01[0][1] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,+1.0, 0.0);
+     483         114 :     dm_drr01[0][2] = 2.0*Tensor( 0.0, 0.0,+1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+     484         114 :     dm_drr01[0][3] = 2.0*Tensor( 0.0,-1.0, 0.0, +1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+     485         114 :     dm_drr01[1][2] = 2.0*Tensor( 0.0,-1.0, 0.0, -1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+     486         114 :     dm_drr01[1][3] = 2.0*Tensor( 0.0, 0.0,-1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+     487         114 :     dm_drr01[2][3] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,-1.0, 0.0);
+     488         114 :     dm_drr01[1][0] = dm_drr01[0][1];
+     489         114 :     dm_drr01[2][0] = dm_drr01[0][2];
+     490         114 :     dm_drr01[2][1] = dm_drr01[1][2];
+     491         114 :     dm_drr01[3][0] = dm_drr01[0][3];
+     492         114 :     dm_drr01[3][1] = dm_drr01[1][3];
+     493         114 :     dm_drr01[3][2] = dm_drr01[2][3];
+     494             :   }
+     495             : 
+     496             :   double dist=0.0;
+     497      549034 :   Vector4d q;
+     498             : 
+     499     2745170 :   Tensor dq_drr01[4];
+     500             :   if(!alEqDis) {
+     501         114 :     Vector4d eigenvals;
+     502         114 :     Tensor4d eigenvecs;
+     503         114 :     diagMatSym(m, eigenvals, eigenvecs );
+     504             :     dist=eigenvals[0]+rr00+rr11;
+     505         114 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+     506             :     double dq_dm[4][4][4];
+     507        9690 :     for(unsigned i=0; i<4; i++) for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+     508             :           double tmp=0.0;
+     509             : // perturbation theory for matrix m
+     510       29184 :           for(unsigned l=1; l<4; l++) tmp+=eigenvecs[l][j]*eigenvecs[l][i]/(eigenvals[0]-eigenvals[l])*eigenvecs[0][k];
+     511        7296 :           dq_dm[i][j][k]=tmp;
+     512             :         }
+     513             : // propagation to _drr01
+     514         570 :     for(unsigned i=0; i<4; i++) {
+     515         456 :       Tensor tmp;
+     516        9576 :       for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+     517        7296 :           tmp+=dq_dm[i][j][k]*dm_drr01[j][k];
+     518             :         }
+     519         456 :       dq_drr01[i]=tmp;
+     520             :     }
+     521             :   } else {
+     522      548920 :     VectorGeneric<1> eigenvals;
+     523      548920 :     TensorGeneric<1,4> eigenvecs;
+     524      548920 :     diagMatSym(m, eigenvals, eigenvecs );
+     525      548920 :     dist=eigenvals[0]+rr00+rr11;
+     526      548920 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+     527             :   }
+     528             : 
+     529             : 
+     530             : // This is the rotation matrix that brings reference to positions
+     531             : // i.e. matmul(rotation,reference[iat])+shift is fitted to positions[iat]
+     532             : 
+     533      549034 :   Tensor rotation;
+     534      549034 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+     535      549034 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+     536      549034 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+     537      549034 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+     538      549034 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+     539      549034 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+     540      549034 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+     541      549034 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+     542      549034 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+     543             : 
+     544             : 
+     545      549034 :   std::array<std::array<Tensor,3>,3> drotation_drr01;
+     546             :   if(!alEqDis) {
+     547         114 :     drotation_drr01[0][0]=2*q[0]*dq_drr01[0]+2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+     548         114 :     drotation_drr01[1][1]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]+2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+     549         114 :     drotation_drr01[2][2]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]+2*q[3]*dq_drr01[3];
+     550         114 :     drotation_drr01[0][1]=2*(+(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+     551         114 :     drotation_drr01[0][2]=2*(-(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+     552         114 :     drotation_drr01[1][2]=2*(+(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+     553         114 :     drotation_drr01[1][0]=2*(-(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+     554         114 :     drotation_drr01[2][0]=2*(+(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+     555         114 :     drotation_drr01[2][1]=2*(-(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+     556             :   }
+     557             : 
+     558             :   double prefactor=2.0;
+     559             : 
+     560      548920 :   if(!squared && alEqDis) prefactor*=0.5/std::sqrt(dist);
+     561             : 
+     562             : // if "safe", recompute dist here to a better accuracy
+     563             :   if(safe || !alEqDis) dist=0.0;
+     564             : 
+     565             : // If safe is set to "false", MSD is taken from the eigenvalue of the M matrix
+     566             : // If safe is set to "true", MSD is recomputed from the rotational matrix
+     567             : // For some reason, this last approach leads to less numerical noise but adds an overhead
+     568             : 
+     569      549034 :   Tensor ddist_drotation;
+     570      549034 :   Vector ddist_dcpositions;
+     571             : 
+     572             : // third expensive loop: derivatives
+     573    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     574    21816039 :     Vector d(positions[iat]-cpositions - matmul(rotation,reference[iat]));
+     575             :     if(alEqDis) {
+     576             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+     577             : // (similar to Hellman-Feynman forces)
+     578    21813863 :       derivatives[iat]= prefactor*align[iat]*d;
+     579     4952157 :       if(safe) dist+=align[iat]*modulo2(d);
+     580             :     } else {
+     581             : // the case for align != displace is different, sob:
+     582        2176 :       dist+=displace[iat]*modulo2(d);
+     583             : // these are the derivatives assuming the roto-translation as frozen
+     584        2176 :       derivatives[iat]=2*displace[iat]*d;
+     585             : // here I accumulate derivatives wrt rotation matrix ..
+     586        2176 :       ddist_drotation+=-2*displace[iat]*extProduct(d,reference[iat]);
+     587             : // .. and cpositions
+     588        2176 :       ddist_dcpositions+=-2*displace[iat]*d;
+     589             :     }
+     590             :   }
+     591             : 
+     592             :   if(!alEqDis) {
+     593         114 :     Tensor ddist_drr01;
+     594        1482 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) ddist_drr01+=ddist_drotation[i][j]*drotation_drr01[i][j];
+     595        2290 :     for(unsigned iat=0; iat<n; iat++) {
+     596             : // this is propagating to positions.
+     597             : // I am implicitly using the derivative of rr01 wrt positions here
+     598        2176 :       derivatives[iat]+=matmul(ddist_drr01,reference[iat])*align[iat];
+     599        2176 :       derivatives[iat]+=ddist_dcpositions*align[iat];
+     600             :     }
+     601             :   }
+     602      549034 :   if(!squared) {
+     603       74171 :     dist=std::sqrt(dist);
+     604             :     if(!alEqDis) {
+     605         114 :       double xx=0.5/dist;
+     606        2290 :       for(unsigned iat=0; iat<n; iat++) derivatives[iat]*=xx;
+     607             :     }
+     608             :   }
+     609             : 
+     610      549034 :   return dist;
+     611             : }
+     612             : #else
+     613             : /// note that this method is intended to be repeatedly invoked
+     614             : /// when the reference does already have the center subtracted
+     615             : /// but the position has not calculated center and not subtracted
+     616             : template <bool safe,bool alEqDis>
+     617             : double RMSD::optimalAlignment(const  std::vector<double>  & align,
+     618             :                               const  std::vector<double>  & displace,
+     619             :                               const std::vector<Vector> & positions,
+     620             :                               const std::vector<Vector> & reference,
+     621             :                               std::vector<Vector>  & derivatives,
+     622             :                               bool squared) const {
+     623             :   //std::cerr<<"setting up the core data \n";
+     624             :   RMSDCoreData cd(align,displace,positions,reference);
+     625             : 
+     626             :   // transfer the settings for the center to let the CoreCalc deal with it
+     627             :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     628             :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     629             :   else {cd.calcPositionsCenter();};
+     630             : 
+     631             :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     632             :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     633             :   else {cd.setReferenceCenter(reference_center);}
+     634             : 
+     635             :   // Perform the diagonalization and all the needed stuff
+     636             :   cd.doCoreCalc(safe,alEqDis);
+     637             :   // make the core calc distance
+     638             :   double dist=cd.getDistance(squared);
+     639             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     640             :   derivatives=cd.getDDistanceDPositions();
+     641             :   return dist;
+     642             : }
+     643             : #endif
+     644             : template <bool safe,bool alEqDis>
+     645           1 : double RMSD::optimalAlignment_DDistDRef(const  std::vector<double>  & align,
+     646             :                                         const  std::vector<double>  & displace,
+     647             :                                         const std::vector<Vector> & positions,
+     648             :                                         const std::vector<Vector> & reference,
+     649             :                                         std::vector<Vector>  & derivatives,
+     650             :                                         std::vector<Vector> & ddistdref,
+     651             :                                         bool squared) const {
+     652             :   //initialize the data into the structure
+     653             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     654           1 :   RMSDCoreData cd(align,displace,positions,reference);
+     655             :   // transfer the settings for the center to let the CoreCalc deal with it
+     656             :   // transfer the settings for the center to let the CoreCalc deal with it
+     657           1 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     658           1 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     659           1 :   else {cd.calcPositionsCenter();};
+     660             : 
+     661           1 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     662           1 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     663           1 :   else {cd.setReferenceCenter(reference_center);}
+     664             : 
+     665             :   // Perform the diagonalization and all the needed stuff
+     666           1 :   cd.doCoreCalc(safe,alEqDis);
+     667             :   // make the core calc distance
+     668           1 :   double dist=cd.getDistance(squared);
+     669             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     670           1 :   derivatives=cd.getDDistanceDPositions();
+     671           2 :   ddistdref=cd.getDDistanceDReference();
+     672           1 :   return dist;
+     673             : }
+     674             : 
+     675             : template <bool safe,bool alEqDis>
+     676           0 : double RMSD::optimalAlignment_SOMA(const  std::vector<double>  & align,
+     677             :                                    const  std::vector<double>  & displace,
+     678             :                                    const std::vector<Vector> & positions,
+     679             :                                    const std::vector<Vector> & reference,
+     680             :                                    std::vector<Vector>  & derivatives,
+     681             :                                    std::vector<Vector> & ddistdref,
+     682             :                                    bool squared) const {
+     683             :   //initialize the data into the structure
+     684             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     685           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     686             :   // transfer the settings for the center to let the CoreCalc deal with it
+     687             :   // transfer the settings for the center to let the CoreCalc deal with it
+     688           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     689           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     690           0 :   else {cd.calcPositionsCenter();};
+     691             : 
+     692           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     693           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     694           0 :   else {cd.setReferenceCenter(reference_center);}
+     695             : 
+     696             :   // Perform the diagonalization and all the needed stuff
+     697           0 :   cd.doCoreCalc(safe,alEqDis);
+     698             :   // make the core calc distance
+     699           0 :   double dist=cd.getDistance(squared);
+     700             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     701           0 :   derivatives=cd.getDDistanceDPositions();
+     702           0 :   ddistdref=cd.getDDistanceDReferenceSOMA();
+     703           0 :   return dist;
+     704             : }
+     705             : 
+     706             : 
+     707             : template <bool safe,bool alEqDis>
+     708           0 : double RMSD::optimalAlignment_DDistDRef_Rot_DRotDPos(const  std::vector<double>  & align,
+     709             :     const  std::vector<double>  & displace,
+     710             :     const std::vector<Vector> & positions,
+     711             :     const std::vector<Vector> & reference,
+     712             :     std::vector<Vector>  & derivatives,
+     713             :     std::vector<Vector> & ddistdref,
+     714             :     Tensor & Rotation,
+     715             :     Matrix<std::vector<Vector> > &DRotDPos,
+     716             :     bool squared) const {
+     717             :   //initialize the data into the structure
+     718             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     719           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     720             :   // transfer the settings for the center to let the CoreCalc deal with it
+     721             :   // transfer the settings for the center to let the CoreCalc deal with it
+     722           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     723           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     724           0 :   else {cd.calcPositionsCenter();};
+     725             : 
+     726           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     727           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     728           0 :   else {cd.setReferenceCenter(reference_center);}
+     729             : 
+     730             :   // Perform the diagonalization and all the needed stuff
+     731           0 :   cd.doCoreCalc(safe,alEqDis);
+     732             :   // make the core calc distance
+     733           0 :   double dist=cd.getDistance(squared);
+     734             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     735           0 :   derivatives=cd.getDDistanceDPositions();
+     736           0 :   ddistdref=cd.getDDistanceDReference();
+     737             :   // get the rotation matrix
+     738           0 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     739             :   // get its derivative
+     740           0 :   DRotDPos=cd.getDRotationDPositions();
+     741           0 :   return dist;
+     742             : }
+     743             : 
+     744             : template <bool safe,bool alEqDis>
+     745           0 : double RMSD::optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef(const  std::vector<double>  & align,
+     746             :     const  std::vector<double>  & displace,
+     747             :     const std::vector<Vector> & positions,
+     748             :     const std::vector<Vector> & reference,
+     749             :     std::vector<Vector>  & derivatives,
+     750             :     std::vector<Vector> & ddistdref,
+     751             :     Tensor & Rotation,
+     752             :     Matrix<std::vector<Vector> > &DRotDPos,
+     753             :     Matrix<std::vector<Vector> > &DRotDRef,
+     754             :     bool squared) const {
+     755             :   //initialize the data into the structure
+     756             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     757           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     758             :   // transfer the settings for the center to let the CoreCalc deal with it
+     759             :   // transfer the settings for the center to let the CoreCalc deal with it
+     760           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     761           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     762           0 :   else {cd.calcPositionsCenter();};
+     763             : 
+     764           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     765           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     766           0 :   else {cd.setReferenceCenter(reference_center);}
+     767             : 
+     768             :   // Perform the diagonalization and all the needed stuff
+     769           0 :   cd.doCoreCalc(safe,alEqDis);
+     770             :   // make the core calc distance
+     771           0 :   double dist=cd.getDistance(squared);
+     772             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     773           0 :   derivatives=cd.getDDistanceDPositions();
+     774           0 :   ddistdref=cd.getDDistanceDReference();
+     775             :   // get the rotation matrix
+     776           0 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     777             :   // get its derivative
+     778           0 :   DRotDPos=cd.getDRotationDPositions();
+     779           0 :   DRotDRef=cd.getDRotationDReference();
+     780           0 :   return dist;
+     781             : }
+     782             : 
+     783             : template <bool safe,bool alEqDis>
+     784        1092 : double RMSD::optimalAlignment_Rot_DRotDRr01(const  std::vector<double>  & align,
+     785             :     const  std::vector<double>  & displace,
+     786             :     const std::vector<Vector> & positions,
+     787             :     const std::vector<Vector> & reference,
+     788             :     Tensor & Rotation,
+     789             :     std::array<std::array<Tensor,3>,3> & DRotDRr01,
+     790             :     bool squared) const {
+     791             :   //initialize the data into the structure
+     792             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     793        1092 :   RMSDCoreData cd(align,displace,positions,reference);
+     794             :   // transfer the settings for the center to let the CoreCalc deal with it
+     795        1092 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     796        1092 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     797        1092 :   else {cd.calcPositionsCenter();};
+     798             : 
+     799        1092 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     800        1092 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     801        1092 :   else {cd.setReferenceCenter(reference_center);}
+     802             : 
+     803             :   // Perform the diagonalization and all the needed stuff
+     804        1092 :   cd.doCoreCalc(safe,alEqDis);
+     805             :   // make the core calc distance
+     806        1092 :   double dist=cd.getDistance(squared);
+     807             :   // get the rotation matrix
+     808        1092 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     809             :   //get detivative w.r.t. rr01
+     810        1092 :   DRotDRr01=cd.getDRotationDRr01();
+     811        1092 :   return dist;
+     812             : }
+     813             : 
+     814             : template <bool safe,bool alEqDis>
+     815         672 : double RMSD::optimalAlignment_Rot(const  std::vector<double>  & align,
+     816             :                                   const  std::vector<double>  & displace,
+     817             :                                   const std::vector<Vector> & positions,
+     818             :                                   const std::vector<Vector> & reference,
+     819             :                                   std::vector<Vector>  & derivatives,
+     820             :                                   Tensor & Rotation,
+     821             :                                   bool squared) const {
+     822             :   //initialize the data into the structure
+     823             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     824         672 :   RMSDCoreData cd(align,displace,positions,reference);
+     825             :   // transfer the settings for the center to let the CoreCalc deal with it
+     826         672 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     827         672 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     828         672 :   else {cd.calcPositionsCenter();};
+     829             : 
+     830         672 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     831         672 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     832         672 :   else {cd.setReferenceCenter(reference_center);}
+     833             : 
+     834             :   // Perform the diagonalization and all the needed stuff
+     835         672 :   cd.doCoreCalc(safe,alEqDis);
+     836             :   // make the core calc distance
+     837         672 :   double dist=cd.getDistance(squared);
+     838             :   //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     839         672 :   derivatives=cd.getDDistanceDPositions();
+     840             :   // get the rotation matrix
+     841         672 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     842         672 :   return dist;
+     843             : }
+     844             : 
+     845             : template <bool safe,bool alEqDis>
+     846       45192 : double RMSD::optimalAlignmentWithCloseStructure(const  std::vector<double>  & align,
+     847             :     const  std::vector<double>  & displace,
+     848             :     const std::vector<Vector> & positions,
+     849             :     const std::vector<Vector> & reference,
+     850             :     std::vector<Vector>  & derivatives,
+     851             :     const Tensor & rotationPosClose,
+     852             :     const Tensor & rotationRefClose,
+     853             :     std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01,
+     854             :     bool squared) const {
+     855             :   //initialize the data into the structure
+     856             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     857       45192 :   RMSDCoreData cd(align,displace,positions,reference);
+     858             :   // transfer the settings for the center to let the CoreCalc deal with it
+     859       45192 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     860       45192 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     861       45192 :   else {cd.calcPositionsCenter();};
+     862             : 
+     863       45192 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     864       45192 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     865       45192 :   else {cd.setReferenceCenter(reference_center);}
+     866             : 
+     867             :   // instead of diagonalization, approximate with saved rotation matrix
+     868       45192 :   cd.doCoreCalcWithCloseStructure(safe,alEqDis, rotationPosClose, rotationRefClose, drotationPosCloseDrr01);
+     869             :   // make the core calc distance
+     870       45192 :   double dist=cd.getDistance(squared);
+     871             :   //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     872       90384 :   derivatives=cd.getDDistanceDPositions();
+     873       45192 :   return dist;
+     874             : }
+     875             : 
+     876             : 
+     877             : template <bool safe,bool alEqDis>
+     878        4985 : double RMSD::optimalAlignment_PCA(const  std::vector<double>  & align,
+     879             :                                   const  std::vector<double>  & displace,
+     880             :                                   const std::vector<Vector> & positions,
+     881             :                                   const std::vector<Vector> & reference,
+     882             :                                   std::vector<Vector> & alignedpositions,
+     883             :                                   std::vector<Vector> & centeredpositions,
+     884             :                                   std::vector<Vector> & centeredreference,
+     885             :                                   Tensor & Rotation,
+     886             :                                   std::vector<Vector> & DDistDPos,
+     887             :                                   Matrix<std::vector<Vector> > & DRotDPos,
+     888             :                                   bool squared) const {
+     889             :   //initialize the data into the structure
+     890             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     891        4985 :   RMSDCoreData cd(align,displace,positions,reference);
+     892             :   // transfer the settings for the center to let the CoreCalc deal with it
+     893        4985 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     894        4985 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     895        4985 :   else {cd.calcPositionsCenter();};
+     896             : 
+     897        4985 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     898        4985 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     899        4985 :   else {cd.setReferenceCenter(reference_center);}
+     900             : 
+     901             :   // Perform the diagonalization and all the needed stuff
+     902        4985 :   cd.doCoreCalc(safe,alEqDis);
+     903             :   // make the core calc distance
+     904        4985 :   double dist=cd.getDistance(squared);
+     905             :   // make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     906        4985 :   DDistDPos=cd.getDDistanceDPositions();
+     907             :   // get the rotation matrix
+     908        4985 :   Rotation=cd.getRotationMatrixPositionsToReference();
+     909             :   // get its derivative
+     910        4985 :   DRotDPos=cd.getDRotationDPositions(true); // this gives back the inverse
+     911             :   // get aligned positions
+     912        4985 :   alignedpositions=cd.getAlignedPositionsToReference();
+     913             :   // get centered positions
+     914        4985 :   centeredpositions=cd.getCenteredPositions();
+     915             :   // get centered reference
+     916        9970 :   centeredreference=cd.getCenteredReference();
+     917        4985 :   return dist;
+     918             : }
+     919             : 
+     920             : 
+     921             : template <bool safe,bool alEqDis>
+     922         210 : double RMSD::optimalAlignment_Fit(const  std::vector<double>  & align,
+     923             :                                   const  std::vector<double>  & displace,
+     924             :                                   const std::vector<Vector> & positions,
+     925             :                                   const std::vector<Vector> & reference,
+     926             :                                   Tensor & Rotation,
+     927             :                                   Matrix<std::vector<Vector> > & DRotDPos,
+     928             :                                   std::vector<Vector> & centeredpositions,
+     929             :                                   Vector & center_positions,
+     930             :                                   bool squared) {
+     931             :   //initialize the data into the structure
+     932             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     933         210 :   RMSDCoreData cd(align,displace,positions,reference);
+     934             :   // transfer the settings for the center to let the CoreCalc deal with it
+     935         210 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     936         210 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     937         210 :   else {cd.calcPositionsCenter();};
+     938             : 
+     939         210 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     940         210 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     941         210 :   else {cd.setReferenceCenter(reference_center);}
+     942             : 
+     943             :   // Perform the diagonalization and all the needed stuff
+     944         210 :   cd.doCoreCalc(safe,alEqDis);
+     945             :   // make the core calc distance
+     946         210 :   double dist=cd.getDistance(squared);
+     947             :   // get the rotation matrix
+     948         210 :   Rotation=cd.getRotationMatrixPositionsToReference();
+     949             :   // get its derivative
+     950         210 :   DRotDPos=cd.getDRotationDPositions(true); // this gives back the inverse
+     951             :   // get centered positions
+     952         210 :   centeredpositions=cd.getCenteredPositions();
+     953             :   // get center
+     954         210 :   center_positions=cd.getPositionsCenter();
+     955         210 :   return dist;
+     956             : }
+     957             : 
+     958             : 
+     959             : 
+     960             : 
+     961             : 
+     962             : 
+     963             : /// This calculates the elements needed by the quaternion to calculate everything that is needed
+     964             : /// additional calls retrieve different components
+     965             : /// note that this considers that the centers of both reference and positions are already setted
+     966             : /// but automatically should properly account for non removed components: if not removed then it
+     967             : /// removes prior to calculation of the alignment
+     968        6960 : void RMSDCoreData::doCoreCalc(bool safe,bool alEqDis, bool only_rotation) {
+     969             : 
+     970        6960 :   retrieve_only_rotation=only_rotation;
+     971        6960 :   const unsigned n=static_cast<unsigned int>(reference.size());
+     972             : 
+     973        6960 :   plumed_massert(creference_is_calculated,"the center of the reference frame must be already provided at this stage");
+     974        6960 :   plumed_massert(cpositions_is_calculated,"the center of the positions frame must be already provided at this stage");
+     975             : 
+     976             : // This is the trace of positions*positions + reference*reference
+     977        6960 :   rr00=0.;
+     978        6960 :   rr11=0.;
+     979             : // This is positions*reference
+     980        6960 :   Tensor rr01;
+     981             : // center of mass managing: must subtract the center from the position or not?
+     982        6960 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+     983        6960 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+     984             : // second expensive loop: compute second moments wrt centers
+     985      588912 :   for(unsigned iat=0; iat<n; iat++) {
+     986      581952 :     double w=align[iat];
+     987      581952 :     rr00+=dotProduct(positions[iat]-cp,positions[iat]-cp)*w;
+     988      581952 :     rr11+=dotProduct(reference[iat]-cr,reference[iat]-cr)*w;
+     989      581952 :     rr01+=Tensor(positions[iat]-cp,reference[iat]-cr)*w;
+     990             :   }
+     991             : 
+     992             : // the quaternion matrix: this is internal
+     993        6960 :   Tensor4d m;
+     994             : 
+     995        6960 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     996        6960 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     997        6960 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     998        6960 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     999        6960 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+    1000        6960 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+    1001        6960 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+    1002        6960 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+    1003        6960 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+    1004        6960 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+    1005        6960 :   m[1][0] = m[0][1];
+    1006        6960 :   m[2][0] = m[0][2];
+    1007        6960 :   m[2][1] = m[1][2];
+    1008        6960 :   m[3][0] = m[0][3];
+    1009        6960 :   m[3][1] = m[1][3];
+    1010        6960 :   m[3][2] = m[2][3];
+    1011             : 
+    1012             : 
+    1013      146160 :   Tensor dm_drr01[4][4];
+    1014        6960 :   if(!alEqDis or !retrieve_only_rotation) {
+    1015        6960 :     dm_drr01[0][0] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,-1.0);
+    1016        6960 :     dm_drr01[1][1] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,+1.0);
+    1017        6960 :     dm_drr01[2][2] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,+1.0);
+    1018        6960 :     dm_drr01[3][3] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,-1.0);
+    1019        6960 :     dm_drr01[0][1] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,+1.0, 0.0);
+    1020        6960 :     dm_drr01[0][2] = 2.0*Tensor( 0.0, 0.0,+1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+    1021        6960 :     dm_drr01[0][3] = 2.0*Tensor( 0.0,-1.0, 0.0, +1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+    1022        6960 :     dm_drr01[1][2] = 2.0*Tensor( 0.0,-1.0, 0.0, -1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+    1023        6960 :     dm_drr01[1][3] = 2.0*Tensor( 0.0, 0.0,-1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+    1024        6960 :     dm_drr01[2][3] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,-1.0, 0.0);
+    1025        6960 :     dm_drr01[1][0] = dm_drr01[0][1];
+    1026        6960 :     dm_drr01[2][0] = dm_drr01[0][2];
+    1027        6960 :     dm_drr01[2][1] = dm_drr01[1][2];
+    1028        6960 :     dm_drr01[3][0] = dm_drr01[0][3];
+    1029        6960 :     dm_drr01[3][1] = dm_drr01[1][3];
+    1030        6960 :     dm_drr01[3][2] = dm_drr01[2][3];
+    1031             :   }
+    1032             : 
+    1033             : 
+    1034        6960 :   Vector4d q;
+    1035             : 
+    1036       34800 :   Tensor dq_drr01[4];
+    1037        6960 :   if(!alEqDis or !only_rotation) {
+    1038        6960 :     diagMatSym(m, eigenvals, eigenvecs );
+    1039        6960 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+    1040             :     double dq_dm[4][4][4];
+    1041      591600 :     for(unsigned i=0; i<4; i++) for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+    1042             :           double tmp=0.0;
+    1043             : // perturbation theory for matrix m
+    1044     1781760 :           for(unsigned l=1; l<4; l++) tmp+=eigenvecs[l][j]*eigenvecs[l][i]/(eigenvals[0]-eigenvals[l])*eigenvecs[0][k];
+    1045      445440 :           dq_dm[i][j][k]=tmp;
+    1046             :         }
+    1047             : // propagation to _drr01
+    1048       34800 :     for(unsigned i=0; i<4; i++) {
+    1049       27840 :       Tensor tmp;
+    1050      584640 :       for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+    1051      445440 :           tmp+=dq_dm[i][j][k]*dm_drr01[j][k];
+    1052             :         }
+    1053       27840 :       dq_drr01[i]=tmp;
+    1054             :     }
+    1055             :   } else {
+    1056           0 :     TensorGeneric<1,4> here_eigenvecs;
+    1057           0 :     VectorGeneric<1> here_eigenvals;
+    1058           0 :     diagMatSym(m, here_eigenvals, here_eigenvecs );
+    1059           0 :     for(unsigned i=0; i<4; i++) eigenvecs[0][i]=here_eigenvecs[0][i];
+    1060           0 :     eigenvals[0]=here_eigenvals[0];
+    1061           0 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+    1062             :   }
+    1063             : 
+    1064             : // This is the rotation matrix that brings reference to positions
+    1065             : // i.e. matmul(rotation,reference[iat])+shift is fitted to positions[iat]
+    1066             : 
+    1067        6960 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+    1068        6960 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+    1069        6960 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+    1070        6960 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+    1071        6960 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+    1072        6960 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+    1073        6960 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+    1074        6960 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+    1075        6960 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+    1076             : 
+    1077             : 
+    1078        6960 :   if(!alEqDis or !only_rotation) {
+    1079        6960 :     drotation_drr01[0][0]=2*q[0]*dq_drr01[0]+2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+    1080        6960 :     drotation_drr01[1][1]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]+2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+    1081        6960 :     drotation_drr01[2][2]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]+2*q[3]*dq_drr01[3];
+    1082        6960 :     drotation_drr01[0][1]=2*(+(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+    1083        6960 :     drotation_drr01[0][2]=2*(-(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+    1084        6960 :     drotation_drr01[1][2]=2*(+(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+    1085        6960 :     drotation_drr01[1][0]=2*(-(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+    1086        6960 :     drotation_drr01[2][0]=2*(+(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+    1087        6960 :     drotation_drr01[2][1]=2*(-(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+    1088             :   }
+    1089             : 
+    1090        6960 :   d.resize(n);
+    1091             : 
+    1092             :   // calculate rotation matrix derivatives and components distances needed for components only when align!=displacement
+    1093        6960 :   if(!alEqDis)ddist_drotation.zero();
+    1094             :   // This pragma leads to incorrect results with INTEL compiler.
+    1095             :   // Failures are seen in rt65-rmsd2, rt-close-structure, rt64-pca, and others.
+    1096             :   // Not really clear why. GB
+    1097             :   // #pragma omp simd
+    1098      588912 :   for(unsigned iat=0; iat<n; iat++) {
+    1099             :     // components differences: this is useful externally
+    1100      581952 :     d[iat]=positions[iat]-cp - matmul(rotation,reference[iat]-cr);
+    1101             :     //cerr<<"D "<<iat<<" "<<d[iat][0]<<" "<<d[iat][1]<<" "<<d[iat][2]<<"\n";
+    1102             :   }
+    1103             :   // ddist_drotation if needed
+    1104        6960 :   if(!alEqDis or !only_rotation) {
+    1105      588912 :     for (unsigned iat=0; iat<n; iat++)
+    1106      581952 :       ddist_drotation+=-2*displace[iat]*extProduct(d[iat],reference[iat]-cr);
+    1107             : 
+    1108        6960 :     ddist_drr01.zero();
+    1109       90480 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) ddist_drr01+=ddist_drotation[i][j]*drotation_drr01[i][j];
+    1110             :   }
+    1111             :   // transfer this bools to the cd so that this settings will be reflected in the other calls
+    1112        6960 :   this->alEqDis=alEqDis;
+    1113        6960 :   this->safe=safe;
+    1114        6960 :   isInitialized=true;
+    1115             : 
+    1116        6960 : }
+    1117             : /// just retrieve the distance already calculated
+    1118       52152 : double RMSDCoreData::getDistance( bool squared) {
+    1119             : 
+    1120       52152 :   if(!isInitialized)plumed_merror("getDistance cannot calculate the distance without being initialized first by doCoreCalc ");
+    1121             : 
+    1122             :   double localDist=0.0;
+    1123       52152 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1124       52152 :   if(safe || !alEqDis) localDist=0.0;
+    1125             :   else
+    1126           0 :     localDist=eigenvals[0]+rr00+rr11;
+    1127      104304 :   #pragma omp simd reduction(+:localDist)
+    1128             :   for(unsigned iat=0; iat<n; iat++) {
+    1129     1169448 :     if(alEqDis) {
+    1130     1168293 :       if(safe) localDist+=align[iat]*modulo2(d[iat]);
+    1131             :     } else {
+    1132        1155 :       localDist+=displace[iat]*modulo2(d[iat]);
+    1133             :     }
+    1134             :   }
+    1135       52152 :   if(!squared) {
+    1136          85 :     dist=std::sqrt(localDist);
+    1137          85 :     distanceIsMSD=false;
+    1138             :   } else {
+    1139       52067 :     dist=localDist;
+    1140       52067 :     distanceIsMSD=true;
+    1141             :   }
+    1142       52152 :   hasDistance=true;
+    1143       52152 :   return dist;
+    1144             : }
+    1145             : 
+    1146       45192 : void RMSDCoreData::doCoreCalcWithCloseStructure(bool safe,bool alEqDis, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01) {
+    1147             : 
+    1148       45192 :   unsigned natoms = reference.size();
+    1149       45192 :   Tensor ddist_drxy;
+    1150       45192 :   ddist_drr01.zero();
+    1151       45192 :   d.resize(natoms);
+    1152             : 
+    1153             :   // center of mass managing: must subtract the center from the position or not?
+    1154       45192 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1155       45192 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1156             :   //distance = \sum_{n=0}^{N} w_n(x_n-cpos-R_{XY} R_{AY} a_n)^2
+    1157             : 
+    1158       45192 :   Tensor rotation = matmul(rotationPosClose, rotationRefClose);
+    1159             : 
+    1160             :   // This pragma leads to incorrect results with INTEL compiler.
+    1161             :   // Failures are seen in rt65-rmsd2, rt-close-structure, rt64-pca, and others.
+    1162             :   // Not really clear why. GB
+    1163             :   // #pragma omp simd
+    1164      632688 :   for (unsigned iat=0; iat<natoms; iat++) {
+    1165      587496 :     d[iat] = positions[iat] - cp - matmul(rotation, reference[iat]-cr);
+    1166             :   }
+    1167       45192 :   if (!alEqDis) {
+    1168           0 :     for (unsigned iat=0; iat<natoms; iat++) {
+    1169             :       //dist = \sum w_i(x_i - cpos - R_xy * R_ay * a_i)
+    1170           0 :       ddist_drxy += -2*displace[iat]*extProduct(matmul(d[iat], rotationRefClose), reference[iat]-cr);
+    1171             :     }
+    1172           0 :     for(unsigned i=0; i<3; i++)
+    1173           0 :       for(unsigned j=0; j<3; j++)
+    1174           0 :         ddist_drr01+=ddist_drxy[i][j]*drotationPosCloseDrr01[i][j];
+    1175             :   }
+    1176       45192 :   this->alEqDis=alEqDis;
+    1177       45192 :   this->safe=safe;
+    1178       45192 :   isInitialized=true;
+    1179       45192 : }
+    1180             : 
+    1181       50850 : std::vector<Vector> RMSDCoreData::getDDistanceDPositions() {
+    1182             :   std::vector<Vector>  derivatives;
+    1183       50850 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1184       50850 :   Vector ddist_dcpositions;
+    1185       50850 :   derivatives.resize(n);
+    1186             :   double prefactor=1.0;
+    1187       50850 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1188       50850 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1189       50850 :   if(!hasDistance)plumed_merror("getDPositionsDerivatives needs to calculate the distance via getDistance first !");
+    1190       50850 :   if(!isInitialized)plumed_merror("getDPositionsDerivatives needs to initialize the coreData first!");
+    1191       50850 :   Vector csum;
+    1192      720102 :   for(unsigned iat=0; iat<n; iat++) {
+    1193      669252 :     if(alEqDis) {
+    1194             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1195             : // (similar to Hellman-Feynman forces)
+    1196      668397 :       derivatives[iat]= 2*prefactor*align[iat]*d[iat];
+    1197             :     } else {
+    1198             : // these are the derivatives assuming the roto-translation as frozen
+    1199         855 :       Vector tmp1=2*displace[iat]*d[iat];
+    1200         855 :       derivatives[iat]=tmp1;
+    1201             : // derivative of cpositions
+    1202         855 :       ddist_dcpositions+=-tmp1;
+    1203             :       // these needed for com corrections
+    1204         855 :       Vector tmp2=matmul(ddist_drr01,reference[iat]-creference)*align[iat];
+    1205         855 :       derivatives[iat]+=tmp2;
+    1206         855 :       csum+=tmp2;
+    1207             :     }
+    1208             :   }
+    1209             : 
+    1210       50850 :   if(!alEqDis)
+    1211             :     #pragma omp simd
+    1212         855 :     for(unsigned iat=0; iat<n; iat++) {derivatives[iat]= prefactor*(derivatives[iat]+(ddist_dcpositions-csum)*align[iat]); }
+    1213             : 
+    1214       50850 :   return derivatives;
+    1215             : }
+    1216             : 
+    1217           1 : std::vector<Vector>  RMSDCoreData::getDDistanceDReference() {
+    1218             :   std::vector<Vector>  derivatives;
+    1219           1 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1220           1 :   Vector ddist_dcreference;
+    1221           1 :   derivatives.resize(n);
+    1222             :   double prefactor=1.0;
+    1223           1 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1224           1 :   Vector csum;
+    1225             : 
+    1226           1 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1227           1 :   if(!hasDistance)plumed_merror("getDDistanceDReference needs to calculate the distance via getDistance first !");
+    1228           1 :   if(!isInitialized)plumed_merror("getDDistanceDReference to initialize the coreData first!");
+    1229             :   // get the transpose rotation
+    1230           1 :   Tensor t_rotation=rotation.transpose();
+    1231           1 :   Tensor t_ddist_drr01=ddist_drr01.transpose();
+    1232             : 
+    1233             : // third expensive loop: derivatives
+    1234         856 :   for(unsigned iat=0; iat<n; iat++) {
+    1235         855 :     if(alEqDis) {
+    1236             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1237             : // (similar to Hellman-Feynman forces)
+    1238             :       //TODO: check this derivative down here
+    1239           0 :       derivatives[iat]= -2*prefactor*align[iat]*matmul(t_rotation,d[iat]);
+    1240             :     } else {
+    1241             : // these are the derivatives assuming the roto-translation as frozen
+    1242         855 :       Vector tmp1=2*displace[iat]*matmul(t_rotation,d[iat]);
+    1243         855 :       derivatives[iat]= -tmp1;
+    1244             : // derivative of cpositions
+    1245         855 :       ddist_dcreference+=tmp1;
+    1246             :       // these below are needed for com correction
+    1247         855 :       Vector tmp2=matmul(t_ddist_drr01,positions[iat]-cpositions)*align[iat];
+    1248         855 :       derivatives[iat]+=tmp2;
+    1249         855 :       csum+=tmp2;
+    1250             :     }
+    1251             :   }
+    1252             : 
+    1253           1 :   if(!alEqDis)
+    1254             :     #pragma omp simd
+    1255         855 :     for(unsigned iat=0; iat<n; iat++) {derivatives[iat]= prefactor*(derivatives[iat]+(ddist_dcreference-csum)*align[iat]);}
+    1256             : 
+    1257           1 :   return derivatives;
+    1258             : }
+    1259             : 
+    1260             : /// this version does not calculate the derivative of rotation matrix as needed for SOMA
+    1261           0 : std::vector<Vector>  RMSDCoreData::getDDistanceDReferenceSOMA() {
+    1262             :   std::vector<Vector>  derivatives;
+    1263           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1264           0 :   Vector ddist_dcreference;
+    1265           0 :   derivatives.resize(n);
+    1266             :   double prefactor=1.0;
+    1267           0 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1268           0 :   Vector csum,tmp1,tmp2;
+    1269             : 
+    1270           0 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1271           0 :   if(!hasDistance)plumed_merror("getDDistanceDReference needs to calculate the distance via getDistance first !");
+    1272           0 :   if(!isInitialized)plumed_merror("getDDistanceDReference to initialize the coreData first!");
+    1273             :   // get the transpose rotation
+    1274           0 :   Tensor t_rotation=rotation.transpose();
+    1275             : 
+    1276             : // third expensive loop: derivatives
+    1277           0 :   for(unsigned iat=0; iat<n; iat++) {
+    1278           0 :     if(alEqDis) {
+    1279             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1280             : // (similar to Hellman-Feynman forces)
+    1281             :       //TODO: check this derivative down here
+    1282           0 :       derivatives[iat]= -2*prefactor*align[iat]*matmul(t_rotation,d[iat]);
+    1283             :     } else {
+    1284             : // these are the derivatives assuming the roto-translation as frozen
+    1285           0 :       tmp1=2*displace[iat]*matmul(t_rotation,d[iat]);
+    1286           0 :       derivatives[iat]= -tmp1;
+    1287             : // derivative of cpositions
+    1288           0 :       ddist_dcreference+=tmp1;
+    1289             :     }
+    1290             :   }
+    1291             : 
+    1292           0 :   if(!alEqDis) for(unsigned iat=0; iat<n; iat++)derivatives[iat]=prefactor*(derivatives[iat]+ddist_dcreference*align[iat]);
+    1293             : 
+    1294           0 :   return derivatives;
+    1295             : }
+    1296             : 
+    1297             : 
+    1298             : 
+    1299             : /*
+    1300             : This below is the derivative of the rotation matrix that aligns the reference onto the positions
+    1301             : respect to positions
+    1302             : note that the this transformation overlap the  reference onto position
+    1303             : if inverseTransform=true then aligns the positions onto reference
+    1304             : */
+    1305        5195 : Matrix<std::vector<Vector> >  RMSDCoreData::getDRotationDPositions( bool inverseTransform ) {
+    1306        5195 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1307        5195 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1308        5195 :   if(!isInitialized)plumed_merror("getDRotationDPosition to initialize the coreData first!");
+    1309             :   Matrix<std::vector<Vector> > DRotDPos=Matrix<std::vector<Vector> >(3,3);
+    1310             :   // remember drotation_drr01 is Tensor drotation_drr01[3][3]
+    1311             :   //           (3x3 rot) (3x3 components of rr01)
+    1312        5195 :   std::vector<Vector> v(n);
+    1313        5195 :   Vector csum;
+    1314             :   // these below could probably be calculated in the main routine
+    1315        5195 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1316        5195 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1317      563360 :   for(unsigned iat=0; iat<n; iat++) csum+=(reference[iat]-cr)*align[iat];
+    1318      563360 :   for(unsigned iat=0; iat<n; iat++) v[iat]=(reference[iat]-cr-csum)*align[iat];
+    1319       20780 :   for(unsigned a=0; a<3; a++) {
+    1320       62340 :     for(unsigned b=0; b<3; b++) {
+    1321       46755 :       if(inverseTransform) {
+    1322       46755 :         DRotDPos[b][a].resize(n);
+    1323     5070240 :         for(unsigned iat=0; iat<n; iat++) {
+    1324     5023485 :           DRotDPos[b][a][iat]=matmul(drotation_drr01[a][b],v[iat]);
+    1325             :         }
+    1326             :       } else {
+    1327           0 :         DRotDPos[a][b].resize(n);
+    1328           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1329           0 :           DRotDPos[a][b][iat]=matmul(drotation_drr01[a][b],v[iat]);
+    1330             :         }
+    1331             :       }
+    1332             :     }
+    1333             :   }
+    1334        5195 :   return DRotDPos;
+    1335             : }
+    1336             : 
+    1337             : /*
+    1338             : This below is the derivative of the rotation matrix that aligns the reference onto the positions
+    1339             : respect to reference
+    1340             : note that the this transformation overlap the  reference onto position
+    1341             : if inverseTransform=true then aligns the positions onto reference
+    1342             : */
+    1343           0 : Matrix<std::vector<Vector> >  RMSDCoreData::getDRotationDReference( bool inverseTransform ) {
+    1344           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1345           0 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1346           0 :   if(!isInitialized)plumed_merror("getDRotationDPositions to initialize the coreData first!");
+    1347             :   Matrix<std::vector<Vector> > DRotDRef=Matrix<std::vector<Vector> >(3,3);
+    1348             :   // remember drotation_drr01 is Tensor drotation_drr01[3][3]
+    1349             :   //           (3x3 rot) (3x3 components of rr01)
+    1350           0 :   std::vector<Vector> v(n);
+    1351           0 :   Vector csum;
+    1352             :   // these below could probably be calculated in the main routine
+    1353           0 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1354           0 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1355           0 :   for(unsigned iat=0; iat<n; iat++) csum+=(positions[iat]-cp)*align[iat];
+    1356           0 :   for(unsigned iat=0; iat<n; iat++) v[iat]=(positions[iat]-cp-csum)*align[iat];
+    1357             : 
+    1358           0 :   for(unsigned a=0; a<3; a++) {
+    1359           0 :     for(unsigned b=0; b<3; b++) {
+    1360           0 :       Tensor t_drotation_drr01=drotation_drr01[a][b].transpose();
+    1361           0 :       if(inverseTransform) {
+    1362           0 :         DRotDRef[b][a].resize(n);
+    1363           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1364           0 :           DRotDRef[b][a][iat]=matmul(t_drotation_drr01,v[iat]);
+    1365             :         }
+    1366             :       } else {
+    1367           0 :         DRotDRef[a][b].resize(n);
+    1368           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1369           0 :           DRotDRef[a][b][iat]=matmul(t_drotation_drr01,v[iat]);
+    1370             :         }
+    1371             :       }
+    1372             :     }
+    1373             :   }
+    1374           0 :   return DRotDRef;
+    1375             : }
+    1376             : 
+    1377             : 
+    1378           0 : std::vector<Vector> RMSDCoreData::getAlignedReferenceToPositions() {
+    1379             :   std::vector<Vector> alignedref;
+    1380           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1381           0 :   alignedref.resize(n);
+    1382           0 :   if(!isInitialized)plumed_merror("getAlignedReferenceToPostions needs to initialize the coreData first!");
+    1383             :   // avoid to calculate matrix element but use the sum of what you have
+    1384           0 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1385           0 :   for(unsigned iat=0; iat<n; iat++)alignedref[iat]=-d[iat]+positions[iat]-cp;
+    1386           0 :   return alignedref;
+    1387             : }
+    1388        4985 : std::vector<Vector> RMSDCoreData::getAlignedPositionsToReference() {
+    1389             :   std::vector<Vector> alignedpos;
+    1390        4985 :   if(!isInitialized)plumed_merror("getAlignedPostionsToReference needs to initialize the coreData first!");
+    1391        4985 :   const unsigned n=static_cast<unsigned int>(positions.size());
+    1392        4985 :   alignedpos.resize(n);
+    1393        4985 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1394             :   // avoid to calculate matrix element but use the sum of what you have
+    1395       77150 :   for(unsigned iat=0; iat<n; iat++)alignedpos[iat]=matmul(rotation.transpose(),positions[iat]-cp);
+    1396        4985 :   return alignedpos;
+    1397             : }
+    1398             : 
+    1399             : 
+    1400        5195 : std::vector<Vector> RMSDCoreData::getCenteredPositions() {
+    1401             :   std::vector<Vector> centeredpos;
+    1402        5195 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1403        5195 :   centeredpos.resize(n);
+    1404        5195 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1405             :   // avoid to calculate matrix element but use the sum of what you have
+    1406      563360 :   for(unsigned iat=0; iat<n; iat++)centeredpos[iat]=positions[iat]-cpositions;
+    1407        5195 :   return centeredpos;
+    1408             : }
+    1409             : 
+    1410        4985 : std::vector<Vector> RMSDCoreData::getCenteredReference() {
+    1411             :   std::vector<Vector> centeredref;
+    1412        4985 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1413        4985 :   centeredref.resize(n);
+    1414        4985 :   if(!isInitialized)plumed_merror("getCenteredReference needs to initialize the coreData first!");
+    1415             :   // avoid to calculate matrix element but use the sum of what you have
+    1416        4985 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1417       77150 :   for(unsigned iat=0; iat<n; iat++)centeredref[iat]=reference[iat]-cr;
+    1418        4985 :   return centeredref;
+    1419             : }
+    1420             : 
+    1421             : 
+    1422         210 : Vector RMSDCoreData::getPositionsCenter() {
+    1423         210 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1424         210 :   return cpositions;
+    1425             : }
+    1426             : 
+    1427           0 : Vector RMSDCoreData::getReferenceCenter() {
+    1428           0 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1429           0 :   return creference;
+    1430             : }
+    1431             : 
+    1432        1764 : Tensor RMSDCoreData::getRotationMatrixReferenceToPositions() {
+    1433        1764 :   if(!isInitialized)plumed_merror("getRotationMatrixReferenceToPositions needs to initialize the coreData first!");
+    1434        1764 :   return rotation;
+    1435             : }
+    1436             : 
+    1437        5195 : Tensor RMSDCoreData::getRotationMatrixPositionsToReference() {
+    1438        5195 :   if(!isInitialized)plumed_merror("getRotationMatrixReferenceToPositions needs to initialize the coreData first!");
+    1439        5195 :   return rotation.transpose();
+    1440             : }
+    1441             : 
+    1442        1092 : const std::array<std::array<Tensor,3>,3> &  RMSDCoreData::getDRotationDRr01() const {
+    1443        1092 :   if(!isInitialized)plumed_merror("getDRotationDRr01 needs to initialize the coreData first!");
+    1444        1092 :   return drotation_drr01;
+    1445             : }
+    1446             : 
+    1447             : 
+    1448             : 
+    1449             : template double RMSD::optimalAlignment<true,true>(const  std::vector<double>  & align,
+    1450             :     const  std::vector<double>  & displace,
+    1451             :     const std::vector<Vector> & positions,
+    1452             :     const std::vector<Vector> & reference,
+    1453             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1454             : template double RMSD::optimalAlignment<true,false>(const  std::vector<double>  & align,
+    1455             :     const  std::vector<double>  & displace,
+    1456             :     const std::vector<Vector> & positions,
+    1457             :     const std::vector<Vector> & reference,
+    1458             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1459             : template double RMSD::optimalAlignment<false,true>(const  std::vector<double>  & align,
+    1460             :     const  std::vector<double>  & displace,
+    1461             :     const std::vector<Vector> & positions,
+    1462             :     const std::vector<Vector> & reference,
+    1463             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1464             : template double RMSD::optimalAlignment<false,false>(const  std::vector<double>  & align,
+    1465             :     const  std::vector<double>  & displace,
+    1466             :     const std::vector<Vector> & positions,
+    1467             :     const std::vector<Vector> & reference,
+    1468             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1469             : 
+    1470             : 
+    1471             : 
+    1472             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func-sort-c.html b/coverage/tools/RMSD.h.func-sort-c.html new file mode 100644 index 0000000000..0ca8312bcd --- /dev/null +++ b/coverage/tools/RMSD.h.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func.html b/coverage/tools/RMSD.h.func.html new file mode 100644 index 0000000000..1f6375ccc3 --- /dev/null +++ b/coverage/tools/RMSD.h.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/RMSD.h.gcov.html b/coverage/tools/RMSD.h.gcov.html new file mode 100644 index 0000000000..21b4df0bd2 --- /dev/null +++ b/coverage/tools/RMSD.h.gcov.html @@ -0,0 +1,450 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func-sort-c.html b/coverage/tools/Random.cpp.func-sort-c.html new file mode 100644 index 0000000000..f0db25aaf8 --- /dev/null +++ b/coverage/tools/Random.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_traitsIcESaIcEEE807031
_ZN4PLMD6Random7setSeedEi807870
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6Random7RandU01Ev1582365
_ZN4PLMD6Random3U01Ev5583335
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func.html b/coverage/tools/Random.cpp.func.html new file mode 100644 index 0000000000..deb96463ad --- /dev/null +++ b/coverage/tools/Random.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random13ReadStateFullERSi0
_ZN4PLMD6Random3U01Ev5583335
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7RandU01Ev1582365
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZN4PLMD6Random7setSeedEi807870
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE807031
_ZNK4PLMD6Random14WriteStateFullERSo1
_ZNK4PLMD6Random8toStringERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.gcov.html b/coverage/tools/Random.cpp.gcov.html new file mode 100644 index 0000000000..0468a4550c --- /dev/null +++ b/coverage/tools/Random.cpp.gcov.html @@ -0,0 +1,245 @@ + + + + + + + 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-05-27 13:05: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      807031 : Random::Random(const std::string & name):
+      39      807031 :   switchGaussian(false),
+      40      807031 :   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      807031 :   name(&name!=&noname?name:"noname")
+      47             : {
+      48      807031 :   iy=0;
+      49    26632023 :   for(unsigned i=0; i<NTAB; i++) iv[i]=0;
+      50      807031 :   setSeed(0);
+      51      807031 : }
+      52             : 
+      53      807870 : void Random::setSeed(int idum_) {
+      54      807870 :   if(idum_>0) idum_=-idum_;
+      55      807870 :   idum=idum_;
+      56      807870 :   incPrec=false;
+      57      807870 : }
+      58             : 
+      59     1582365 : double Random::RandU01 ()
+      60             : {
+      61     1582365 :   if (incPrec)
+      62           1 :     return U01d();
+      63             :   else
+      64     1582364 :     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     5583335 : double Random::U01() {
+      77             :   int j,k;
+      78             :   double temp;
+      79     5583335 :   if (idum <= 0 || !iy) {
+      80        1376 :     if (-idum < 1) idum=1;
+      81         626 :     else idum = -idum;
+      82       56416 :     for (j=NTAB+7; j>=0; j--) {
+      83       55040 :       k=idum/IQ;
+      84       55040 :       idum=IA*(idum-k*IQ)-IR*k;
+      85       55040 :       if (idum < 0) idum += IM;
+      86       55040 :       if (j < NTAB) iv[j] = idum;
+      87             :     }
+      88        1376 :     iy=iv[0];
+      89             :   }
+      90     5583335 :   k=idum/IQ;
+      91     5583335 :   idum=IA*(idum-k*IQ)-IR*k;
+      92     5583335 :   if (idum < 0) idum += IM;
+      93     5583335 :   j=iy/NDIV;
+      94     5583335 :   iy=iv[j];
+      95     5583335 :   iv[j] = idum;
+      96     5583335 :   if ((temp=AM*iy) > RNMX) return RNMX;
+      97     5583335 :   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      790676 :     v1=2.0*RandU01()-1.0;
+     150      790676 :     v2=2.0*RandU01()-1.0;
+     151      790676 :     rsq=v1*v1+v2*v2;
+     152      790676 :     if(rsq<1.0 && rsq>0.0) break;
+     153             :   }
+     154      621215 :   double fac=std::sqrt(-2.*std::log(rsq)/rsq);
+     155      621215 :   saveGaussian=v1*fac;
+     156      621215 :   switchGaussian=true;
+     157      621215 :   return v2*fac;
+     158             : }
+     159             : 
+     160           2 : void Random::Shuffle(std::vector<unsigned>& vec) {
+     161             :   std::iterator_traits<std::vector<unsigned>::iterator >::difference_type i, n;
+     162             :   n = vec.end() - vec.begin();
+     163           6 :   for(i=n-1; i>0; --i) {
+     164           4 :     std::swap(vec[i], vec[(int)round(RandU01() * IM) % i]);
+     165             :   }
+     166           2 : }
+     167             : 
+     168             : 
+     169             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func-sort-c.html b/coverage/tools/Random.h.func-sort-c.html new file mode 100644 index 0000000000..f671a8f3a5 --- /dev/null +++ b/coverage/tools/Random.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func.html b/coverage/tools/Random.h.func.html new file mode 100644 index 0000000000..b24e824f20 --- /dev/null +++ b/coverage/tools/Random.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.gcov.html b/coverage/tools/Random.h.gcov.html new file mode 100644 index 0000000000..215b8e29ab --- /dev/null +++ b/coverage/tools/Random.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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      806981 : class Random {
+      33             :   static const int IA=16807,IM=2147483647,IQ=127773,IR=2836,NTAB=32;
+      34             :   static const int NDIV=(1+(IM-1)/NTAB);
+      35             :   static const double EPS;
+      36             :   static const double AM;
+      37             :   static const double RNMX;
+      38             :   static const double fact;
+      39             :   static const std::string noname;
+      40             :   bool incPrec;
+      41             :   bool switchGaussian;
+      42             :   double saveGaussian;
+      43             :   int iy;
+      44             :   int iv[NTAB];
+      45             :   int idum;
+      46             :   std::string name;
+      47             : public:
+      48             :   explicit Random(const std::string & name=noname);
+      49             :   void setSeed(int idum);
+      50             :   double RandU01();
+      51             :   double U01();
+      52             :   double U01d();
+      53             :   int RandInt(int i);
+      54             :   void Shuffle(std::vector<unsigned>& vec);
+      55             :   void WriteStateFull(std::ostream &)const;
+      56             :   void ReadStateFull (std::istream &);
+      57             :   void fromString(const std::string & str);
+      58             :   void toString(std::string & str)const;
+      59             :   friend std::ostream & operator<<(std::ostream & out,const Random & rng) {
+      60             :     rng.WriteStateFull(out); return out;
+      61             :   }
+      62             :   friend std::istream & operator>>(std::istream & in,Random & rng) {
+      63             :     rng.ReadStateFull(in); return in;
+      64             :   }
+      65             :   double Gaussian();
+      66             :   void IncreasedPrecis(bool i) {incPrec=i;}
+      67             : };
+      68             : 
+      69             : }
+      70             : 
+      71             : #endif
+      72             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func-sort-c.html b/coverage/tools/RootFindingBase.h.func-sort-c.html new file mode 100644 index 0000000000..a7a5b1f9cb --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func.html b/coverage/tools/RootFindingBase.h.func.html new file mode 100644 index 0000000000..61d71d8a24 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.gcov.html b/coverage/tools/RootFindingBase.h.gcov.html new file mode 100644 index 0000000000..653fb61b71 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.gcov.html @@ -0,0 +1,153 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func-sort-c.html b/coverage/tools/Stopwatch.cpp.func-sort-c.html new file mode 100644 index 0000000000..cfaf93f7eb --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9StopwatchE1019
_ZNK4PLMD9Stopwatch3logERSo1019
_ZN4PLMD9StopwatchD2Ev805862
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func.html b/coverage/tools/Stopwatch.cpp.func.html new file mode 100644 index 0000000000..3f290c7fb5 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchD2Ev805862
_ZN4PLMDlsERSoRKNS_9StopwatchE1019
_ZNK4PLMD9Stopwatch3logERSo1019
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.gcov.html b/coverage/tools/Stopwatch.cpp.gcov.html new file mode 100644 index 0000000000..1420f5084b --- /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-05-27 13:05: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        1019 : std::ostream& operator<<(std::ostream&os,const Stopwatch&sw) {
+      36        1019 :   return sw.log(os);
+      37             : }
+      38             : 
+      39      805862 : Stopwatch::~Stopwatch() {
+      40      805862 :   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        7673 :     for(auto & w : watches) {
+      45        6657 :       if(w.second.state==Watch::State::paused) w.second.start().stop();
+      46             :     }
+      47        1016 :     *mylog << *this;
+      48             :   }
+      49      805862 : }
+      50             : 
+      51        1019 : std::ostream& Stopwatch::log(std::ostream&os)const {
+      52             :   const std::size_t bufferlen=1000;
+      53             :   char buffer[bufferlen];
+      54        1019 :   buffer[0]=0;
+      55       41779 :   for(unsigned i=0; i<40; i++) os<<" ";
+      56        1019 :   os<<"      Cycles        Total      Average      Minimum      Maximum\n";
+      57             : 
+      58             :   std::vector<std::string> names;
+      59        7682 :   for(const auto & it : watches) names.push_back(it.first);
+      60        1019 :   std::sort(names.begin(),names.end());
+      61             : 
+      62             :   const double frac=1.0/1000000000.0;
+      63             : 
+      64        7682 :   for(const auto & name : names) {
+      65             :     const Watch&t(watches.find(name)->second);
+      66             :     os<<name;
+      67      164528 :     for(unsigned i=name.length(); i<40; i++) os<<" ";
+      68        6663 :     std::snprintf(buffer,bufferlen,"%12u %12.6f %12.6f %12.6f %12.6f\n", t.cycles, frac*t.total, frac*t.total/t.cycles, frac*t.min,frac*t.max);
+      69        6663 :     os<<buffer;
+      70             :   }
+      71        1019 :   return os;
+      72        1019 : }
+      73             : 
+      74             : }
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func-sort-c.html b/coverage/tools/Stopwatch.h.func-sort-c.html new file mode 100644 index 0000000000..ecc69d8030 --- /dev/null +++ b/coverage/tools/Stopwatch.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch5pauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE571
_ZN4PLMD9Stopwatch4stopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE574
_ZN4PLMD9Stopwatch5startERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1148
_ZN4PLMD9Stopwatch7HandleraSEOS1_3493
_ZN4PLMD9Stopwatch10startPauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1118951
_ZN4PLMDL20StopwatchEmptyStringEv1121233
_ZN4PLMD9Stopwatch9startStopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1530756
_ZN4PLMD9Stopwatch5Watch4stopEv1532337
_ZN4PLMD9Stopwatch5Watch5pauseEv2651728
_ZN4PLMD9Stopwatch7HandlerD2Ev6203636
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func.html b/coverage/tools/Stopwatch.h.func.html new file mode 100644 index 0000000000..8f578b15ac --- /dev/null +++ b/coverage/tools/Stopwatch.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch10startPauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1118951
_ZN4PLMD9Stopwatch4stopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE574
_ZN4PLMD9Stopwatch5Watch4stopEv1532337
_ZN4PLMD9Stopwatch5Watch5pauseEv2651728
_ZN4PLMD9Stopwatch5pauseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE571
_ZN4PLMD9Stopwatch5startERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1148
_ZN4PLMD9Stopwatch7HandlerD2Ev6203636
_ZN4PLMD9Stopwatch7HandleraSEOS1_3493
_ZN4PLMD9Stopwatch9startStopERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1530756
_ZN4PLMDL20StopwatchEmptyStringEv1121233
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.gcov.html b/coverage/tools/Stopwatch.h.gcov.html new file mode 100644 index 0000000000..e8a2b9a215 --- /dev/null +++ b/coverage/tools/Stopwatch.h.gcov.html @@ -0,0 +1,485 @@ + + + + + + + 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-05-27 13:05: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     1121233 : inline static const std::string & StopwatchEmptyString() noexcept {
+     172     1121233 :   const static std::string s;
+     173     1121233 :   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       11467 :   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      805277 :   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     2649707 :   watch(watch),
+     290     2649707 :   stop(stop)
+     291             : {
+     292             :   watch->start();
+     293             : }
+     294             : 
+     295             : inline
+     296     6203636 : Stopwatch::Handler::~Handler() {
+     297     6203636 :   if(watch) {
+     298     2649707 :     if(stop) watch->stop();
+     299     1118951 :     else watch->pause();
+     300             :   }
+     301     6203636 : }
+     302             : 
+     303             : inline
+     304        1148 : Stopwatch& Stopwatch::start(const std::string & name) {
+     305             :   watches[name].start();
+     306        1148 :   return *this;
+     307             : }
+     308             : 
+     309             : inline
+     310         574 : Stopwatch& Stopwatch::stop(const std::string & name) {
+     311         574 :   watches[name].stop();
+     312         574 :   return *this;
+     313             : }
+     314             : 
+     315             : inline
+     316         571 : Stopwatch& Stopwatch::pause(const std::string & name) {
+     317         571 :   watches[name].pause();
+     318         571 :   return *this;
+     319             : }
+     320             : 
+     321             : inline
+     322     1530756 : Stopwatch::Handler Stopwatch::startStop(const std::string&name) {
+     323     1530756 :   return watches[name].startStop();
+     324             : }
+     325             : 
+     326             : inline
+     327     1118951 : Stopwatch::Handler Stopwatch::startPause(const std::string&name) {
+     328     1118951 :   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     2651862 :   state=State::started;
+     362     2651862 :   running++;
+     363     2651862 :   lastStart=std::chrono::high_resolution_clock::now();
+     364             :   return *this;
+     365             : }
+     366             : 
+     367             : inline
+     368     1532337 : Stopwatch::Watch & Stopwatch::Watch::stop() {
+     369     1532337 :   pause();
+     370     1532337 :   state=State::stopped;
+     371     1532337 :   cycles++;
+     372     1532337 :   total+=lap;
+     373     1532337 :   if(lap>max)max=lap;
+     374     1532337 :   if(min>lap || cycles==1)min=lap;
+     375     1532337 :   lap=0;
+     376     1532337 :   return *this;
+     377             : }
+     378             : 
+     379             : inline
+     380     2651728 : Stopwatch::Watch & Stopwatch::Watch::pause() {
+     381     2651728 :   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     2651728 :   plumed_assert(running>0) << "Non matching start/pause or start/stop commands in a Stopwatch";
+     386     2651728 :   running--;
+     387             : // notice: with exception safety the following might be converted to a plain error.
+     388             : // I leave it like this for now:
+     389     2651728 :   if(running!=0) return *this;
+     390     2651677 :   auto t=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-lastStart);
+     391     2651677 :   lap+=t.count();
+     392     2651677 :   return *this;
+     393             : }
+     394             : 
+     395             : inline
+     396             : Stopwatch::Handler Stopwatch::Watch::startStop() {
+     397             :   return Handler( this,true );
+     398             : }
+     399             : 
+     400             : inline
+     401             : Stopwatch::Handler Stopwatch::Watch::startPause() {
+     402             :   return Handler( this,false );
+     403             : }
+     404             : 
+     405             : 
+     406             : }
+     407             : 
+     408             : 
+     409             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func-sort-c.html b/coverage/tools/Subprocess.cpp.func-sort-c.html new file mode 100644 index 0000000000..9d313285c3 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func-sort-c.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD10Subprocess9availableEv85
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10002
_ZN4PLMD10SubprocessD2Ev10002
_ZN4PLMD13SubprocessPidC2Ei10002
_ZN4PLMD13SubprocessPidD2Ev10002
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func.html b/coverage/tools/Subprocess.cpp.func.html new file mode 100644 index 0000000000..09ec99c8a0 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func.html @@ -0,0 +1,136 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD10Subprocess9availableEv85
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10002
_ZN4PLMD10SubprocessD2Ev10002
_ZN4PLMD13SubprocessPid4contEv16
_ZN4PLMD13SubprocessPid4stopEv18
_ZN4PLMD13SubprocessPidC2Ei10002
_ZN4PLMD13SubprocessPidD2Ev10002
_ZN4PLMDL26SubprocessPidGetenvSignalsEv34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.gcov.html b/coverage/tools/Subprocess.cpp.gcov.html new file mode 100644 index 0000000000..a609ac6a46 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.gcov.html @@ -0,0 +1,265 @@ + + + + + + + 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-05-27 13:05: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          85 : bool Subprocess::available() noexcept {
+     134             : #ifdef __PLUMED_HAS_SUBPROCESS
+     135          85 :   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.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func-sort-c.html b/coverage/tools/Subprocess.h.func-sort-c.html new file mode 100644 index 0000000000..41587e0cfb --- /dev/null +++ b/coverage/tools/Subprocess.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func.html b/coverage/tools/Subprocess.h.func.html new file mode 100644 index 0000000000..788de072cd --- /dev/null +++ b/coverage/tools/Subprocess.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.gcov.html b/coverage/tools/Subprocess.h.gcov.html new file mode 100644 index 0000000000..1d1fba255b --- /dev/null +++ b/coverage/tools/Subprocess.h.gcov.html @@ -0,0 +1,218 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func-sort-c.html b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 0000000000..9ed87ef357 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1019
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1069
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19721455
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41286095
_ZNK4PLMD17SwitchingFunction9calculateEdRd88945983
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func.html b/coverage/tools/SwitchingFunction.cpp.func.html new file mode 100644 index 0000000000..61d49d40fc --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE91
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1019
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1069
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41286095
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19721455
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
_ZNK4PLMD17SwitchingFunction9calculateEdRd88945983
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.gcov.html b/coverage/tools/SwitchingFunction.cpp.gcov.html new file mode 100644 index 0000000000..aa8a2860c7 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.gcov.html @@ -0,0 +1,629 @@ + + + + + + + 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-05-27 13:05: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          91 : void SwitchingFunction::registerKeywords( Keywords& keys ) {
+     177         182 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+     178         182 :   keys.add("compulsory","D_0","0.0","the value of D_0 in the switching function");
+     179         182 :   keys.add("optional","D_MAX","the value at which the switching function can be assumed equal to zero");
+     180         182 :   keys.add("compulsory","NN","6","the value of n in the switching function (only needed for TYPE=RATIONAL)");
+     181         182 :   keys.add("compulsory","MM","0","the value of m in the switching function (only needed for TYPE=RATIONAL); 0 implies 2*NN");
+     182         182 :   keys.add("compulsory","A","the value of a in the switching function (only needed for TYPE=SMAP)");
+     183         182 :   keys.add("compulsory","B","the value of b in the switching function (only needed for TYPE=SMAP)");
+     184          91 : }
+     185             : 
+     186        1019 : void SwitchingFunction::set(const std::string & definition,std::string& errormsg) {
+     187        1019 :   std::vector<std::string> data=Tools::getWords(definition);
+     188        1019 :   if( data.size()<1 ) {
+     189             :     errormsg="missing all input for switching function";
+     190             :     return;
+     191             :   }
+     192        1019 :   std::string name=data[0];
+     193             :   data.erase(data.begin());
+     194        1019 :   invr0=0.0;
+     195        1019 :   invr0_2=0.0;
+     196        1019 :   d0=0.0;
+     197        1019 :   dmax=std::numeric_limits<double>::max();
+     198        1019 :   dmax_2=std::numeric_limits<double>::max();
+     199        1019 :   stretch=1.0;
+     200        1019 :   shift=0.0;
+     201        1019 :   init=true;
+     202             : 
+     203             :   bool present;
+     204             : 
+     205        1019 :   present=Tools::findKeyword(data,"D_0");
+     206        1313 :   if(present && !Tools::parse(data,"D_0",d0)) errormsg="could not parse D_0";
+     207             : 
+     208        1019 :   present=Tools::findKeyword(data,"D_MAX");
+     209        1247 :   if(present && !Tools::parse(data,"D_MAX",dmax)) errormsg="could not parse D_MAX";
+     210        1019 :   if(dmax<std::sqrt(std::numeric_limits<double>::max())) dmax_2=dmax*dmax;
+     211        1019 :   bool dostretch=false;
+     212        1019 :   Tools::parseFlag(data,"STRETCH",dostretch); // this is ignored now
+     213        1019 :   dostretch=true;
+     214        1019 :   bool dontstretch=false;
+     215        1019 :   Tools::parseFlag(data,"NOSTRETCH",dontstretch); // this is ignored now
+     216        1019 :   if(dontstretch) dostretch=false;
+     217             :   double r0;
+     218        1019 :   if(name=="CUBIC") {
+     219          18 :     r0 = dmax - d0;
+     220             :   } else {
+     221        1001 :     bool found_r0=Tools::parse(data,"R_0",r0);
+     222        1001 :     if(!found_r0) errormsg="R_0 is required";
+     223             :   }
+     224        1019 :   invr0=1.0/r0;
+     225        1019 :   invr0_2=invr0*invr0;
+     226             : 
+     227        1019 :   if(name=="RATIONAL") {
+     228         291 :     type=rational;
+     229         291 :     nn=6;
+     230         291 :     mm=0;
+     231         291 :     present=Tools::findKeyword(data,"NN");
+     232         441 :     if(present && !Tools::parse(data,"NN",nn)) errormsg="could not parse NN";
+     233         291 :     present=Tools::findKeyword(data,"MM");
+     234         441 :     if(present && !Tools::parse(data,"MM",mm)) errormsg="could not parse MM";
+     235         291 :     if(mm==0) mm=2*nn;
+     236         357 :     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        1017 :   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        1017 :   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        1017 :   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        1019 : }
+     324             : 
+     325        1069 : std::string SwitchingFunction::description() const {
+     326        1069 :   std::ostringstream ostr;
+     327        1069 :   ostr<<1./invr0<<".  Using ";
+     328        1069 :   if(type==rational) {
+     329         348 :     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        1069 :   ostr<<" switching function with parameters d0="<<d0;
+     350        1069 :   if(type==rational) {
+     351         348 :     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        1069 :   return ostr.str();
+     363        1069 : }
+     364             : 
+     365    41286095 : double SwitchingFunction::do_rational(double rdist,double&dfunc,int nn,int mm)const {
+     366             :   double result;
+     367    41286095 :   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    25190757 :     double rNdist=Tools::fastpow(rdist,nn-1);
+     370    25190757 :     double iden=1.0/(1+rNdist*rdist);
+     371    25190757 :     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    41286095 :   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    88945983 : double SwitchingFunction::calculate(double distance,double&dfunc)const {
+     432    88945983 :   plumed_massert(init,"you are trying to use an unset SwitchingFunction");
+     433    88945983 :   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    88495442 :   if(leptonx2) {
+     440           2 :     return calculateSqr(distance*distance,dfunc);
+     441             :   }
+     442    88495440 :   const double rdist = (distance-d0)*invr0;
+     443             :   double result;
+     444             : 
+     445    88495440 :   if(rdist<=0.) {
+     446             :     result=1.;
+     447    24431541 :     dfunc=0.0;
+     448             :   } else {
+     449    64063899 :     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    33772598 :       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    64063899 :     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    64063899 :     dfunc/=distance;
+     505             :   }
+     506             : 
+     507    88495440 :   result=result*stretch+shift;
+     508    88495440 :   dfunc*=stretch;
+     509             : 
+     510    88495440 :   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.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func-sort-c.html b/coverage/tools/Tensor.cpp.func-sort-c.html new file mode 100644 index 0000000000..bc4dfa7c62 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func.html b/coverage/tools/Tensor.cpp.func.html new file mode 100644 index 0000000000..82504bb29d --- /dev/null +++ b/coverage/tools/Tensor.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.gcov.html b/coverage/tools/Tensor.cpp.gcov.html new file mode 100644 index 0000000000..feb46db1eb --- /dev/null +++ b/coverage/tools/Tensor.cpp.gcov.html @@ -0,0 +1,115 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func-sort-c.html b/coverage/tools/Tensor.h.func-sort-c.html new file mode 100644 index 0000000000..fc0c278b9f --- /dev/null +++ b/coverage/tools/Tensor.h.func-sort-c.html @@ -0,0 +1,344 @@ + + + + + + + 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-05-27 13:05: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
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63425
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv130819
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv204967
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE371340
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE548920
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE859175
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261656
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1596525
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730074
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE1747545
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv2093614
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3202134
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv3439149
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4339003
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4758860
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916659
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9326427
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13395760
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16996312
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE33529052
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42880312
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_47075253
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev47469421
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105724388
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_130591419
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_148935080
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d154202291
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd154207316
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj235715368
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5395296118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func.html b/coverage/tools/Tensor.h.func.html new file mode 100644 index 0000000000..b3495d06ac --- /dev/null +++ b/coverage/tools/Tensor.h.func.html @@ -0,0 +1,344 @@ + + + + + + + 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-05-27 13:05: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_EEE1747545
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv2093614
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE29160
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1596525
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13395760
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_148935080
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev47469421
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9326427
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj235715368
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_47075253
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd154207316
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42880312
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16996312
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105724388
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE33529052
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4758860
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE371340
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4339003
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916659
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE859175
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d254
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261656
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d154202291
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_130591419
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730074
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv204967
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj24300
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3202134
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv130819
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv3439149
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5395296118
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63425
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv21229
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.gcov.html b/coverage/tools/Tensor.h.gcov.html new file mode 100644 index 0000000000..ea7cd21ba9 --- /dev/null +++ b/coverage/tools/Tensor.h.gcov.html @@ -0,0 +1,650 @@ + + + + + + + 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-05-27 13:05: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    83937843 : void TensorGeneric<n,m>::auxiliaryConstructor(double first,Args... arg)
+     216             : {
+     217    83937843 :   d[n*m-(sizeof...(Args))-1]=first;
+     218    74611416 :   auxiliaryConstructor(arg...);
+     219    83937843 : }
+     220             : 
+     221             : template <unsigned n,unsigned m>
+     222             : template<typename... Args>
+     223     9326427 : 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     9326427 :   auxiliaryConstructor(first,arg...);
+     227     9326427 : }
+     228             : 
+     229             : template<unsigned n,unsigned m>
+     230    58879995 : TensorGeneric<n,m>::TensorGeneric() {
+     231    58879995 :   LoopUnroller<n*m>::_zero(d.data());
+     232    58879995 : }
+     233             : 
+     234             : template<unsigned n,unsigned m>
+     235   148935080 : TensorGeneric<n,m>::TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     236  1936156040 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++)d[i*m+j]=v1[i]*v2[j];
+     237   148935080 : }
+     238             : 
+     239             : template<unsigned n,unsigned m>
+     240     2093614 : void TensorGeneric<n,m>::zero() {
+     241     2093614 :   LoopUnroller<n*m>::_zero(d.data());
+     242     2093614 : }
+     243             : 
+     244             : template<unsigned n,unsigned m>
+     245   260754920 : 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   260754920 :   return d[m*i+j];
+     251             : }
+     252             : 
+     253             : template<unsigned n,unsigned m>
+     254  5399914846 : 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  5399914846 :   return d[m*i+j];
+     260             : }
+     261             : 
+     262             : template<unsigned n,unsigned m>
+     263    42880312 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator +=(const TensorGeneric<n,m>& b) {
+     264    42880312 :   LoopUnroller<n*m>::_add(d.data(),b.d.data());
+     265    42880312 :   return *this;
+     266             : }
+     267             : 
+     268             : template<unsigned n,unsigned m>
+     269    47075253 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator -=(const TensorGeneric<n,m>& b) {
+     270    47075253 :   LoopUnroller<n*m>::_sub(d.data(),b.d.data());
+     271    47075253 :   return *this;
+     272             : }
+     273             : 
+     274             : template<unsigned n,unsigned m>
+     275   154207316 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator *=(double s) {
+     276   154207316 :   LoopUnroller<n*m>::_mul(d.data(),s);
+     277   154207316 :   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       63425 : TensorGeneric<n,m> TensorGeneric<n,m>::operator-()const {
+     293       63425 :   TensorGeneric<n,m> r;
+     294       63425 :   LoopUnroller<n*m>::_neg(r.d.data(),d.data());
+     295       63425 :   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     2888253 : TensorGeneric<n,m>& TensorGeneric<n,m>::setRow(unsigned i,const VectorGeneric<m> & r) {
+     306    11553012 :   for(unsigned j=0; j<m; ++j) (*this)(i,j)=r(j);
+     307     2888253 :   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     3202134 : VectorGeneric<m> TensorGeneric<n,m>::getRow(unsigned i)const {
+     319     3202134 :   VectorGeneric<m> v;
+     320    12808536 :   for(unsigned j=0; j<m; ++j) v(j)=(*this)(i,j);
+     321     3202134 :   return v;
+     322             : }
+     323             : 
+     324             : template<unsigned n,unsigned m>
+     325     1730074 : TensorGeneric<n,m> operator+(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     326     1730074 :   TensorGeneric<n,m> t(t1);
+     327     1730074 :   t+=t2;
+     328     1730074 :   return t;
+     329             : }
+     330             : 
+     331             : template<unsigned n,unsigned m>
+     332     1261656 : TensorGeneric<n,m> operator-(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     333     1261656 :   TensorGeneric<n,m> t(t1);
+     334     1261656 :   t-=t2;
+     335     1261656 :   return t;
+     336             : }
+     337             : 
+     338             : template<unsigned n,unsigned m>
+     339   154202291 : TensorGeneric<n,m> operator*(const TensorGeneric<n,m>&t1,double s) {
+     340   154202291 :   TensorGeneric<n,m> t(t1);
+     341   154202291 :   t*=s;
+     342   154202291 :   return t;
+     343             : }
+     344             : 
+     345             : template<unsigned n,unsigned m>
+     346   130591419 : TensorGeneric<n,m> operator*(double s,const TensorGeneric<n,m>&t1) {
+     347   130591419 :   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      204967 : double TensorGeneric<3,3>::determinant()const {
+     358             :   return
+     359      204967 :     d[0]*d[4]*d[8]
+     360      204967 :     + d[1]*d[5]*d[6]
+     361      204967 :     + d[2]*d[3]*d[7]
+     362      204967 :     - d[0]*d[5]*d[7]
+     363      204967 :     - d[1]*d[3]*d[8]
+     364      204967 :     - d[2]*d[4]*d[6];
+     365             : }
+     366             : 
+     367             : template<unsigned n,unsigned m>
+     368             : inline
+     369    13395760 : TensorGeneric<n,n> TensorGeneric<n,m>::identity() {
+     370    13395760 :   TensorGeneric<n,n> t;
+     371    53583040 :   for(unsigned i=0; i<n; i++) t(i,i)=1.0;
+     372    13395760 :   return t;
+     373             : }
+     374             : 
+     375             : template<unsigned n,unsigned m>
+     376     3439149 : TensorGeneric<m,n> TensorGeneric<n,m>::transpose()const {
+     377     3439149 :   TensorGeneric<m,n> t;
+     378    44708937 :   for(unsigned i=0; i<m; i++)for(unsigned j=0; j<n; j++) t(i,j)=(*this)(j,i);
+     379     3439149 :   return t;
+     380             : }
+     381             : 
+     382             : template<>
+     383             : inline
+     384      130819 : TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const {
+     385      130819 :   TensorGeneric t;
+     386      130819 :   double invdet=1.0/determinant();
+     387     1700647 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     388     1177371 :       t(j,i)=invdet*(   (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3)
+     389     1177371 :                         -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3));
+     390      130819 :   return t;
+     391             : }
+     392             : 
+     393             : template<unsigned n,unsigned m,unsigned l>
+     394     4758860 : TensorGeneric<n,l> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b) {
+     395     4758860 :   TensorGeneric<n,l> t;
+     396   190354400 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<l; j++) for(unsigned k=0; k<m; k++) {
+     397   128489220 :         t(i,j)+=a(i,k)*b(k,j);
+     398             :       }
+     399     4758860 :   return t;
+     400             : }
+     401             : 
+     402             : template<unsigned n,unsigned m>
+     403    33529052 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const VectorGeneric<m>&b) {
+     404    33529052 :   VectorGeneric<n> t;
+     405   435877676 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(i,j)*b(j);
+     406    33529052 :   return t;
+     407             : }
+     408             : 
+     409             : template<unsigned n,unsigned m>
+     410   106109282 : VectorGeneric<n> matmul(const VectorGeneric<m>&a,const TensorGeneric<m,n>&b) {
+     411   106109282 :   VectorGeneric<n> t;
+     412  1380575348 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(j)*b(j,i);
+     413   106109282 :   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      371340 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const VectorGeneric<l>&c) {
+     428      371340 :   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       65643 :   return t.inverse();
+     449             : }
+     450             : 
+     451             : template<unsigned n,unsigned m>
+     452      859175 : TensorGeneric<n,m> transpose(const TensorGeneric<m,n>&t) {
+     453      859175 :   return t.transpose();
+     454             : }
+     455             : 
+     456             : template<unsigned n,unsigned m>
+     457     1747545 : TensorGeneric<n,m> extProduct(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     458     1747545 :   return TensorGeneric<n,m>(v1,v2);
+     459             : }
+     460             : 
+     461             : inline
+     462     4339003 : 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     4339003 :            -v2[2],   0.0, v2[0],
+     467     4339003 :            v2[1],-v2[0],   0.0);
+     468             : }
+     469             : 
+     470             : inline
+     471     4916659 : 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     4916659 :            v1[2],0.0,-v1[0],
+     476     4916659 :            -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.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.func-sort-c.html b/coverage/tools/Tools.cpp.func-sort-c.html new file mode 100644 index 0000000000..765c2abda4 --- /dev/null +++ b/coverage/tools/Tools.cpp.func-sort-c.html @@ -0,0 +1,292 @@ + + + + + + + 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:25527891.7 %
Date:2024-05-27 13:05:14Functions:515592.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclEPKc1
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsIRNS0_21process_one_exceptionEEEvOT_14
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToIntIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm97
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_120
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe128
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception133
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv134
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4320
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4985
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj4985
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7162
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11454
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11683
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14304
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb15000
_ZN4PLMD5Tools12molfile_lockEv18842
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_78989
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_98872
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i107190
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_332007
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE450408
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_455393
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc644164
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_907035
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE949153
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1355542
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2222876
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2222876
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2225593
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2739484
_ZN4PLMD5Tools8getWordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKcPiSA_RKb3876776
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14226760
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14226760
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14226760
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.func.html b/coverage/tools/Tools.cpp.func.html new file mode 100644 index 0000000000..8a172ddbca --- /dev/null +++ b/coverage/tools/Tools.cpp.func.html @@ -0,0 +1,292 @@ + + + + + + + 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:25527891.7 %
Date:2024-05-27 13:05:14Functions:515592.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv134
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclEPKc1
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception133
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_120
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsIRNS0_21process_one_exceptionEEEvOT_14
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_98872
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14226760
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2225593
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_455393
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2222876
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_4985
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToIntIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToIntIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12molfile_lockEv18842
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1355542
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14226760
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_128
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb15000
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE14304
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE450408
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_78989
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14226760
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe128
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2222876
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj4985
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm97
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11454
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_332007
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4320
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7162
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE949153
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i107190
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2739484
_ZN4PLMD5Tools8getWordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKcPiSA_RKb3876776
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11683
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_907035
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc644164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.gcov.html b/coverage/tools/Tools.cpp.gcov.html new file mode 100644 index 0000000000..64dcf14380 --- /dev/null +++ b/coverage/tools/Tools.cpp.gcov.html @@ -0,0 +1,596 @@ + + + + + + + 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:25527891.7 %
Date:2024-05-27 13:05:14Functions:515592.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    16908113 : bool Tools::convertToAny(const std::string & str,T & t) {
+      41    31590633 :   std::istringstream istr(str.c_str());
+      42    16908113 :   bool ok=static_cast<bool>(istr>>t);
+      43    16908113 :   if(!ok) return false;
+      44             :   std::string remaining;
+      45    14804694 :   istr>>remaining;
+      46    14804694 :   return remaining.length()==0;
+      47    16908113 : }
+      48             : 
+      49     2222876 : bool Tools::convertNoexcept(const std::string & str,int & t) {
+      50     2222876 :   return convertToInt(str,t);
+      51             : }
+      52             : 
+      53           3 : bool Tools::convertNoexcept(const std::string & str,long int & t) {
+      54           3 :   return convertToInt(str,t);
+      55             : }
+      56             : 
+      57          85 : bool Tools::convertNoexcept(const std::string & str,long long int & t) {
+      58          85 :   return convertToInt(str,t);
+      59             : }
+      60             : 
+      61        4985 : bool Tools::convertNoexcept(const std::string & str,unsigned & t) {
+      62        4985 :   return convertToInt(str,t);
+      63             : }
+      64             : 
+      65          97 : bool Tools::convertNoexcept(const std::string & str,long unsigned & t) {
+      66          97 :   return convertToInt(str,t);
+      67             : }
+      68             : 
+      69          54 : bool Tools::convertNoexcept(const std::string & str,long long unsigned & t) {
+      70          54 :   return convertToInt(str,t);
+      71             : }
+      72             : 
+      73      450408 : bool Tools::convertNoexcept(const std::string & str,AtomNumber &a) {
+      74             :   // Note: AtomNumber's are NOT converted as int, so as to
+      75             :   // avoid using lepton conversions.
+      76             :   unsigned i;
+      77      450408 :   bool r=convertToAny(str,i);
+      78      450408 :   if(r) a.setSerial(i);
+      79      450408 :   return r;
+      80             : }
+      81             : 
+      82             : template<class T>
+      83     2228100 : bool Tools::convertToInt(const std::string & str,T & t) {
+      84             :   // First try standard conversion
+      85     2228100 :   if(convertToAny(str,t)) return true;
+      86             :   // Then use lepton
+      87             :   try {
+      88     2008031 :     double r=lepton::Parser::parse(str).evaluate(lepton::Constants());
+      89             : 
+      90             :     // now sanity checks on the resulting number
+      91             : 
+      92             :     // it should not overflow the requested int type:
+      93             :     // (see https://stackoverflow.com/a/526092)
+      94     2008031 :     if(r>std::nextafter(std::numeric_limits<T>::max(), 0)) return false;
+      95     2008031 :     if(r<std::nextafter(std::numeric_limits<T>::min(), 0)) return false;
+      96             : 
+      97             :     // do the actual conversion
+      98     2008031 :     auto tmp=static_cast<T>(std::round(r));
+      99             : 
+     100             :     // it should be *very close* to itself if converted back to double
+     101     2008031 :     double diff= r-static_cast<double>(tmp);
+     102     2008031 :     if(diff*diff > 1e-20) return false;
+     103             :     // this is to accomodate small numerical errors and allow e.g. exp(log(7)) to be integer
+     104             : 
+     105             :     // it should be change if incremented or decremented by one (see https://stackoverflow.com/a/43656140)
+     106     2008027 :     if(r == static_cast<double>(tmp-1)) return false;
+     107     2008026 :     if(r == static_cast<double>(tmp+1)) return false;
+     108             : 
+     109             :     // everything is fine, then store in t
+     110     2008026 :     t=tmp;
+     111     2008026 :     return true;
+     112           0 :   } catch(const PLMD::lepton::Exception& exc) {
+     113             :   }
+     114           0 :   return false;
+     115             : }
+     116             : 
+     117             : 
+     118             : template<class T>
+     119    14226888 : bool Tools::convertToReal(const std::string & str,T & t) {
+     120    14226888 :   if(convertToAny(str,t)) return true;
+     121     8378094 :   if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi") {
+     122     1047301 :     t=pi; return true;
+     123     2094570 :   } else if(str=="-PI" || str=="-pi") {
+     124     1047220 :     t=-pi; return true;
+     125             :   }
+     126             :   try {
+     127          65 :     t=lepton::Parser::parse(str).evaluate(lepton::Constants());
+     128          24 :     return true;
+     129          41 :   } catch(const PLMD::lepton::Exception& exc) {
+     130             :   }
+     131          41 :   if( str.find("PI")!=std::string::npos ) {
+     132           0 :     std::size_t pi_start=str.find_first_of("PI");
+     133           0 :     if(str.substr(pi_start)!="PI") return false;
+     134           0 :     std::istringstream nstr(str.substr(0,pi_start));
+     135           0 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     136           0 :     if(!ok) return false;
+     137           0 :     t=ff*pi;
+     138           0 :     std::string remains; nstr>>remains;
+     139           0 :     return remains.length()==0;
+     140          41 :   } else if( str.find("pi")!=std::string::npos ) {
+     141          15 :     std::size_t pi_start=str.find_first_of("pi");
+     142          30 :     if(str.substr(pi_start)!="pi") return false;
+     143          15 :     std::istringstream nstr(str.substr(0,pi_start));
+     144          15 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     145          15 :     if(!ok) return false;
+     146          15 :     t=ff*pi;
+     147          15 :     std::string remains; nstr>>remains;
+     148          15 :     return remains.length()==0;
+     149          41 :   } else if(str=="NAN") {
+     150           0 :     t=std::numeric_limits<double>::quiet_NaN();
+     151           0 :     return true;
+     152             :   }
+     153             :   return false;
+     154             : }
+     155             : 
+     156           0 : bool Tools::convertNoexcept(const std::string & str,float & t) {
+     157           0 :   return convertToReal(str,t);
+     158             : }
+     159             : 
+     160    14226760 : bool Tools::convertNoexcept(const std::string & str,double & t) {
+     161    14226760 :   return convertToReal(str,t);
+     162             : }
+     163             : 
+     164         128 : bool Tools::convertNoexcept(const std::string & str,long double & t) {
+     165         128 :   return convertToReal(str,t);
+     166             : }
+     167             : 
+     168       78989 : bool Tools::convertNoexcept(const std::string & str,std::string & t) {
+     169             :   t=str;
+     170       78989 :   return true;
+     171             : }
+     172             : 
+     173     3876776 : std::vector<std::string> Tools::getWords(const std::string & line,const char* separators,int * parlevel,const char* parenthesis, const bool& delete_parenthesis) {
+     174     3876776 :   plumed_massert(std::strlen(parenthesis)==1,"multiple parenthesis type not available");
+     175     3876776 :   plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
+     176             :                  "only ( [ { allowed as parenthesis");
+     177     3876776 :   if(!separators) separators=" \t\n";
+     178     3876776 :   const std::string sep(separators);
+     179     3876776 :   char openpar=parenthesis[0];
+     180             :   char closepar;
+     181             :   if(openpar=='(') closepar=')';
+     182     3876776 :   if(openpar=='[') closepar=']';
+     183     3876776 :   if(openpar=='{') closepar='}';
+     184             :   std::vector<std::string> words;
+     185             :   std::string word;
+     186             :   int parenthesisLevel=0;
+     187     3876776 :   if(parlevel) parenthesisLevel=*parlevel;
+     188   199388033 :   for(unsigned i=0; i<line.length(); i++) {
+     189             :     bool found=false;
+     190             :     bool onParenthesis=false;
+     191   195511257 :     if( (line[i]==openpar || line[i]==closepar) && delete_parenthesis ) onParenthesis=true;
+     192   195511257 :     if(line[i]==closepar) {
+     193        2767 :       parenthesisLevel--;
+     194        2767 :       plumed_massert(parenthesisLevel>=0,"Extra closed parenthesis in '" + line + "'");
+     195             :     }
+     196   782262105 :     if(parenthesisLevel==0) for(unsigned j=0; j<sep.length(); j++) if(line[i]==sep[j]) found=true;
+     197             : // If at parenthesis level zero (outer)
+     198   195511257 :     if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
+     199             :     //if(onParenthesis) word.push_back(' ');
+     200   195511257 :     if(line[i]==openpar) parenthesisLevel++;
+     201   195511257 :     if(found && word.length()>0) {
+     202    11613352 :       if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
+     203    11613352 :       words.push_back(word);
+     204             :       word.clear();
+     205             :     }
+     206             :   }
+     207     3876776 :   if(word.length()>0) {
+     208     3759344 :     if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
+     209     3759344 :     words.push_back(word);
+     210             :   }
+     211     3876776 :   if(parlevel) *parlevel=parenthesisLevel;
+     212     3876776 :   return words;
+     213           0 : }
+     214             : 
+     215       15000 : bool Tools::getParsedLine(IFile& ifile,std::vector<std::string> & words, bool trimcomments) {
+     216       15000 :   std::string line("");
+     217             :   words.clear();
+     218             :   bool stat;
+     219             :   bool inside=false;
+     220       15000 :   int parlevel=0;
+     221             :   bool mergenext=false;
+     222       32510 :   while((stat=ifile.getline(line))) {
+     223       31640 :     if(trimcomments) trimComments(line);
+     224       31640 :     trim(line);
+     225       31640 :     if(line.length()==0) continue;
+     226       25728 :     std::vector<std::string> w=getWords(line,NULL,&parlevel,"{",trimcomments);
+     227       25728 :     if(!w.empty()) {
+     228       36992 :       if(inside && *(w.begin())=="...") {
+     229             :         inside=false;
+     230        1221 :         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]);
+     231        1221 :         plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
+     232        1221 :         w.clear(); if(!trimcomments) words.push_back("...");
+     233       24262 :       } else if(*(w.end()-1)=="...") {
+     234             :         inside=true;
+     235             :         w.erase(w.end()-1);
+     236             :       };
+     237             :       int i0=0;
+     238       25483 :       if(mergenext && words.size()>0 && w.size()>0) {
+     239         128 :         words[words.size()-1]+=" "+w[0];
+     240             :         i0=1;
+     241             :       }
+     242       91109 :       for(unsigned i=i0; i<w.size(); ++i) words.push_back(w[i]);
+     243             :     }
+     244       25728 :     mergenext=(parlevel>0);
+     245       25728 :     if(!inside)break;
+     246       11598 :     if(!trimcomments && parlevel==0) words.push_back("@newline");
+     247       11598 :     else if(!trimcomments) words[words.size()-1] += " @newline";
+     248       25728 :   }
+     249       15000 :   plumed_massert(parlevel==0,"non matching parenthesis");
+     250       15000 :   if(words.size()>0) return true;
+     251             :   return stat;
+     252             : }
+     253             : 
+     254             : 
+     255     2739484 : bool Tools::getline(FILE* fp,std::string & line) {
+     256             :   line="";
+     257             :   const int bufferlength=1024;
+     258             :   char buffer[bufferlength];
+     259             :   bool ret;
+     260  2807971100 :   for(int i=0; i<bufferlength; i++) buffer[i]='\0';
+     261     2739484 :   while((ret=fgets(buffer,bufferlength,fp))) {
+     262     2738744 :     line.append(buffer);
+     263     2738744 :     unsigned ss=std::strlen(buffer);
+     264     2738744 :     if(ss>0) if(buffer[ss-1]=='\n') break;
+     265             :   };
+     266     2739484 :   if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
+     267     2739484 :   if(line.length()>0) if(*(line.end()-1)=='\r') line.erase(line.end()-1);
+     268     2739484 :   return ret;
+     269             : }
+     270             : 
+     271      949153 : void Tools::trim(std::string & s) {
+     272      949153 :   auto n=s.find_last_not_of(" \t");
+     273      949153 :   if(n!=std::string::npos) s.resize(n+1);
+     274      949153 : }
+     275             : 
+     276     1355542 : void Tools::trimComments(std::string & s) {
+     277     1355542 :   auto n=s.find_first_of("#");
+     278     1355542 :   if(n!=std::string::npos) s.resize(n);
+     279     1355542 : }
+     280             : 
+     281      332007 : bool Tools::caseInSensStringCompare(const std::string & str1, const std::string &str2)
+     282             : {
+     283      332007 :   return ((str1.size() == str2.size()) && std::equal(str1.begin(), str1.end(), str2.begin(), [](char c1, char c2) {
+     284      644164 :     return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
+     285      332007 :   }));
+     286             : }
+     287             : 
+     288      107190 : bool Tools::getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep) {
+     289             :   s.clear();
+     290      384422 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     291      332007 :     if((*p).length()==0) continue;
+     292      332007 :     std::string x=(*p).substr(0,key.length());
+     293      332007 :     if(caseInSensStringCompare(x,key)) {
+     294       54775 :       if((*p).length()==key.length())return false;
+     295       54774 :       std::string tmp=(*p).substr(key.length(),(*p).length());
+     296             :       line.erase(p);
+     297             :       s=tmp;
+     298       54774 :       const std::string multi("@replicas:");
+     299       54774 :       if(rep>=0 && startWith(s,multi)) {
+     300          24 :         s=s.substr(multi.length(),s.length());
+     301          24 :         std::vector<std::string> words=getWords(s,"\t\n ,");
+     302          24 :         plumed_massert(rep<static_cast<int>(words.size()),"Number of fields in " + s + " not consistent with number of replicas");
+     303          24 :         s=words[rep];
+     304          24 :       }
+     305             :       return true;
+     306             :     }
+     307             :   };
+     308             :   return false;
+     309             : }
+     310             : 
+     311       11454 : void Tools::interpretRanges(std::vector<std::string>&s) {
+     312             :   std::vector<std::string> news;
+     313       57296 :   for(const auto & p :s) {
+     314       45842 :     news.push_back(p);
+     315       45842 :     size_t dash=p.find("-");
+     316       46453 :     if(dash==std::string::npos) continue;
+     317             :     int first;
+     318        3292 :     if(!Tools::convertToAny(p.substr(0,dash),first)) continue;
+     319        1035 :     int stride=1;
+     320             :     int second;
+     321        1035 :     size_t colon=p.substr(dash+1).find(":");
+     322        1035 :     if(colon!=std::string::npos) {
+     323         108 :       if(!Tools::convertToAny(p.substr(dash+1).substr(0,colon),second) ||
+     324         144 :           !Tools::convertToAny(p.substr(dash+1).substr(colon+1),stride)) continue;
+     325             :     } else {
+     326        1998 :       if(!Tools::convertToAny(p.substr(dash+1),second)) continue;
+     327             :     }
+     328        1035 :     news.resize(news.size()-1);
+     329        1035 :     if(first<=second) {
+     330        1034 :       plumed_massert(stride>0,"interpreting ranges "+ p + ", stride should be positive");
+     331      403537 :       for(int i=first; i<=second; i+=stride) {
+     332             :         std::string ss;
+     333      402503 :         convert(i,ss);
+     334      402503 :         news.push_back(ss);
+     335             :       }
+     336             :     } else {
+     337           1 :       plumed_massert(stride<0,"interpreting ranges "+ p + ", stride should be positive");
+     338           3 :       for(int i=first; i>=second; i+=stride) {
+     339             :         std::string ss;
+     340           2 :         convert(i,ss);
+     341           2 :         news.push_back(ss);
+     342             :       }
+     343             :     }
+     344             :   }
+     345       11454 :   s=news;
+     346       11454 : }
+     347             : 
+     348       14304 : void Tools::interpretLabel(std::vector<std::string>&s) {
+     349       14304 :   if(s.size()<2)return;
+     350       13984 :   std::string s0=s[0];
+     351       13984 :   unsigned l=s0.length();
+     352       13984 :   if(l<1) return;
+     353       13984 :   if(s0[l-1]==':') {
+     354             :     s[0]=s[1];
+     355       21596 :     s[1]="LABEL="+s0.substr(0,l-1);
+     356             :   }
+     357       13984 :   std::transform(s[0].begin(), s[0].end(), s[0].begin(), ::toupper);
+     358             : }
+     359             : 
+     360        7162 : std::vector<std::string> Tools::ls(const std::string&d) {
+     361             :   DIR*dir;
+     362             :   std::vector<std::string> result;
+     363        7162 :   if ((dir=opendir(d.c_str()))) {
+     364             : #if defined(__PLUMED_HAS_READDIR_R)
+     365             :     struct dirent ent;
+     366             : #endif
+     367             :     while(true) {
+     368             :       struct dirent *res;
+     369             : #if defined(__PLUMED_HAS_READDIR_R)
+     370             :       readdir_r(dir,&ent,&res);
+     371             : #else
+     372      113564 :       res=readdir(dir);
+     373             : #endif
+     374      113564 :       if(!res) break;
+     375      510524 :       if(std::string(res->d_name)!="." && std::string(res->d_name)!="..") result.push_back(res->d_name);
+     376             :     }
+     377        7162 :     closedir (dir);
+     378             :   }
+     379        7162 :   return result;
+     380           0 : }
+     381             : 
+     382        4320 : void Tools::stripLeadingAndTrailingBlanks( std::string& str ) {
+     383        4320 :   std::size_t first=str.find_first_not_of(' ');
+     384        4320 :   std::size_t last=str.find_last_not_of(' ');
+     385        8603 :   if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
+     386        4320 : }
+     387             : 
+     388       11683 : std::string Tools::extension(const std::string&s) {
+     389       11683 :   size_t n=s.find_last_of(".");
+     390             :   std::string ext;
+     391       11683 :   if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()) {
+     392        8619 :     ext=s.substr(n+1);
+     393        8619 :     if(ext.find("/")!=std::string::npos) ext="";
+     394        8619 :     std::string base=s.substr(0,n);
+     395        8619 :     if(base.length()==0) ext="";
+     396        8619 :     if(base.length()>0 && base[base.length()-1]=='/') ext="";
+     397             :   }
+     398       11683 :   return ext;
+     399             : }
+     400             : 
+     401          14 : double Tools::bessel0( const double& val ) {
+     402          14 :   if (std::abs(val)<3.75) {
+     403           2 :     double y = Tools::fastpow( val/3.75, 2 );
+     404           2 :     return 1 + y*(3.5156229 +y*(3.0899424 + y*(1.2067492+y*(0.2659732+y*(0.0360768+y*0.0045813)))));
+     405             :   }
+     406          12 :   double ax=std::abs(val), y=3.75/ax, bx=std::exp(ax)/std::sqrt(ax);
+     407          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)))))));
+     408          12 :   return ax*bx;
+     409             : }
+     410             : 
+     411      907035 : bool Tools::startWith(const std::string & full,const std::string &start) {
+     412      907035 :   return (full.substr(0,start.length())==start);
+     413             : }
+     414             : 
+     415       98872 : bool Tools::findKeyword(const std::vector<std::string>&line,const std::string&key) {
+     416       98872 :   const std::string search(key+"=");
+     417      583189 :   for(const auto & p : line) {
+     418      532145 :     if(startWith(p,search)) return true;
+     419             :   }
+     420             :   return false;
+     421             : }
+     422             : 
+     423         521 : Tools::DirectoryChanger::DirectoryChanger(const char*path) {
+     424         521 :   if(!path) return;
+     425         521 :   if(std::strlen(path)==0) return;
+     426             : #ifdef __PLUMED_HAS_GETCWD
+     427           2 :   char* ret=getcwd(cwd,buffersize);
+     428           2 :   plumed_assert(ret)<<"Name of current directory too long, increase buffer size";
+     429             : #else
+     430             :   plumed_error()<<"You are trying to use DirectoryChanger but your system does not support getcwd";
+     431             : #endif
+     432             : #ifdef __PLUMED_HAS_CHDIR
+     433           2 :   int r=chdir(path);
+     434           3 :   plumed_assert(r==0) <<"Cannot chdir to directory "<<path<<". The directory must exist!";
+     435             : #else
+     436             :   plumed_error()<<"You are trying to use DirectoryChanger but your system does not support chdir";
+     437             : #endif
+     438             : }
+     439             : 
+     440         521 : Tools::DirectoryChanger::~DirectoryChanger() {
+     441             : #ifdef __PLUMED_HAS_CHDIR
+     442         520 :   if(std::strlen(cwd)==0) return;
+     443           1 :   int ret=chdir(cwd);
+     444             : // we cannot put an assertion here (in a destructor) otherwise cppcheck complains
+     445             : // we thus just report the problem
+     446           1 :   if(ret!=0) std::fprintf(stderr,"+++ WARNING: cannot cd back to directory %s\n",cwd);
+     447             : #endif
+     448         520 : }
+     449             : 
+     450       18842 : std::unique_ptr<std::lock_guard<std::mutex>> Tools::molfile_lock() {
+     451             :   static std::mutex mtx;
+     452       18842 :   return Tools::make_unique<std::lock_guard<std::mutex>>(mtx);
+     453             : }
+     454             : 
+     455             : /// Internal tool, I am keeping it private for now
+     456             : namespace {
+     457             : 
+     458             : class process_one_exception {
+     459             :   std::string & msg;
+     460             :   bool first=true;
+     461         134 :   void update() {
+     462         134 :     if(!first) msg+="\n\nThe above exception was the direct cause of the following exception:\n";
+     463         134 :     first=false;
+     464         134 :   }
+     465             : public:
+     466         120 :   process_one_exception(std::string & msg):
+     467         120 :     msg(msg)
+     468             :   {}
+     469         133 :   void operator()(const std::exception & e) {
+     470         133 :     update();
+     471         133 :     msg+=e.what();
+     472         133 :   }
+     473           0 :   void operator()(const std::string & e) {
+     474           0 :     update();
+     475           0 :     msg+=e;
+     476           0 :   }
+     477           1 :   void operator()(const char* e) {
+     478           1 :     update();
+     479           1 :     msg+=e;
+     480           1 :   }
+     481             : };
+     482             : 
+     483             : template<class T>
+     484         134 : static void process_all_exceptions(T&& f) {
+     485             :   try {
+     486             :     // First throw the current exception
+     487         134 :     throw;
+     488         148 :   } catch(const std::nested_exception & e) {
+     489             :     // If nested, we go recursive
+     490             :     // notice that we apply function f only if exception is also a std::exception
+     491             :     try {
+     492          14 :       e.rethrow_nested();
+     493          28 :     } catch(...) {
+     494          14 :       process_all_exceptions(f);
+     495             :     }
+     496          14 :     auto d=dynamic_cast<const std::exception*>(&e);
+     497          14 :     if(d) f(*d);
+     498         238 :   } catch(const std::exception &e) {
+     499             :     // If not nested, we end recursion
+     500         119 :     f(e);
+     501           0 :   } catch(const std::string &e) {
+     502             :     // If not nested, we end recursion
+     503           0 :     f(e);
+     504           2 :   } catch(const char* e) {
+     505             :     // If not nested, we end recursion
+     506           1 :     f(e);
+     507           0 :   } catch(...) {
+     508             :     // If not nested and of unknown type, we stop the chain
+     509             :   }
+     510         134 : }
+     511             : 
+     512             : }
+     513             : 
+     514         120 : std::string Tools::concatenateExceptionMessages() {
+     515             :   std::string msg;
+     516         120 :   process_all_exceptions(process_one_exception(msg));
+     517         120 :   return msg;
+     518             : }
+     519             : 
+     520             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func-sort-c.html b/coverage/tools/Tools.h.func-sort-c.html new file mode 100644 index 0000000000..218e98680c --- /dev/null +++ b/coverage/tools/Tools.h.func-sort-c.html @@ -0,0 +1,1808 @@ + + + + + + + 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:769282.6 %
Date:2024-05-27 13:05:14Functions:39943491.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_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EEbRbRKNS_3PbcERNS_12CommunicatorEEEENS0_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
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIxNSt7__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_14membranefusion10memFusionPEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_14membranefusion20fusionPoreExpansionPEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_14membranefusion21fusionPoreNucleationPEJRKNS_13ActionOptionsEEEENS0_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
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_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_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_6colvar7ExtraCVEJRKNS_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_8function7pytorch12PytorchModelEJRKNS_13ActionOptionsEEEENS0_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_7cltools7GenJsonEJRKNS_13CLToolOptionsEEEENS0_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_3piv3PIV10SharedDataEJEEENS0_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_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_bbRbRKNS_3PbcERNS_12CommunicatorERdRiEEENS0_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_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_15crystallization21EnvironmentSimilarityEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10
_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_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_4opes9OPESmetadINS2_11convergenceEEEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11make_uniqueINS_6colvar7PathMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_14
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEyEEvRKT_RT0_14
_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
_ZN4PLMD5Tools11make_uniqueINS_3ves9BF_PowersEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools11make_uniqueINS_3ves9TD_CustomEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESI_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_16
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEExEEvRKT_RT0_16
_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
_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_4isdb4EMMIEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_20
_ZN4PLMD5Tools11make_uniqueINS_5setup5UnitsEJRKNS_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_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EEbRbRKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_ZN4PLMD5Tools11make_uniqueINS_4isdb4SAXSEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_ZN4PLMD5Tools11make_uniqueINS_7generic10DumpForcesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_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_8function5StatsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_31
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi31
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase8MoreThanEJRKNS2_13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_32
_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_8analysis9HistogramEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_34
_ZN4PLMD5Tools11make_uniqueINS_10SimpleRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_35
_ZN4PLMD5Tools11make_uniqueINS_3ves9FesWeightEJRKdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_4GridEJRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IS8_SaIS8_EESJ_RSA_IjSaIjEERbbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_7generic14WholeMoleculesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_36
_ZN4PLMD5Tools11make_uniqueINS_9gridtools15HistogramOnGridEJRNS_10vesselbase13VesselOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_37
_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_4bias7PBMetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_41
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_RbS8_S8_RKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_43
_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_54
_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_3ves10TD_UniformEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_73
_ZN4PLMD5Tools11make_uniqueINS_3ves19Opt_BachAveragedSGDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_75
_ZN4PLMD5Tools11make_uniqueINS_6colvar4RMSDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_78
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsMatrixEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE82
_ZN4PLMD5Tools11make_uniqueINS_10vesselbase4MeanEJRKNS2_13VesselOptionsEEEENS0_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_14GenericMolInfoEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_87
_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_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
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools11make_uniqueINS_3ves24OutputTargetDistributionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_120
_ZN4PLMD5Tools11make_uniqueINS_7generic5GroupEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_132
_ZN4PLMD5Tools11make_uniqueINS_8function7CombineEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_137
_ZN4PLMD5Tools11make_uniqueINS_4bias5MetaDEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_157
_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_7generic9DumpAtomsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_173
_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_263
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpDerivativesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_282
_ZN4PLMD5Tools11make_uniqueINS_7cltools6ManualEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_297
_ZN4PLMD5Tools11make_uniqueINS_5IFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_348
_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_434
_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_466
_ZN4PLMD5Tools11make_uniqueINS_3ves12CoeffsVectorEJRS3_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_487
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi520
_ZN4PLMD5Tools11make_uniqueINS_6colvar7TorsionEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_657
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_800
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIdEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_808
_ZN4PLMD5Tools11make_uniqueINS_7generic5PrintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_820
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_946
_ZN4PLMD5Tools11make_uniqueINS_5OFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_975
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RA19_KcRA9_S7_RdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1092
_ZN4PLMD5Tools11make_uniqueINS_7cltools4InfoEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1857
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2401
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2439
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2439
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2576
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i4003
_ZN4PLMD5Tools11make_uniqueINS_10CLToolMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4217
_ZN4PLMD5Tools11make_uniqueINS_15KernelFunctionsEJRSt6vectorIdSaIdEES6_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERA13_KcRdEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4412
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5466
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools11make_uniqueINS_5vatom6CenterEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7163
_ZN4PLMD5Tools11make_uniqueINS_13SubprocessPidEJRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10002
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12552
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE13462
_ZN4PLMD5Tools11make_uniqueISt10lock_guardISt5mutexEJRS3_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18842
_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_EEi22298
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i26901
_ZN4PLMD5Tools18mergeSortedVectorsIKSt6vectorINS_10AtomNumberESaIS3_EEEEvRKS2_IPT_SaIS8_EERS2_INS7_10value_typeESaISD_EEb27123
_ZN4PLMDL18dp2cutoffNoStretchEv30397
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33481
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i35215
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb43084
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE90725
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_90725
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE218589
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE416075
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_416075
_ZN4PLMD5Tools11make_uniqueINS_17EuclideanDistanceEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_518364
_ZN4PLMD5Tools11make_uniqueINS_12MDAtomsTypedIdEEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_806144
_ZN4PLMD5Tools11make_uniqueINS_23DataFetchingObjectTypedIdEEJRNS_10PlumedMainEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_806144
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219435
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_3560198
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11881695
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE13702951
_ZN4PLMD5Tools7fastpowEdi79175830
_ZN4PLMD5Tools3pbcEd1826108571
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func.html b/coverage/tools/Tools.h.func.html new file mode 100644 index 0000000000..4e387f67b8 --- /dev/null +++ b/coverage/tools/Tools.h.func.html @@ -0,0 +1,1808 @@ + + + + + + + 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:769282.6 %
Date:2024-05-27 13:05:14Functions:39943491.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_uniqueINS_10CLToolMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4217
_ZN4PLMD5Tools11make_uniqueINS_10PlumedMainEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_102
_ZN4PLMD5Tools11make_uniqueINS_10SimpleRMSDEJRKNS_29ReferenceConfigurationOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_35
_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_84
_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_32
_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_806144
_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_43
_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_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EES7_bbRbRKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_8
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EEbRbRKNS_3PbcERNS_12CommunicatorEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_12NeighborListEJRSt6vectorINS_10AtomNumberESaIS4_EEbRbRKNS_3PbcERNS_12CommunicatorERdRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_28
_ZN4PLMD5Tools11make_uniqueINS_13SubprocessPidEJRiEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_10002
_ZN4PLMD5Tools11make_uniqueINS_14GenericMolInfoEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_87
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6LWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_0
_ZN4PLMD5Tools11make_uniqueINS_14manyrestraints6UWallsEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_2
_ZN4PLMD5Tools11make_uniqueINS_14membranefusion10memFusionPEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_14membranefusion20fusionPoreExpansionPEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_ZN4PLMD5Tools11make_uniqueINS_14membranefusion21fusionPoreNucleationPEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_1
_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_10
_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_806144
_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_3piv3PIV10SharedDataEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_6
_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_36
_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_16
_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_157
_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_41
_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_28
_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_348
_ZN4PLMD5Tools11make_uniqueINS_5OFileEJEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_975
_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_2401
_ZN4PLMD5Tools11make_uniqueINS_5ValueEJPNS_15ActionWithValueERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_33481
_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_20
_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_7163
_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_78
_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_54
_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_3
_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_657
_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_466
_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_1857
_ZN4PLMD5Tools11make_uniqueINS_7cltools5PesMDEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_7
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIdEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_808
_ZN4PLMD5Tools11make_uniqueINS_7cltools6DriverIfEEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_ZN4PLMD5Tools11make_uniqueINS_7cltools6ManualEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_297
_ZN4PLMD5Tools11make_uniqueINS_7cltools7GenJsonEJRKNS_13CLToolOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_5
_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_36
_ZN4PLMD5Tools11make_uniqueINS_7generic15DumpDerivativesEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_282
_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_132
_ZN4PLMD5Tools11make_uniqueINS_7generic5PrintEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_820
_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_173
_ZN4PLMD5Tools11make_uniqueINS_7generic9EndPlumedEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_263
_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_434
_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_8function7pytorch12PytorchModelEJRKNS_13ActionOptionsEEEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_4
_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
_ZN4PLMD5Tools11make_uniqueISt10lock_guardISt5mutexEJRS3_EEENS0_10_Unique_ifIT_E14_Single_objectEDpOT0_18842
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi22298
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12552
_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_EEi520
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE218589
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20864
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE416075
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE90725
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2439
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE13462
_ZN4PLMD5Tools18mergeSortedVectorsIKSt6vectorINS_10AtomNumberESaIS3_EEEEvRKS2_IPT_SaIS8_EERS2_INS7_10value_typeESaISD_EEb27123
_ZN4PLMD5Tools3pbcEd1826108571
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i35215
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i26901
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i5466
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i4003
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2576
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11881695
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219435
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_946
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEExEEvRKT_RT0_16
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEyEEvRKT_RT0_14
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_800
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_20864
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_416075
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_90725
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2439
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7fastpowEdi79175830
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb43084
_ZN4PLMDL18dp2cutoffNoStretchEv30397
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.gcov.html b/coverage/tools/Tools.h.gcov.html new file mode 100644 index 0000000000..d9d669da14 --- /dev/null +++ b/coverage/tools/Tools.h.gcov.html @@ -0,0 +1,542 @@ + + + + + + + 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:769282.6 %
Date:2024-05-27 13:05:14Functions:39943491.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.h"
+      27             : #include "Tensor.h"
+      28             : #include <vector>
+      29             : #include <string>
+      30             : #include <cctype>
+      31             : #include <cstdio>
+      32             : #include <cmath>
+      33             : #include <limits>
+      34             : #include <algorithm>
+      35             : #include <sstream>
+      36             : #include <memory>
+      37             : #include <cstddef>
+      38             : #include <queue>
+      39             : #include <mutex>
+      40             : 
+      41             : namespace PLMD {
+      42             : 
+      43             : class IFile;
+      44             : 
+      45             : /// \ingroup TOOLBOX
+      46             : /// Very small non-zero number
+      47             : const double epsilon(std::numeric_limits<double>::epsilon());
+      48             : 
+      49             : /// \ingroup TOOLBOX
+      50             : /// Boltzman constant in kj/K
+      51             : const double kBoltzmann(0.0083144621);
+      52             : 
+      53             : /// \ingroup TOOLBOX
+      54             : /// PI
+      55             : const double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
+      56             : 
+      57             : const double dp2cutoff(6.25);
+      58             : 
+      59             : const double dp2cutoffA=1.00193418799744762399; // 1.0/(1-std::exp(-dp2cutoff));
+      60             : const double dp2cutoffB=-.00193418799744762399; // -std::exp(-dp2cutoff)/(1-std::exp(-dp2cutoff));
+      61             : 
+      62       30397 : inline static bool dp2cutoffNoStretch() {
+      63       30397 :   static const auto* res=std::getenv("PLUMED_DP2CUTOFF_NOSTRETCH");
+      64       30397 :   return res;
+      65             : }
+      66             : 
+      67             : /// \ingroup TOOLBOX
+      68             : /// Empty class which just contains several (static) tools
+      69             : class Tools {
+      70             : /// class to convert a string to a generic type T
+      71             :   template<class T>
+      72             :   static bool convertToAny(const std::string & str,T &t);
+      73             : /// class to convert a string to a real type T.
+      74             : /// T should be either float, double, or long double
+      75             :   template<class T>
+      76             :   static bool convertToReal(const std::string & str,T &t);
+      77             : /// class to convert a string to a int type T
+      78             :   template<class T>
+      79             :   static bool convertToInt(const std::string & str,T &t);
+      80             : public:
+      81             : /// Split the line in words using separators.
+      82             : /// It also take into account parenthesis. Outer parenthesis found are removed from
+      83             : /// output, and the text between them is considered as a single word. Only the
+      84             : /// outer parenthesis are processed, to allow nesting them.
+      85             : /// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
+      86             :   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);
+      87             : /// Get a line from the file pointer ifile
+      88             :   static bool getline(FILE*,std::string & line);
+      89             : /// Get a parsed line from the file pointer ifile
+      90             : /// This function already takes care of joining continued lines and splitting the
+      91             : /// resulting line into an array of words
+      92             :   static bool getParsedLine(IFile&ifile,std::vector<std::string> & line, const bool trimcomments=true);
+      93             : /// compare two string in a case insensitive manner
+      94             :   static bool caseInSensStringCompare(const std::string & str1, const std::string &str2);
+      95             : /// Convert a string to a double, reading it
+      96             :   static bool convertNoexcept(const std::string & str,double & t);
+      97             : /// Convert a string to a long double, reading it
+      98             :   static bool convertNoexcept(const std::string & str,long double & t);
+      99             : /// Convert a string to a float, reading it
+     100             :   static bool convertNoexcept(const std::string & str,float & t);
+     101             : /// Convert a string to a int, reading it
+     102             :   static bool convertNoexcept(const std::string & str,int & t);
+     103             : /// Convert a string to a long int, reading it
+     104             :   static bool convertNoexcept(const std::string & str,long int & t);
+     105             : /// Convert a string to a long long int, reading it
+     106             :   static bool convertNoexcept(const std::string & str,long long int & t);
+     107             : /// Convert a string to an unsigned int, reading it
+     108             :   static bool convertNoexcept(const std::string & str,unsigned & t);
+     109             : /// Convert a string to a long unsigned int, reading it
+     110             :   static bool convertNoexcept(const std::string & str,long unsigned & t);
+     111             : /// Convert a string to a long long unsigned int, reading it
+     112             :   static bool convertNoexcept(const std::string & str,long long unsigned & t);
+     113             : /// Convert a string to a atom number, reading it
+     114             :   static bool convertNoexcept(const std::string & str,AtomNumber & t);
+     115             : /// Convert a string to a string (i.e. copy)
+     116             :   static bool convertNoexcept(const std::string & str,std::string & t);
+     117             : /// Convert anything into a string
+     118             :   template<typename T>
+     119             :   static bool convertNoexcept(T i,std::string & str);
+     120             : /// Convert anything into anything, throwing an exception in case there is an error
+     121             : /// Remove trailing blanks
+     122             :   static void trim(std::string & s);
+     123             : /// Remove trailing comments
+     124             :   static void trimComments(std::string & s);
+     125             : /// Apply pbc for a unitary cell
+     126             :   static double pbc(double);
+     127             : /// Retrieve a key from a vector of options.
+     128             : /// It finds a key starting with "key=" or equal to "key" and copy the
+     129             : /// part after the = on s. E.g.:
+     130             : /// line.push_back("aa=xx");
+     131             : /// getKey(line,"aa",s);
+     132             : /// will set s="xx"
+     133             :   static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep=-1);
+     134             : /// Find a keyword on the input line, eventually deleting it, and saving its value to val
+     135             :   template <typename T,typename U>
+     136    14641347 :   static void convert(const T & t,U & u) {
+     137    14642148 :     plumed_assert(convertNoexcept(t,u)) <<"Error converting  "<<t;
+     138    14641346 :   }
+     139             :   template <typename T>
+     140             :   static bool parse(std::vector<std::string>&line,const std::string&key,T&val,int rep=-1);
+     141             : /// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
+     142             :   template <class T>
+     143             :   static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep=-1);
+     144             : /// Find a keyword without arguments on the input line
+     145             :   static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
+     146             : /// Find a keyword on the input line, just reporting if it exists or not
+     147             :   static bool findKeyword(const std::vector<std::string>&line,const std::string&key);
+     148             : /// Interpret atom ranges
+     149             :   static void interpretRanges(std::vector<std::string>&);
+     150             : /// Remove duplicates from a vector of type T
+     151             :   template <typename T>
+     152             :   static void removeDuplicates(std::vector<T>& vec);
+     153             : /// interpret ":" syntax for labels
+     154             :   static void interpretLabel(std::vector<std::string>&s);
+     155             : /// list files in a directory
+     156             :   static std::vector<std::string> ls(const std::string&);
+     157             : /// removes leading and trailing blanks from a string
+     158             :   static void stripLeadingAndTrailingBlanks( std::string& str );
+     159             : /// Extract the extensions from a file name.
+     160             : /// E.g.: extension("pippo.xyz")="xyz".
+     161             : /// It only returns extensions with a length between 1 and 4
+     162             : /// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
+     163             : /// It is also smart enough to detect "/", so that
+     164             : /// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
+     165             :   static std::string extension(const std::string&);
+     166             : /// Fast int power
+     167             :   static double fastpow(double base,int exp);
+     168             : /// Modified 0th-order Bessel function of the first kind
+     169             :   static double bessel0(const double& val);
+     170             : /// Check if a string full starts with string start.
+     171             : /// Same as full.find(start)==0
+     172             :   static bool startWith(const std::string & full,const std::string &start);
+     173             :   /**
+     174             :     Tool to create a vector of raw pointers from a vector of unique_pointers (const version).
+     175             :   Returning a vector is fast in C++11. It can be used in order to feed a vector<unique_ptr<T>>
+     176             :   to a function that takes a vector<T*>.
+     177             :   \verbatim
+     178             :   // some function that takes a vec
+     179             :   void func(std::vector<Data*> & vec);
+     180             :   std::vector<std::unique_ptr<Data>> vec;
+     181             :   // func(vec); // does not compile
+     182             :   func(Tools::unique2raw(vec)); // compiles
+     183             :   \endverbatim
+     184             :   Notice that the conversion is fast but takes
+     185             :   some time to allocate the new vector and copy the pointers. In case the function
+     186             :   acting on the vector<T*> is very fast and we do not want to add significant overhead,
+     187             :   it might be convenient to store a separate set of raw pointers.
+     188             :   \verbatim
+     189             :   // some function that takes a vec
+     190             :   void func(std::vector<Data*> & vec);
+     191             :   std::vector<std::unique_ptr<Data>> vec;
+     192             : 
+     193             :   // conversion done only once:
+     194             :   auto vec_ptr=Tools::unique2raw(vec);
+     195             : 
+     196             :   for(int i=0;i<1000;i++){
+     197             :     func(vec_ptr);
+     198             :   }
+     199             :   \endverbatim
+     200             :   */
+     201             :   template <typename T>
+     202             :   static std::vector<T*> unique2raw(const std::vector<std::unique_ptr<T>>&);
+     203             : /// Tool to create a vector of raw pointers from a vector of unique_pointers.
+     204             : /// See the non const version.
+     205             :   template <typename T>
+     206             :   static std::vector<const T*> unique2raw(const std::vector<std::unique_ptr<const T>>&);
+     207             : /// Tiny class that changes directory and comes back when going out of scope.
+     208             : /// In case system calls to change dir are not available it throws an exception.
+     209             : /// \warning By construction, changing directory breaks thread safety! Use with care.
+     210             :   class DirectoryChanger {
+     211             :     static const std::size_t buffersize=4096;
+     212             :     char cwd[buffersize]= {0};
+     213             :   public:
+     214             :     explicit DirectoryChanger(const char*path);
+     215             :     ~DirectoryChanger();
+     216             :   };
+     217             : /// Mimic C++14 std::make_unique
+     218             :   template<class T> struct _Unique_if {
+     219             :     typedef std::unique_ptr<T> _Single_object;
+     220             :   };
+     221             :   template<class T> struct _Unique_if<T[]> {
+     222             :     typedef std::unique_ptr<T[]> _Unknown_bound;
+     223             :   };
+     224             :   template<class T, std::size_t N> struct _Unique_if<T[N]> {
+     225             :     typedef void _Known_bound;
+     226             :   };
+     227             :   template<class T, class... Args>
+     228             :   static typename _Unique_if<T>::_Single_object
+     229     5810122 :   make_unique(Args&&... args) {
+     230     9423218 :     return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+     231             :   }
+     232             :   template<class T>
+     233             :   static typename _Unique_if<T>::_Unknown_bound
+     234         189 :   make_unique(std::size_t n) {
+     235             :     typedef typename std::remove_extent<T>::type U;
+     236        9473 :     return std::unique_ptr<T>(new U[n]());
+     237             :   }
+     238             :   template<class T, class... Args>
+     239             :   static typename _Unique_if<T>::_Known_bound
+     240             :   make_unique(Args&&...) = delete;
+     241             : 
+     242             :   static void set_to_zero(double*ptr,unsigned n) {
+     243    22309121 :     for(unsigned i=0; i<n; i++) ptr[i]=0.0;
+     244             :   }
+     245             : 
+     246             :   template<unsigned n>
+     247      218589 :   static void set_to_zero(std::vector<VectorGeneric<n>> & vec) {
+     248      218589 :     unsigned s=vec.size();
+     249      218589 :     if(s==0) return;
+     250      196256 :     set_to_zero(&vec[0][0],s*n);
+     251             :   }
+     252             : 
+     253             :   template<unsigned n,unsigned m>
+     254             :   static void set_to_zero(std::vector<TensorGeneric<n,m>> & vec) {
+     255             :     unsigned s=vec.size();
+     256             :     if(s==0) return;
+     257             :     set_to_zero(&vec[0](0,0),s*n*m);
+     258             :   }
+     259             : 
+     260             : 
+     261             : 
+     262             : 
+     263             :   /// Merge sorted vectors.
+     264             :   /// Takes a vector of pointers to containers and merge them.
+     265             :   /// Containers should be already sorted.
+     266             :   /// The content is appended to the result vector.
+     267             :   /// Optionally, uses a priority_queue implementation.
+     268             :   template<class C>
+     269       27123 :   static void mergeSortedVectors(const std::vector<C*> & vecs, std::vector<typename C::value_type> & result,bool priority_queue=false) {
+     270             : 
+     271             :     /// local class storing the range of remaining objects to be pushed
+     272             :     struct Entry
+     273             :     {
+     274             :       typename C::const_iterator fwdIt,endIt;
+     275             : 
+     276       52989 :       explicit Entry(C const& v) : fwdIt(v.begin()), endIt(v.end()) {}
+     277             :       /// check if this vector still contains something to be pushed
+     278             :       explicit operator bool () const { return fwdIt != endIt; }
+     279             :       /// to allow using a priority_queu, which selects the highest element.
+     280             :       /// we here (counterintuitively) define < as >
+     281             :       bool operator< (Entry const& rhs) const { return *fwdIt > *rhs.fwdIt; }
+     282             :     };
+     283             : 
+     284       27123 :     if(priority_queue) {
+     285             :       std::priority_queue<Entry> queue;
+     286             :       // note: queue does not have reserve() method
+     287             : 
+     288             :       // add vectors to the queue
+     289             :       {
+     290             :         std::size_t maxsize=0;
+     291           0 :         for(unsigned i=0; i<vecs.size(); i++) {
+     292           0 :           if(vecs[i]->size()>maxsize) maxsize=vecs[i]->size();
+     293           0 :           if(!vecs[i]->empty())queue.push(Entry(*vecs[i]));
+     294             :         }
+     295             :         // this is just to save multiple reallocations on push_back
+     296           0 :         result.reserve(maxsize);
+     297             :       }
+     298             : 
+     299             :       // first iteration (to avoid a if in the main loop)
+     300           0 :       if(queue.empty()) return;
+     301           0 :       auto tmp=queue.top();
+     302           0 :       queue.pop();
+     303           0 :       result.push_back(*tmp.fwdIt);
+     304             :       tmp.fwdIt++;
+     305           0 :       if(tmp) queue.push(tmp);
+     306             : 
+     307             :       // main loop
+     308           0 :       while(!queue.empty()) {
+     309           0 :         auto tmp=queue.top();
+     310           0 :         queue.pop();
+     311           0 :         if(result.back() < *tmp.fwdIt) result.push_back(*tmp.fwdIt);
+     312             :         tmp.fwdIt++;
+     313           0 :         if(tmp) queue.push(tmp);
+     314             :       }
+     315             :     } else {
+     316             : 
+     317             :       std::vector<Entry> entries;
+     318       27123 :       entries.reserve(vecs.size());
+     319             : 
+     320             :       {
+     321             :         std::size_t maxsize=0;
+     322       82853 :         for(int i=0; i<vecs.size(); i++) {
+     323       55730 :           if(vecs[i]->size()>maxsize) maxsize=vecs[i]->size();
+     324      108719 :           if(!vecs[i]->empty())entries.push_back(Entry(*vecs[i]));
+     325             :         }
+     326             :         // this is just to save multiple reallocations on push_back
+     327       27123 :         result.reserve(maxsize);
+     328             :       }
+     329             : 
+     330      401812 :       while(!entries.empty()) {
+     331             :         // find smallest pending element
+     332             :         // we use max_element instead of min_element because we are defining < as > (see above)
+     333      374689 :         const auto minval=*std::max_element(entries.begin(),entries.end())->fwdIt;
+     334             : 
+     335             :         // push it
+     336      374689 :         result.push_back(minval);
+     337             : 
+     338             :         // fast forward vectors with elements equal to minval (to avoid duplicates)
+     339     2150654 :         for(auto & e : entries) while(e && *e.fwdIt==minval) ++e.fwdIt;
+     340             : 
+     341             :         // remove from the entries vector all exhausted vectors
+     342      374689 :         auto erase=std::remove_if(entries.begin(),entries.end(),[](const Entry & e) {return !e;});
+     343             :         entries.erase(erase,entries.end());
+     344             :       }
+     345             :     }
+     346             : 
+     347             :   }
+     348             :   static std::unique_ptr<std::lock_guard<std::mutex>> molfile_lock();
+     349             :   /// Build a concatenated exception message.
+     350             :   /// Should be called with an in-flight exception.
+     351             :   static std::string concatenateExceptionMessages();
+     352             : };
+     353             : 
+     354             : template <class T>
+     355       71710 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
+     356             :   std::string s;
+     357      143420 :   if(!getKey(line,key+"=",s,rep)) return false;
+     358       28567 :   if(s.length()>0 && !convertNoexcept(s,val))return false;
+     359             :   return true;
+     360             : }
+     361             : 
+     362             : template <class T>
+     363       35447 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
+     364             :   std::string s;
+     365       70894 :   if(!getKey(line,key+"=",s,rep)) return false;
+     366             :   val.clear();
+     367       26174 :   std::vector<std::string> words=getWords(s,"\t\n ,");
+     368      113682 :   for(unsigned i=0; i<words.size(); ++i) {
+     369             :     T v;
+     370       87508 :     std::string s=words[i];
+     371       87508 :     const std::string multi("@replicas:");
+     372       87508 :     if(rep>=0 && startWith(s,multi)) {
+     373           6 :       s=s.substr(multi.length(),s.length());
+     374           6 :       std::vector<std::string> words=getWords(s,"\t\n ,");
+     375           6 :       plumed_assert(rep<static_cast<int>(words.size()));
+     376           6 :       s=words[rep];
+     377           6 :     }
+     378       87508 :     if(!convertNoexcept(s,v))return false;
+     379       87508 :     val.push_back(v);
+     380             :   }
+     381             :   return true;
+     382       26174 : }
+     383             : 
+     384             : template<typename T>
+     385       13462 : void Tools::removeDuplicates(std::vector<T>& vec)
+     386             : {
+     387       13462 :   std::sort(vec.begin(), vec.end());
+     388       13462 :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+     389       13462 : }
+     390             : 
+     391             : inline
+     392       43084 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
+     393      106891 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     394       65332 :     if(key==*p) {
+     395        1525 :       val=true;
+     396             :       line.erase(p);
+     397             :       return true;
+     398             :     }
+     399             :   }
+     400             :   return false;
+     401             : }
+     402             : 
+     403             : /// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
+     404             : inline
+     405  1826108571 : double Tools::pbc(double x) {
+     406             : #ifdef __PLUMED_PBC_WHILE
+     407             :   while (x>0.5) x-=1.0;
+     408             :   while (x<-0.5) x+=1.0;
+     409             :   return x;
+     410             : #else
+     411             :   if(std::numeric_limits<int>::round_style == std::round_toward_zero) {
+     412             :     const double offset=100.0;
+     413  1826108571 :     const double y=x+offset;
+     414  1826108571 :     if(y>=0) return y-int(y+0.5);
+     415        4577 :     else     return y-int(y-0.5);
+     416             :   } else if(std::numeric_limits<int>::round_style == std::round_to_nearest) {
+     417             :     return x-int(x);
+     418             :   } else return x-floor(x+0.5);
+     419             : #endif
+     420             : }
+     421             : 
+     422             : template<typename T>
+     423      530103 : bool Tools::convertNoexcept(T i,std::string & str) {
+     424      530103 :   std::ostringstream ostr;
+     425      416075 :   ostr<<i;
+     426      530103 :   str=ostr.str();
+     427      530103 :   return true;
+     428      530103 : }
+     429             : 
+     430             : inline
+     431    79175830 : double Tools::fastpow(double base, int exp)
+     432             : {
+     433    79175830 :   if(exp<0) {
+     434           0 :     exp=-exp;
+     435           0 :     base=1.0/base;
+     436             :   }
+     437             :   double result = 1.0;
+     438   375015129 :   while (exp)
+     439             :   {
+     440   262239105 :     if (exp & 1)
+     441   181137476 :       result *= base;
+     442   262239105 :     exp >>= 1;
+     443   262239105 :     base *= base;
+     444             :   }
+     445             : 
+     446    79175830 :   return result;
+     447             : }
+     448             : 
+     449             : template<typename T>
+     450    13703470 : std::vector<T*> Tools::unique2raw(const std::vector<std::unique_ptr<T>> & x) {
+     451    13703470 :   std::vector<T*> v(x.size());
+     452    52721172 :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     453    13703470 :   return v;
+     454             : }
+     455             : 
+     456             : template<typename T>
+     457             : std::vector<const T*> Tools::unique2raw(const std::vector<std::unique_ptr<const T>> & x) {
+     458             :   std::vector<const T*> v(x.size());
+     459             :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     460             :   return v;
+     461             : }
+     462             : 
+     463             : }
+     464             : 
+     465             : #endif
+     466             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func-sort-c.html b/coverage/tools/Torsion.cpp.func-sort-c.html new file mode 100644 index 0000000000..77cb31c847 --- /dev/null +++ b/coverage/tools/Torsion.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084725
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func.html b/coverage/tools/Torsion.cpp.func.html new file mode 100644 index 0000000000..023e102f3a --- /dev/null +++ b/coverage/tools/Torsion.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084725
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.gcov.html b/coverage/tools/Torsion.cpp.gcov.html new file mode 100644 index 0000000000..152d465a47 --- /dev/null +++ b/coverage/tools/Torsion.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05: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     1084725 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3,Vector& d1,Vector& d2,Vector& d3)const {
+      40             : 
+      41     1084725 :   const double modv2(1./v2.modulo());
+      42     1084725 :   const Vector nv2(v2*modv2);
+      43     1084725 :   const Tensor dnv2_v2((Tensor::identity()-extProduct(nv2,nv2))*modv2);
+      44             : 
+      45     1084725 :   const Vector a(crossProduct(v2,v1));
+      46     1084725 :   const Tensor da_dv2(dcrossDv1(v2,v1));
+      47     1084725 :   const Tensor da_dv1(dcrossDv2(v2,v1));
+      48     1084725 :   const Vector b(crossProduct(v3,v2));
+      49     1084725 :   const Tensor db_dv3(dcrossDv1(v3,v2));
+      50     1084725 :   const Tensor db_dv2(dcrossDv2(v3,v2));
+      51     1084725 :   const double cosangle=dotProduct(a,b);
+      52     1084725 :   const Vector dcosangle_dv1=matmul(b,da_dv1);
+      53     1084725 :   const Vector dcosangle_dv2=matmul(b,da_dv2) + matmul(a,db_dv2);
+      54     1084725 :   const Vector dcosangle_dv3=matmul(a,db_dv3);
+      55             : 
+      56     1084725 :   const Vector cab(crossProduct(a,b));
+      57     1084725 :   const Tensor dcab_dv1(matmul(dcrossDv1(a,b),da_dv1));
+      58     1084725 :   const Tensor dcab_dv2(matmul(dcrossDv1(a,b),da_dv2) + matmul(dcrossDv2(a,b),db_dv2));
+      59     1084725 :   const Tensor dcab_dv3(matmul(dcrossDv2(a,b),db_dv3));
+      60             : 
+      61     1084725 :   const double sinangle=dotProduct(cab,nv2);
+      62     1084725 :   const Vector dsinangle_dv1=matmul(nv2,dcab_dv1);
+      63     1084725 :   const Vector dsinangle_dv2=matmul(nv2,dcab_dv2)+matmul(cab,dnv2_v2);
+      64     1084725 :   const Vector dsinangle_dv3=matmul(nv2,dcab_dv3);
+      65             : 
+      66     1084725 :   const double torsion=std::atan2(-sinangle,cosangle);
+      67             : // this is required since v1 and v3 are not normalized:
+      68     1084725 :   const double invR2=1.0/(cosangle*cosangle+sinangle*sinangle);
+      69             : 
+      70     1084725 :   d1= ( -dsinangle_dv1*cosangle + sinangle * dcosangle_dv1 ) *invR2;
+      71     1084725 :   d2= ( -dsinangle_dv2*cosangle + sinangle * dcosangle_dv2 ) *invR2;
+      72     1084725 :   d3= ( -dsinangle_dv3*cosangle + sinangle * dcosangle_dv3 ) *invR2;
+      73             : 
+      74     1084725 :   return torsion;
+      75             : }
+      76             : 
+      77             : }
+      78             : 
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.func-sort-c.html b/coverage/tools/Tree.cpp.func-sort-c.html new file mode 100644 index 0000000000..7c4c179383 --- /dev/null +++ b/coverage/tools/Tree.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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:3737100.0 %
Date:2024-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE2
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE2
_ZNK4PLMD4Tree7getRootEv2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.func.html b/coverage/tools/Tree.cpp.func.html new file mode 100644 index 0000000000..1160b78185 --- /dev/null +++ b/coverage/tools/Tree.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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:3737100.0 %
Date:2024-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE2
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE2
_ZNK4PLMD4Tree7getRootEv2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.gcov.html b/coverage/tools/Tree.cpp.gcov.html new file mode 100644 index 0000000000..38ec41e372 --- /dev/null +++ b/coverage/tools/Tree.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + 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:3737100.0 %
Date:2024-05-27 13:05:14Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2021-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Tree.h"
+      24             : #include "Tools.h"
+      25             : #include "Vector.h"
+      26             : #include "AtomNumber.h"
+      27             : #include "core/GenericMolInfo.h"
+      28             : #include <vector>
+      29             : #include <limits>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33           2 : Tree::Tree(GenericMolInfo* moldat) {
+      34             : // initialize class
+      35           2 :   moldat_ = moldat;
+      36             : // check if molinfo present
+      37           2 :   if(!moldat_) plumed_merror("MOLINFO DATA not found");
+      38             : // check if reference structure is whole
+      39           2 :   if(!moldat_->isWhole()) plumed_merror("Check that reference structure in PDB file is not broken by pbc and set WHOLE in MOLINFO line");
+      40           2 : }
+      41             : 
+      42           2 : 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           2 :   root_.clear();
+      51             : 
+      52             :   // remove atoms not in PDB file
+      53             :   std::vector<AtomNumber> addtotree, addtoroot;
+      54             :   std::vector<AtomNumber> newatoms;
+      55           2 :   newatoms.reserve(atoms.size());
+      56           2 :   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           2 :   newatoms.push_back(atoms[0]);
+      59         245 :   for(unsigned i=1; i<atoms.size(); ++i) {
+      60         243 :     if(!moldat_->checkForAtom(atoms[i])) {
+      61             :       // store this atom for later
+      62          61 :       addtotree.push_back(atoms[i]);
+      63             :       // along with its root (the previous atom)
+      64          61 :       addtoroot.push_back(atoms[i-1]);
+      65             :     } else {
+      66         182 :       newatoms.push_back(atoms[i]);
+      67             :     }
+      68             :   }
+      69             :   // reassign atoms
+      70           2 :   atoms=newatoms;
+      71             :   // start EMST
+      72           2 :   std::vector<bool> intree(atoms.size(), false);
+      73           2 :   std::vector<double> mindist(atoms.size(), std::numeric_limits<double>::max());
+      74             :   // initialize tree with first atom
+      75           2 :   mindist[0] = 0.0;
+      76             :   // loops
+      77         186 :   for(unsigned i=0; i<atoms.size(); ++i) {
+      78             :     int selected_vertex = -1;
+      79       19034 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      80       18850 :       if( !intree[j] && (selected_vertex==-1 || mindist[j] < mindist[selected_vertex]) )
+      81        1078 :         selected_vertex = j;
+      82             :     }
+      83             :     // add to tree
+      84         184 :     plumed_assert(selected_vertex>=0);
+      85         184 :     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       19034 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      91       18850 :       double dist = delta(moldat_->getPosition(atoms[selected_vertex]), moldat_->getPosition(atoms[j])).modulo2();
+      92       18850 :       if(dist < mindist[j]) mindist[j] = dist;
+      93       22401 :       if(dist < minroot && intree[j] && dist>0.0) {
+      94             :         minroot = dist;
+      95        2822 :         iroot = j;
+      96             :       }
+      97             :     }
+      98             :     // add to root vector
+      99         184 :     if(iroot>=0) root_.push_back(atoms[iroot]);
+     100             :   }
+     101             : 
+     102             :   // now re-add atoms not present in the PDB
+     103          63 :   for(unsigned i=0; i<addtotree.size(); ++i) {
+     104          61 :     tree.push_back(addtotree[i]);
+     105          61 :     root_.push_back(addtoroot[i]);
+     106             :   }
+     107             : 
+     108             :   // return
+     109           2 :   return tree;
+     110             : }
+     111             : 
+     112           2 : std::vector<AtomNumber> Tree::getRoot() const
+     113             : {
+     114           2 :   return root_;
+     115             : }
+     116             : 
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func-sort-c.html b/coverage/tools/Tree.h.func-sort-c.html new file mode 100644 index 0000000000..7be7b7fe66 --- /dev/null +++ b/coverage/tools/Tree.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func.html b/coverage/tools/Tree.h.func.html new file mode 100644 index 0000000000..d1e78f67e4 --- /dev/null +++ b/coverage/tools/Tree.h.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.gcov.html b/coverage/tools/Tree.h.gcov.html new file mode 100644 index 0000000000..bc22a3fd67 --- /dev/null +++ b/coverage/tools/Tree.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - tools/Tree.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-05-27 13:05: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           2 : class Tree
+      35             : {
+      36             : 
+      37             : private:
+      38             :   GenericMolInfo* moldat_;
+      39             :   std::vector<AtomNumber> root_;
+      40             : 
+      41             : public:
+      42             : /// constructor
+      43             :   explicit Tree(GenericMolInfo* moldat);
+      44             : /// build a tree
+      45             :   std::vector<AtomNumber> getTree(std::vector<AtomNumber> atoms);
+      46             : /// get root
+      47             :   std::vector<AtomNumber> getRoot() const;
+      48             : };
+      49             : 
+      50             : }
+      51             : 
+      52             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func-sort-c.html b/coverage/tools/TypesafePtr.cpp.func-sort-c.html new file mode 100644 index 0000000000..1044507bda --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZN4PLMD11TypesafePtr11fromSafePtrEPv14881
_ZNK4PLMD11TypesafePtr4copyEv564903
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func.html b/coverage/tools/TypesafePtr.cpp.func.html new file mode 100644 index 0000000000..d3970224f8 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr11fromSafePtrEPv14881
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZNK4PLMD11TypesafePtr4copyEv564903
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.gcov.html b/coverage/tools/TypesafePtr.cpp.gcov.html new file mode 100644 index 0000000000..b07618709e --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.gcov.html @@ -0,0 +1,133 @@ + + + + + + + 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-05-27 13:05: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       14881 : TypesafePtr TypesafePtr::fromSafePtr(void* safe) {
+      30             :   auto s=(plumed_safeptr_x*)safe;
+      31       14881 :   return TypesafePtr(const_cast<void*>(s->ptr), s->nelem, s->shape, s->flags);
+      32             : }
+      33             : 
+      34      564903 : TypesafePtr TypesafePtr::copy() const {
+      35      564903 :   auto passbyvalue=((flags>>25)&0x7)==1;
+      36      564903 :   if(passbyvalue) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object passed by value";
+      37      564903 :   auto forbidstore=flags&0x10000000;
+      38      564903 :   if(forbidstore) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object for which this was forbidden";
+      39             :   TypesafePtr ret;
+      40      564903 :   ret.ptr=ptr;
+      41      564903 :   ret.flags=flags;
+      42      564903 :   ret.nelem=nelem;
+      43      564903 :   ret.shape=shape;
+      44      564903 :   return ret;
+      45             : }
+      46             : 
+      47           8 : std::string TypesafePtr::extra_msg() {
+      48             :   const char *text = "\n"
+      49             :                      "If you are sure your code is correct you can disable this check with export PLUMED_TYPESAFE_IGNORE=yes\n"
+      50             :                      "In case this is necessary, please report an issue to developers of PLUMED and of the MD code\n"
+      51             :                      "See also https://github.com/plumed/plumed2/pull/653";
+      52           8 :   return std::string(text);
+      53             : }
+      54             : 
+      55             : }
+      56             : 
+      57             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func-sort-c.html b/coverage/tools/TypesafePtr.h.func-sort-c.html new file mode 100644 index 0000000000..3c08fc8b33 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func-sort-c.html @@ -0,0 +1,292 @@ + + + + + + + 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:11513187.8 %
Date:2024-05-27 13:05:14Functions:405572.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
_ZN4PLMD11TypesafePtrC2EOS0_64
_ZN4PLMD17typesafePtrSizeofIlEEmv64
_ZNK4PLMD11TypesafePtr3setIlEEvT_64
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb64
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb851
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1715
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2178
_ZNK4PLMD11TypesafePtr3setIdEEvT_3029
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb4133
_ZNK4PLMD11TypesafePtr3setIiEEvT_4548
_ZN4PLMD17typesafePtrSizeofIKcEEmv6236
_ZN4PLMD11TypesafePtrC2EimPKm8645
_ZN4PLMD11TypesafePtrC2EdmPKm8939
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv13300
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv14347
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb15335
_ZN4PLMD17typesafePtrSizeofIKiEEmv15377
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv55821
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE139874
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv157463
_ZN4PLMD17typesafePtrSizeofIdEEmv198650
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb198839
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE211095
_ZN4PLMD11TypesafePtrC2ExmPKm246118
_ZN4PLMD17typesafePtrSizeofIKxEEmv250057
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv250057
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb250057
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv253956
_ZN4PLMD17typesafePtrSizeofIiEEmv258497
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb258504
_ZN4PLMD17typesafePtrSizeofIKdEEmv379312
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb383613
_ZN4PLMD11TypesafePtraSEOS0_899637
_ZN4PLMDL20typesafePtrSkipCheckEv1115406
_ZN4PLMD11TypesafePtr10init_shapeEPKm1135275
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func.html b/coverage/tools/TypesafePtr.h.func.html new file mode 100644 index 0000000000..65400b4ac7 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func.html @@ -0,0 +1,292 @@ + + + + + + + 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:11513187.8 %
Date:2024-05-27 13:05:14Functions:405572.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr10init_shapeEPKm1135275
_ZN4PLMD11TypesafePtrC2EOS0_64
_ZN4PLMD11TypesafePtrC2EdmPKm8939
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EimPKm8645
_ZN4PLMD11TypesafePtrC2ExmPKm246118
_ZN4PLMD11TypesafePtraSEOS0_899637
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKcEEmv6236
_ZN4PLMD17typesafePtrSizeofIKdEEmv379312
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKiEEmv15377
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZN4PLMD17typesafePtrSizeofIKxEEmv250057
_ZN4PLMD17typesafePtrSizeofIdEEmv198650
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZN4PLMD17typesafePtrSizeofIiEEmv258497
_ZN4PLMD17typesafePtrSizeofIlEEmv64
_ZN4PLMDL20typesafePtrSkipCheckEv1115406
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv157463
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE211095
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv55821
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE139874
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv253956
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv13300
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv14347
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv250057
_ZNK4PLMD11TypesafePtr3setIdEEvT_3029
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr3setIiEEvT_4548
_ZNK4PLMD11TypesafePtr3setIlEEvT_64
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb851
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb4133
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2178
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb383613
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb15335
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1715
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb250057
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb198839
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb258504
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb64
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.gcov.html b/coverage/tools/TypesafePtr.h.gcov.html new file mode 100644 index 0000000000..f945a2b632 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.gcov.html @@ -0,0 +1,475 @@ + + + + + + + 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:11513187.8 %
Date:2024-05-27 13:05:14Functions:405572.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             : #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     1115406 : static inline bool typesafePtrSkipCheck() {
+      42     1115406 :   static const bool ret=std::getenv("PLUMED_TYPESAFE_IGNORE");
+      43     1115406 :   return ret;
+      44             : }
+      45             : 
+      46             : template<class T>
+      47     1108194 : std::size_t typesafePtrSizeof() {
+      48     1108194 :   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     1135275 :   inline void init_shape(const std::size_t* shape) {
+      70     1135275 :     this->shape[0]=0;
+      71     1135275 :     if(shape && *shape>0) {
+      72             :       std::size_t nelem_=1;
+      73             :       unsigned i=0;
+      74         820 :       for(i=0; i<this->shape.size(); i++) {
+      75         820 :         this->shape[i]=*shape;
+      76         820 :         if(*shape==0) break;
+      77         468 :         nelem_*=*shape;
+      78         468 :         shape++;
+      79             :       }
+      80         352 :       plumed_assert(i<this->shape.size()); // check that last element is actually zero
+      81         352 :       if(nelem==0) nelem=nelem_;
+      82         352 :       plumed_assert(nelem==nelem_) << "Inconsistent shape/nelem";
+      83             :     }
+      84     1135275 :   }
+      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      291328 :     ptr(ptr),
+      92      291328 :     nelem(nelem),
+      93      291328 :     flags(flags)
+      94             :   {
+      95      291328 :     buffer[0]='\0';
+      96      291328 :     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      276090 :     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     1704911 :   TypesafePtr() {
+     112     1704911 :     shape[0]=0;
+     113     1481759 :     buffer[0]='\0';
+     114             :   }
+     115             : 
+     116             :   TypesafePtr(std::nullptr_t)
+     117      260571 :   {
+     118      260571 :     shape[0]=0;
+     119      259455 :     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        1217 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(void,1)
+     169        1761 :   __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      264252 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(int,3)
+     175          98 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned int,0x100+3)
+     176             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long,3)
+     177             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long,0x100+3)
+     178      246118 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long long,3)
+     179        3939 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long long,0x100+3)
+     180           0 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(float,4)
+     181      325712 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(double,4)
+     182             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long double,4)
+     183         850 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(FILE,5)
+     184             : 
+     185             :   ~TypesafePtr() {
+     186     2290733 :   }
+     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      899637 :   TypesafePtr & operator=(TypesafePtr && other) {
+     206      899637 :     ptr=(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr);
+     207      899637 :     flags=other.flags;
+     208      899637 :     nelem=other.nelem;
+     209      899637 :     shape=other.shape;
+     210      899637 :     buffer=other.buffer;
+     211      899637 :     other.ptr=nullptr;
+     212      899637 :     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     1115406 :   T* get_priv(std::size_t nelem, const std::size_t* shape, bool byvalue) const {
+     230             : 
+     231     1115406 :     if(typesafePtrSkipCheck()) return (T*) ptr;
+     232             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     233     1115406 :     if(flags==0) return (T*) ptr; // no check
+     234     1109051 :     auto size=flags&0xffff;
+     235     1109051 :     auto type=(flags>>16)&0xff;
+     236             :     // auto unsi=(flags>>24)&0x1; // ignored
+     237     1110766 :     auto cons=(flags>>25)&0x7;
+     238             : 
+     239             :     // type=0: ignore check
+     240             :     // type>5: undefined yet
+     241     1109051 :     if(type!=0 && type<=5) {
+     242      530236 :       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      577963 :       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         851 :       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     1109046 :     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     1110761 :     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     1106627 :     if(cons>0) {
+     263             :       if(!std::is_pointer<T>::value) {
+     264             :         if(std::is_void<T>::value) {
+     265        1715 :           if(cons==1) {
+     266           0 :             throw ExceptionTypeError() << "This command expects a void pointer. It received a value instead"<<extra_msg();
+     267             :           }
+     268             :         } else {
+     269     1104796 :           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      458062 :           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      458062 :           } 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     1110760 :     if(shape && shape[0] && this->shape[0]) {
+     298         510 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     299         510 :         if(shape[i]==0 && this->shape[i]!=0) {
+     300           0 :           throw ExceptionTypeError() << "Incorrect number of axis (passed greater than requested)"<<extra_msg();
+     301             :         }
+     302         510 :         if(shape[i]!=0 && this->shape[i]==0) {
+     303           0 :           throw ExceptionTypeError() << "Incorrect number of axis (requested greater than passed)"<<extra_msg();
+     304             :         }
+     305         510 :         if(shape[i]==0) break;
+     306         340 :         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         340 :         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     1110760 :     if(nelem==0 && shape && shape[0]>0) {
+     315      293774 :       nelem=1;
+     316      881322 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     317      881322 :         if(shape[i]==0) break;
+     318      587548 :         nelem*=shape[i];
+     319             :       }
+     320             :     }
+     321             :     // check number of elements
+     322     1110760 :     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     1110758 :     return (T*) ptr;
+     326             :   }
+     327             : 
+     328             : public:
+     329             : 
+     330             :   template<typename T>
+     331        7642 :   void set(T val) const {
+     332        7642 :     *get_priv<T>(0,nullptr,false)=val;
+     333        7642 :   }
+     334             : 
+     335             :   template<typename T>
+     336      467240 :   typename std::enable_if<std::is_pointer<T>::value,T>::type get() const {
+     337             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     338      472212 :     return get_priv<T_noptr>(0,nullptr,false);
+     339             :   }
+     340             : 
+     341             :   template<typename T>
+     342      277704 :   typename std::enable_if<!std::is_pointer<T>::value,T>::type get() const {
+     343      277704 :     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        6875 :     return get_priv<T_noptr>(nelem,nullptr,false);
+     351             :   }
+     352             : 
+     353             :   template<typename T>
+     354      350969 :   T get(std::initializer_list<std::size_t> shape) const {
+     355             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     356      350969 :     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     1052907 :     for(auto i : shape) {
+     361      701938 :       shape_[j]=i;
+     362      701938 :       j++;
+     363             :     }
+     364      350969 :     shape_[j]=0;
+     365      350969 :     return get_priv<T_noptr>(0,&shape_[0],false);
+     366             :   }
+     367             : 
+     368             :   operator bool() const noexcept {
+     369      964835 :     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.16
+
+ + + diff --git a/coverage/tools/Units.cpp.func-sort-c.html b/coverage/tools/Units.cpp.func-sort-c.html new file mode 100644 index 0000000000..d312d40fa5 --- /dev/null +++ b/coverage/tools/Units.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_traitsIcESaIcEEE35
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units7setMassEd810
_ZN4PLMD5Units9setChargeEd810
_ZN4PLMD5Units9setLengthEd810
_ZN4PLMD5UnitsC2Ev1611377
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.func.html b/coverage/tools/Units.cpp.func.html new file mode 100644 index 0000000000..2e9a6868aa --- /dev/null +++ b/coverage/tools/Units.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units7setMassEd810
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units9setChargeEd810
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35
_ZN4PLMD5Units9setLengthEd810
_ZN4PLMD5UnitsC2Ev1611377
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.gcov.html b/coverage/tools/Units.cpp.gcov.html new file mode 100644 index 0000000000..e1e0cf1f88 --- /dev/null +++ b/coverage/tools/Units.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + 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-05-27 13:05: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     1611377 : Units::Units():
+      28     1611377 :   energy(1.0),
+      29     1611377 :   energyString("kj/mol"),
+      30     1611377 :   length(1.0),
+      31     1611377 :   lengthString("nm"),
+      32     1611377 :   time(1.0),
+      33     1611377 :   timeString("ps"),
+      34     1611377 :   charge(1.0),
+      35     1611377 :   chargeString("e"),
+      36     1611377 :   mass(1.0),
+      37     1611377 :   massString("amu")
+      38             : {
+      39     1611377 : }
+      40             : 
+      41          13 : void Units::setEnergy(const std::string &s) {
+      42          13 :   energyString=s;
+      43          13 :   if(s=="kj/mol") {
+      44           5 :     energy=1.0;
+      45           8 :   } else if(s=="kcal/mol") {
+      46           5 :     energy=4.184;
+      47           3 :   } else if(s=="j/mol") {
+      48           0 :     energy=0.001;
+      49           3 :   } else if(s=="eV") {
+      50           0 :     energy=96.48530749925792;
+      51           3 :   } else if(s =="Ha") {
+      52           1 :     energy=2625.499638;
+      53             :   } else {
+      54           2 :     energy=-1.0;
+      55             :     energyString="";
+      56           2 :     if(!Tools::convertNoexcept(s,energy)) {
+      57           0 :       plumed_merror("problem with setting the energy unit, either use give an numerical value or use one of the defined units: kj/mol, kcal/mol, j/mol, eV, Ha (case sensitive)");
+      58             :     }
+      59           2 :     plumed_massert(energy>0.0,"energy unit should be positive");
+      60             :   }
+      61          13 : }
+      62             : 
+      63          35 : void Units::setLength(const std::string &s) {
+      64          35 :   lengthString=s;
+      65          35 :   if(s=="nm") {
+      66           2 :     length=1.0;
+      67          33 :   } else if(s=="A") {
+      68          26 :     length=0.1;
+      69           7 :   } else if(s=="um") {
+      70           0 :     length=1000.0;
+      71           7 :   } else if(s=="Bohr") {
+      72           1 :     length=0.052917721067;
+      73             :   } else {
+      74           6 :     length=-1.0;
+      75             :     lengthString="";
+      76           6 :     if(!Tools::convertNoexcept(s,length)) {
+      77           0 :       plumed_merror("problem with setting the length unit, either use a numerical value or use one of the defined units: nm, A, um, Bohr (case sensitive)");
+      78             :     }
+      79           6 :     plumed_massert(length>0.0,"length unit should be positive");
+      80             :   }
+      81          35 : }
+      82             : 
+      83           7 : void Units::setTime(const std::string &s) {
+      84           7 :   timeString=s;
+      85           7 :   if(s=="ps") {
+      86           2 :     time=1.0;
+      87           5 :   } else if(s=="ns") {
+      88           0 :     time=1000.0;
+      89           5 :   } else if(s=="fs") {
+      90           2 :     time=0.001;
+      91           3 :   } else if(s=="atomic") {
+      92           1 :     time=2.418884326509e-5;
+      93             :   } else {
+      94           2 :     time=-1.0;
+      95             :     timeString="";
+      96           2 :     if(!Tools::convertNoexcept(s,time)) {
+      97           0 :       plumed_merror("problem with setting the time unit, either use a numerical value or use one of the defined units: ps, fs, atomic (case sensitive)");
+      98             :     }
+      99           2 :     plumed_massert(time>0.0,"time unit should be positive");
+     100             :   }
+     101           7 : }
+     102             : 
+     103           4 : void Units::setCharge(const std::string &s) {
+     104           4 :   chargeString=s;
+     105           4 :   if(s=="e") {
+     106           1 :     charge=1.0;
+     107             :   } else {
+     108           3 :     charge=-1.0;
+     109             :     chargeString="";
+     110           3 :     if(!Tools::convertNoexcept(s,charge)) {
+     111           0 :       plumed_merror("problem with setting the charge unit, either use a numerical value or use one of the defined units: e (case sensitive)");
+     112             :     }
+     113           3 :     plumed_massert(charge>0.0,"charge unit should be positive");
+     114             :   }
+     115           4 : }
+     116             : 
+     117           3 : void Units::setMass(const std::string &s) {
+     118           3 :   massString=s;
+     119           3 :   if(s=="amu") {
+     120           1 :     mass=1.0;
+     121             :   } else {
+     122           2 :     mass=-1.0;
+     123             :     massString="";
+     124           2 :     if(!Tools::convertNoexcept(s,mass)) {
+     125           0 :       plumed_merror("problem with setting the mass unit, either use a numerical value or use one of the defined units: amu (case sensitive)");
+     126             :     }
+     127           2 :     plumed_massert(mass>0.0,"mass unit should be positive");
+     128             :   }
+     129           3 : }
+     130             : 
+     131          45 : void Units::setEnergy(const double s) {
+     132          45 :   energyString="";
+     133          45 :   energy=s;
+     134          45 : }
+     135             : 
+     136         810 : void Units::setLength(const double s) {
+     137         810 :   lengthString="";
+     138         810 :   length=s;
+     139         810 : }
+     140             : 
+     141           6 : void Units::setTime(const double s) {
+     142           6 :   timeString="";
+     143           6 :   time=s;
+     144           6 : }
+     145             : 
+     146         810 : void Units::setCharge(const double s) {
+     147         810 :   chargeString="";
+     148         810 :   charge=s;
+     149         810 : }
+     150             : 
+     151         810 : void Units::setMass(const double s) {
+     152         810 :   massString="";
+     153         810 :   mass=s;
+     154         810 : }
+     155             : 
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func-sort-c.html b/coverage/tools/Units.h.func-sort-c.html new file mode 100644 index 0000000000..90e09034a2 --- /dev/null +++ b/coverage/tools/Units.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func.html b/coverage/tools/Units.h.func.html new file mode 100644 index 0000000000..d490cbe970 --- /dev/null +++ b/coverage/tools/Units.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.gcov.html b/coverage/tools/Units.h.gcov.html new file mode 100644 index 0000000000..300fda27d6 --- /dev/null +++ b/coverage/tools/Units.h.gcov.html @@ -0,0 +1,243 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/tools/Vector.h.func-sort-c.html b/coverage/tools/Vector.h.func-sort-c.html new file mode 100644 index 0000000000..f96d63aa73 --- /dev/null +++ b/coverage/tools/Vector.h.func-sort-c.html @@ -0,0 +1,288 @@ + + + + + + + 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-05-27 13:05:14Functions:515494.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJffEEEdDpT_0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj3EEdVEd43767
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_103260
_ZN4PLMD13VectorGenericILj1EEC2Ev548920
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_555994
_ZN4PLMD13VectorGenericILj1EEixEj1097840
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZN4PLMD13VectorGenericILj4EEC2Ev1747526
_ZN4PLMD13VectorGenericILj3EE4zeroEv4597856
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881282
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13711507
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13711507
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13814767
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD13VectorGenericILj4EEixEj27787512
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_28854794
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_28854794
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_28958054
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_42772821
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d72569397
_ZNK4PLMD13VectorGenericILj3EEngEv106092195
_ZNK4PLMD13VectorGenericILj3EE6moduloEv119083320
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166491732
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202717593
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_353994532
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d441991235
_ZN4PLMD13VectorGenericILj3EEC2Ev488648078
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev784172799
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_900359209
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1218493064
_ZNK4PLMD13VectorGenericILj3EEclEj1262297343
_ZN4PLMD13VectorGenericILj3EEclEj1267578990
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368339694
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1747356161
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1824810154
_ZN4PLMD13VectorGenericILj3EEmLEd1825196113
_ZN4PLMD13VectorGenericILj3EEixEj2652237166
_ZNK4PLMD13VectorGenericILj3EEixEj3343050167
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.func.html b/coverage/tools/Vector.h.func.html new file mode 100644 index 0000000000..3bcdf0afd4 --- /dev/null +++ b/coverage/tools/Vector.h.func.html @@ -0,0 +1,288 @@ + + + + + + + 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-05-27 13:05:14Functions:515494.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166491732
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881282
_ZN4PLMD13VectorGenericILj1EEC2Ev548920
_ZN4PLMD13VectorGenericILj1EEixEj1097840
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_42772821
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_28958054
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_28854794
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13814767
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13711507
_ZN4PLMD13VectorGenericILj3EE4zeroEv4597856
_ZN4PLMD13VectorGenericILj3EEC2Ev488648078
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_28854794
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJffEEEdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13711507
_ZN4PLMD13VectorGenericILj3EEclEj1267578990
_ZN4PLMD13VectorGenericILj3EEdVEd43767
_ZN4PLMD13VectorGenericILj3EEixEj2652237166
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1218493064
_ZN4PLMD13VectorGenericILj3EEmLEd1825196113
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1747356161
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EEC2Ev1747526
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_555994
_ZN4PLMD13VectorGenericILj4EEixEj27787512
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_353994532
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202717593
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d72569397
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_900359209
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d441991235
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1824810154
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368339694
_ZNK4PLMD13VectorGenericILj3EE6moduloEv119083320
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev784172799
_ZNK4PLMD13VectorGenericILj3EEclEj1262297343
_ZNK4PLMD13VectorGenericILj3EEixEj3343050167
_ZNK4PLMD13VectorGenericILj3EEngEv106092195
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.gcov.html b/coverage/tools/Vector.h.gcov.html new file mode 100644 index 0000000000..40d42a797f --- /dev/null +++ b/coverage/tools/Vector.h.gcov.html @@ -0,0 +1,419 @@ + + + + + + + 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-05-27 13:05: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   130542439 : void VectorGeneric<n>::auxiliaryConstructor(double first,Args... arg)
+     164             : {
+     165   130542439 :   d[n-(sizeof...(Args))-1]=first;
+     166    87213624 :   auxiliaryConstructor(arg...);
+     167   130542439 : }
+     168             : 
+     169             : template <unsigned n>
+     170             : template<typename... Args>
+     171    43328815 : 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    43328815 :   auxiliaryConstructor(first,arg...);
+     175    43328815 : }
+     176             : 
+     177             : template <unsigned n>
+     178     4597856 : void VectorGeneric<n>::zero() {
+     179     4597856 :   LoopUnroller<n>::_zero(d.data());
+     180     4597856 : }
+     181             : 
+     182             : template <unsigned n>
+     183   490948528 : VectorGeneric<n>::VectorGeneric() {
+     184   490399608 :   LoopUnroller<n>::_zero(d.data());
+     185   490948528 : }
+     186             : 
+     187             : template <unsigned n>
+     188  2744771880 : double & VectorGeneric<n>::operator[](unsigned i) {
+     189  2744771880 :   return d[i];
+     190             : }
+     191             : 
+     192             : template <unsigned n>
+     193  3739426547 : const double & VectorGeneric<n>::operator[](unsigned i)const {
+     194  3739426547 :   return d[i];
+     195             : }
+     196             : 
+     197             : template <unsigned n>
+     198  1267578990 : double & VectorGeneric<n>::operator()(unsigned i) {
+     199  1267578990 :   return d[i];
+     200             : }
+     201             : 
+     202             : template <unsigned n>
+     203  1266916071 : const double & VectorGeneric<n>::operator()(unsigned i)const {
+     204  1266916071 :   return d[i];
+     205             : }
+     206             : 
+     207             : template <unsigned n>
+     208  1747356161 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
+     209  1747356161 :   LoopUnroller<n>::_add(d.data(),b.d.data());
+     210  1747356161 :   return *this;
+     211             : }
+     212             : 
+     213             : template <unsigned n>
+     214  1219612166 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
+     215  1219612166 :   LoopUnroller<n>::_sub(d.data(),b.d.data());
+     216  1219612166 :   return *this;
+     217             : }
+     218             : 
+     219             : template <unsigned n>
+     220  1825196113 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
+     221  1825196113 :   LoopUnroller<n>::_mul(d.data(),s);
+     222  1825196113 :   return *this;
+     223             : }
+     224             : 
+     225             : template <unsigned n>
+     226       43767 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
+     227       43767 :   LoopUnroller<n>::_mul(d.data(),1.0/s);
+     228       43767 :   return *this;
+     229             : }
+     230             : 
+     231             : template <unsigned n>
+     232             : VectorGeneric<n>  VectorGeneric<n>::operator +()const {
+     233             :   return *this;
+     234             : }
+     235             : 
+     236             : template <unsigned n>
+     237   106092195 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
+     238   106092195 :   VectorGeneric<n> r;
+     239   106092195 :   LoopUnroller<n>::_neg(r.d.data(),d.data());
+     240   106092195 :   return r;
+     241             : }
+     242             : 
+     243             : template <unsigned n>
+     244  1368339694 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     245  1368339694 :   VectorGeneric<n> v(v1);
+     246  1368339694 :   return v+=v2;
+     247             : }
+     248             : 
+     249             : template <unsigned n>
+     250   901478311 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     251   901478311 :   VectorGeneric<n> v(v1);
+     252   901478311 :   return v-=v2;
+     253             : }
+     254             : 
+     255             : template <unsigned n>
+     256  1824810154 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
+     257  1824810154 :   VectorGeneric<n> vv(v);
+     258  1824810154 :   return vv*=s;
+     259             : }
+     260             : 
+     261             : template <unsigned n>
+     262   441991235 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
+     263   441991235 :   return s*v;
+     264             : }
+     265             : 
+     266             : template <unsigned n>
+     267    72569397 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
+     268    72569397 :   return v*(1.0/s);
+     269             : }
+     270             : 
+     271             : template <unsigned n>
+     272   355113634 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     273   355113634 :   return v2-v1;
+     274             : }
+     275             : 
+     276             : template <unsigned n>
+     277   785291901 : double VectorGeneric<n>::modulo2()const {
+     278   785291901 :   return LoopUnroller<n>::_sum2(d.data());
+     279             : }
+     280             : 
+     281             : template <unsigned n>
+     282   166491732 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
+     283   166491732 :   return LoopUnroller<n>::_dot(v1.d.data(),v2.d.data());
+     284             : }
+     285             : 
+     286             : inline
+     287     4881282 : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
+     288             :   return VectorGeneric<3>(
+     289     4881282 :            v1[1]*v2[2]-v1[2]*v2[1],
+     290     4881282 :            v1[2]*v2[0]-v1[0]*v2[2],
+     291     4881282 :            v1[0]*v2[1]-v1[1]*v2[0]);
+     292             : }
+     293             : 
+     294             : template<unsigned n>
+     295   119083320 : double VectorGeneric<n>::modulo()const {
+     296   119083320 :   return sqrt(modulo2());
+     297             : }
+     298             : 
+     299             : template<unsigned n>
+     300   202717593 : double modulo2(const VectorGeneric<n>&v) {
+     301   202717593 :   return v.modulo2();
+     302             : }
+     303             : 
+     304             : template<unsigned n>
+     305    22918220 : double modulo(const VectorGeneric<n>&v) {
+     306    22918220 :   return v.modulo();
+     307             : }
+     308             : 
+     309             : template<unsigned n>
+     310             : std::ostream & operator<<(std::ostream &os, const VectorGeneric<n>& v) {
+     311             :   for(unsigned i=0; i<n-1; i++) os<<v(i)<<" ";
+     312             :   os<<v(n-1);
+     313             :   return os;
+     314             : }
+     315             : 
+     316             : 
+     317             : /// \ingroup TOOLBOX
+     318             : /// Alias for one dimensional vectors
+     319             : typedef VectorGeneric<1> Vector1d;
+     320             : /// \ingroup TOOLBOX
+     321             : /// Alias for two dimensional vectors
+     322             : typedef VectorGeneric<2> Vector2d;
+     323             : /// \ingroup TOOLBOX
+     324             : /// Alias for three dimensional vectors
+     325             : typedef VectorGeneric<3> Vector3d;
+     326             : /// \ingroup TOOLBOX
+     327             : /// Alias for four dimensional vectors
+     328             : typedef VectorGeneric<4> Vector4d;
+     329             : /// \ingroup TOOLBOX
+     330             : /// Alias for five dimensional vectors
+     331             : typedef VectorGeneric<5> Vector5d;
+     332             : /// \ingroup TOOLBOX
+     333             : /// Alias for three dimensional vectors
+     334             : typedef Vector3d Vector;
+     335             : 
+     336             : static_assert(sizeof(VectorGeneric<2>)==2*sizeof(double), "code cannot work if this is not satisfied");
+     337             : static_assert(sizeof(VectorGeneric<3>)==3*sizeof(double), "code cannot work if this is not satisfied");
+     338             : static_assert(sizeof(VectorGeneric<4>)==4*sizeof(double), "code cannot work if this is not satisfied");
+     339             : 
+     340             : }
+     341             : 
+     342             : #endif
+     343             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func-sort-c.html b/coverage/tools/h36.cpp.func-sort-c.html new file mode 100644 index 0000000000..ba5776f0da --- /dev/null +++ b/coverage/tools/h36.cpp.func-sort-c.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05: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_clEv219
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv219
_ZN4PLMD3h36L12digits_lowerEv7885
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_upperEv111663
_ZN4PLMD3h3610hy36decodeEjPKcjPi542340
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi542340
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func.html b/coverage/tools/h36.cpp.func.html new file mode 100644 index 0000000000..ede9ee54fd --- /dev/null +++ b/coverage/tools/h36.cpp.func.html @@ -0,0 +1,120 @@ + + + + + + + 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-05-27 13:05:14Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h3610hy36decodeEjPKcjPi542340
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi542340
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_lowerEv7885
_ZN4PLMD3h36L12digits_upperEv111663
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv219
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv219
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.gcov.html b/coverage/tools/h36.cpp.gcov.html new file mode 100644 index 0000000000..e42e9602dc --- /dev/null +++ b/coverage/tools/h36.cpp.gcov.html @@ -0,0 +1,411 @@ + + + + + + + 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-05-27 13:05: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      111663 : digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+      62             : 
+      63             : static
+      64             : const char*
+      65        7885 : 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      542340 : 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     2982869 :   for(; i<s_size; i++) {
+     133     2440530 :     si = s[i];
+     134     2440530 :     if (si < 0 || si > 127) {
+     135           0 :       *result = 0;
+     136           0 :       return invalid_number_literal();
+     137             :     }
+     138     2440530 :     if (si == ' ') {
+     139      908622 :       if (!have_non_blank) continue;
+     140           0 :       value *= digits_size;
+     141             :     }
+     142     1531908 :     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     1531908 :       dv = digits_values[si];
+     154     1531908 :       if (dv < 0 || dv >= digits_size) {
+     155           1 :         *result = 0;
+     156           1 :         return invalid_number_literal();
+     157             :       }
+     158     1531907 :       value *= digits_size;
+     159     1531907 :       value += dv;
+     160             :     }
+     161             :   }
+     162      542339 :   if (have_minus) value = -value;
+     163      542339 :   *result = value;
+     164      542339 :   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      542340 : hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+     261             : {
+     262         219 :   static const std::vector<int> digits_values_upper_vector([]() {
+     263         219 :     std::vector<int> ret(128U,-1);
+     264        8103 :     for(unsigned i=0; i<36U; i++) {
+     265        7884 :       int di = digits_upper()[i];
+     266        7884 :       if (di < 0 || di > 127) {
+     267           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     268             :       }
+     269        7884 :       ret[di] = i;
+     270             :     }
+     271         219 :     return ret;
+     272      542340 :   }());
+     273      542340 :   static const int* digits_values_upper=digits_values_upper_vector.data();
+     274         219 :   static const std::vector<int> digits_values_lower_vector([]() {
+     275         219 :     std::vector<int> ret(128U,-1);
+     276        8103 :     for(unsigned i=0; i<36U; i++) {
+     277        7884 :       int di = digits_lower()[i];
+     278        7884 :       if (di < 0 || di > 127) {
+     279           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     280             :       }
+     281        7884 :       ret[di] = i;
+     282             :     }
+     283         219 :     return ret;
+     284      542340 :   }());
+     285      542340 :   static const int* digits_values_lower=digits_values_lower_vector.data();
+     286             :   int di;
+     287             :   const char* errmsg;
+     288      542340 :   if (s_size == width) {
+     289      542340 :     di = s[0];
+     290      542340 :     if (di >= 0 && di <= 127) {
+     291      542340 :       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      542334 :       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      542334 :         errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+     319      542334 :         if (errmsg) return errmsg;
+     320      542334 :         if (!(width == 4U || width == 5U)) {
+     321           0 :           *result = 0;
+     322           0 :           return unsupported_width();
+     323             :         }
+     324             :         return 0;
+     325             :       }
+     326             :     }
+     327             :   }
+     328           1 :   *result = 0;
+     329           1 :   return invalid_number_literal();
+     330             : }
+     331             : 
+     332             : }
+     333             : 
+     334             : }
+     335             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-f.html b/coverage/tools/index-sort-f.html new file mode 100644 index 0000000000..87e02c9400 --- /dev/null +++ b/coverage/tools/index-sort-f.html @@ -0,0 +1,803 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5628673883.5 %
Date:2024-05-27 13:05:14Functions:1406172881.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Exception.h +
83.3%83.3%
+
83.3 %30 / 3617.0 %23 / 135
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 +
62.9%62.9%
+
62.9 %22 / 3562.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.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
TypesafePtr.h +
87.8%87.8%
+
87.8 %115 / 13172.7 %40 / 55
OpenMP.h +
100.0%
+
100.0 %8 / 875.0 %3 / 4
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
DLLoader.cpp +
81.0%81.0%
+
81.0 %17 / 2180.0 %4 / 5
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
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
PDB.cpp +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15182.4 %56 / 68
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Subprocess.cpp +
75.3%75.3%
+
75.3 %64 / 8587.5 %14 / 16
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
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
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
Tools.h +
82.6%82.6%
+
82.6 %76 / 9291.9 %399 / 434
Tools.cpp +
91.7%91.7%
+
91.7 %255 / 27892.7 %51 / 55
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.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
OFile.cpp +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Pbc.h +
100.0%
+
100.0 %3 / 3-0 / 0
NeighborList.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
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
AtomNumber.h +
100.0%
+
100.0 %18 / 18100.0 %2 / 2
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
Stopwatch.cpp +
100.0%
+
100.0 %20 / 20100.0 %3 / 3
Tree.cpp +
100.0%
+
100.0 %37 / 37100.0 %3 / 3
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
MultiValue.cpp +
100.0%
+
100.0 %62 / 62100.0 %9 / 9
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
HistogramBead.cpp +
78.8%78.8%
+
78.8 %93 / 118100.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
SwitchingFunction.cpp +
97.3%97.3%
+
97.3 %256 / 263100.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
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-l.html b/coverage/tools/index-sort-l.html new file mode 100644 index 0000000000..b8840775bc --- /dev/null +++ b/coverage/tools/index-sort-l.html @@ -0,0 +1,803 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5628673883.5 %
Date:2024-05-27 13:05:14Functions:1406172881.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
PlumedHandle.cpp +
62.9%62.9%
+
62.9 %22 / 3562.5 %5 / 8
PDB.cpp +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
Grid.cpp +
71.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
RMSD.cpp +
73.5%73.5%
+
73.5 %540 / 73552.5 %42 / 80
Subprocess.cpp +
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
OpenMP.cpp +
82.4%82.4%
+
82.4 %14 / 1780.0 %4 / 5
Tools.h +
82.6%82.6%
+
82.6 %76 / 9291.9 %399 / 434
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
Exception.h +
83.3%83.3%
+
83.3 %30 / 3617.0 %23 / 135
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
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.8%87.8%
+
87.8 %115 / 13172.7 %40 / 55
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
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
Tools.cpp +
91.7%91.7%
+
91.7 %255 / 27892.7 %51 / 55
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
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
Tensor.h +
96.7%96.7%
+
96.7 %146 / 15182.4 %56 / 68
OFile.cpp +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
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
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Pbc.h +
100.0%
+
100.0 %3 / 3-0 / 0
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 %6 / 6-0 / 0
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
OpenMP.h +
100.0%
+
100.0 %8 / 875.0 %3 / 4
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
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 %18 / 18100.0 %2 / 2
Stopwatch.cpp +
100.0%
+
100.0 %20 / 20100.0 %3 / 3
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Tree.cpp +
100.0%
+
100.0 %37 / 37100.0 %3 / 3
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 %80 / 8093.3 %14 / 15
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index.html b/coverage/tools/index.html new file mode 100644 index 0000000000..b1bb6030ae --- /dev/null +++ b/coverage/tools/index.html @@ -0,0 +1,803 @@ + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5628673883.5 %
Date:2024-05-27 13:05:14Functions:1406172881.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %18 / 18100.0 %2 / 2
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
DLLoader.cpp +
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 +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
Exception.h +
83.3%83.3%
+
83.3 %30 / 3617.0 %23 / 135
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %13 / 13
Grid.cpp +
71.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
HistogramBead.cpp +
78.8%78.8%
+
78.8 %93 / 118100.0 %11 / 11
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
KernelFunctions.cpp +
84.4%84.4%
+
84.4 %189 / 22490.0 %9 / 10
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.0 %2 / 2
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %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 +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
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 +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
Pbc.cpp +
95.3%95.3%
+
95.3 %102 / 10791.7 %11 / 12
Pbc.h +
100.0%
+
100.0 %3 / 3-0 / 0
PlumedHandle.cpp +
62.9%62.9%
+
62.9 %22 / 3562.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 +
91.7%91.7%
+
91.7 %255 / 27892.7 %51 / 55
Tools.h +
82.6%82.6%
+
82.6 %76 / 9291.9 %399 / 434
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
Tree.cpp +
100.0%
+
100.0 %37 / 37100.0 %3 / 3
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
TypesafePtr.h +
87.8%87.8%
+
87.8 %115 / 13172.7 %40 / 55
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Vector.h +
100.0%
+
100.0 %66 / 6694.4 %51 / 54
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/updown.png b/coverage/updown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa56a238b3e6c435265250f9266cd1b8caba0f20 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}Qd8;}%R+`Ae`*?77*hG?8mPH5^{)z4*}Q$iB}huR`+ literal 0 HcmV?d00001 diff --git a/coverage/vatom/Center.cpp.func-sort-c.html b/coverage/vatom/Center.cpp.func-sort-c.html new file mode 100644 index 0000000000..ea9d82e11e --- /dev/null +++ b/coverage/vatom/Center.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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:12012298.4 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1406createERKNS_13ActionOptionsE74
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe139C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe139D2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe140C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe140D2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1396createERKNS_13ActionOptionsE7089
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7163
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7167
_ZN4PLMD5vatom6Center9calculateEv13808
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.func.html b/coverage/vatom/Center.cpp.func.html new file mode 100644 index 0000000000..561817503a --- /dev/null +++ b/coverage/vatom/Center.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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:12012298.4 %
Date:2024-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1396createERKNS_13ActionOptionsE7089
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe139C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe139D2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe1406createERKNS_13ActionOptionsE74
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe140C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_119CenterRegisterMe140D2Ev4168
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7167
_ZN4PLMD5vatom6Center9calculateEv13808
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7163
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.gcov.html b/coverage/vatom/Center.cpp.gcov.html new file mode 100644 index 0000000000..9021280863 --- /dev/null +++ b/coverage/vatom/Center.cpp.gcov.html @@ -0,0 +1,398 @@ + + + + + + + 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:12012298.4 %
Date:2024-05-27 13:05: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             :   double charge_;
+     126             :   double mass_;
+     127             :   bool isChargeSet_;
+     128             :   bool isMassSet_;
+     129             :   bool weight_mass;
+     130             :   bool nopbc;
+     131             :   bool first;
+     132             :   bool phases;
+     133             : public:
+     134             :   explicit Center(const ActionOptions&ao);
+     135             :   void calculate() override;
+     136             :   static void registerKeywords( Keywords& keys );
+     137             : };
+     138             : 
+     139       26680 : PLUMED_REGISTER_ACTION(Center,"CENTER")
+     140       12652 : PLUMED_REGISTER_ACTION(Center,"COM")
+     141             : 
+     142        7167 : void Center::registerKeywords(Keywords& keys) {
+     143        7167 :   ActionWithVirtualAtom::registerKeywords(keys);
+     144       14334 :   keys.add("optional","WEIGHTS","Center is computed as a weighted average.");
+     145       14334 :   keys.add("optional","SET_CHARGE","Set the charge of the virtual atom to a given value.");
+     146       14334 :   keys.add("optional","SET_MASS","Set the mass of the virtual atom to a given value.");
+     147       14334 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     148       14334 :   keys.addFlag("MASS",false,"If set center is mass weighted");
+     149       14334 :   keys.addFlag("PHASES",false,"Compute center using trigonometric phases");
+     150        7167 : }
+     151             : 
+     152        7163 : Center::Center(const ActionOptions&ao):
+     153             :   Action(ao),
+     154             :   ActionWithVirtualAtom(ao),
+     155        7163 :   charge_(nan("")),
+     156        7163 :   mass_(-1),
+     157        7163 :   isChargeSet_(false),
+     158        7163 :   isMassSet_(false),
+     159        7163 :   weight_mass(false),
+     160        7163 :   nopbc(false),
+     161        7163 :   first(true),
+     162        7163 :   phases(false)
+     163             : {
+     164             :   std::vector<AtomNumber> atoms;
+     165       14326 :   parseAtomList("ATOMS",atoms);
+     166        7163 :   if(atoms.size()==0) error("at least one atom should be specified");
+     167        7163 :   parseVector("WEIGHTS",weights);
+     168        7163 :   parseFlag("MASS",weight_mass);
+     169        7163 :   parseFlag("NOPBC",nopbc);
+     170        7163 :   parseFlag("PHASES",phases);
+     171        7163 :   parse("SET_CHARGE",charge_);
+     172        7163 :   if(!std::isnan(charge_)) isChargeSet_=true;
+     173        7163 :   parse("SET_MASS",mass_);
+     174        7163 :   if(mass_>0.) isMassSet_=true;
+     175        7163 :   if(mass_==0.) error("SETMASS must be greater than 0");
+     176        7163 :   if( getName()=="COM") weight_mass=true;
+     177        7163 :   checkRead();
+     178        7163 :   log.printf("  of atoms:");
+     179       37425 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     180       30262 :     if(i%25==0) log<<"\n";
+     181       30262 :     log.printf(" %d",atoms[i].serial());
+     182             :   }
+     183        7163 :   log<<"\n";
+     184        7163 :   if(weight_mass) {
+     185          77 :     log<<"  mass weighted\n";
+     186          77 :     if(weights.size()!=0) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+     187             :   } else {
+     188        7086 :     if( weights.size()==0) {
+     189         109 :       log<<" using the geometric center\n";
+     190         109 :       weights.resize( atoms.size() );
+     191        1330 :       for(unsigned i=0; i<atoms.size(); i++) weights[i] = 1.;
+     192             :     } else {
+     193        6977 :       log<<" with weights:";
+     194        6979 :       if( weights.size()!=atoms.size() ) error("number of elements in weight vector does not match the number of atoms");
+     195       35074 :       for(unsigned i=0; i<weights.size(); ++i) {
+     196       28098 :         if(i%25==0) log<<"\n";
+     197       28098 :         log.printf(" %f",weights[i]);
+     198             :       }
+     199        6976 :       log.printf("\n");
+     200             :     }
+     201             :   }
+     202        7161 :   if(phases) {
+     203           3 :     log<<"  Phases will be used to take into account PBC\n";
+     204        7158 :   } else if(nopbc) {
+     205          45 :     log<<"  PBC will be ignored\n";
+     206             :   } else {
+     207        7113 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     208             :   }
+     209        7161 :   requestAtoms(atoms);
+     210        7165 : }
+     211             : 
+     212       13808 : void Center::calculate() {
+     213       13808 :   Vector pos;
+     214             :   double mass(0.0);
+     215       13808 :   const bool dophases=(getPbc().isSet() ? phases : false);
+     216             : 
+     217       13808 :   if(!nopbc && !dophases) makeWhole();
+     218             : 
+     219       13808 :   if( first && weight_mass) {
+     220         725 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     221         659 :       if(std::isnan(getMass(i))) {
+     222           0 :         error(
+     223             :           "You are trying to compute a CENTER or COM but masses are not known.\n"
+     224             :           "        If you are using plumed driver, please use the --mc option"
+     225             :         );
+     226             :       }
+     227             :     }
+     228          66 :     first=false;
+     229             :   }
+     230             : 
+     231       13808 :   std::vector<Tensor> deriv(getNumberOfAtoms());
+     232       93301 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
+     233       13808 :   if( plumed.getAtoms().chargesWereSet() && !isChargeSet_) {
+     234             :     double charge(0.0);
+     235       60621 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
+     236             :     setCharge(charge);
+     237        4066 :   } else if(isChargeSet_) {
+     238          10 :     setCharge(charge_);
+     239             :   } else {
+     240             :     setCharge(0.0);
+     241             :   }
+     242             :   double wtot=0.0;
+     243       57967 :   for(unsigned i=0; i<weights.size(); i++) wtot+=weights[i];
+     244             : 
+     245       13808 :   if(dophases) {
+     246         240 :     dcenter_sin.resize(getNumberOfAtoms());
+     247         240 :     dcenter_cos.resize(getNumberOfAtoms());
+     248         240 :     Vector center_sin;
+     249         240 :     Vector center_cos;
+     250         240 :     Tensor invbox2pi=2*pi*getPbc().getInvBox();
+     251         240 :     Tensor box2pi=getPbc().getBox() / (2*pi);
+     252         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     253             :       double w=0;
+     254         720 :       if(weight_mass) w=getMass(i)/mass;
+     255         720 :       else w=weights[i]/wtot;
+     256             : 
+     257             :       // real to scaled
+     258         720 :       const Vector scaled=matmul(getPosition(i),invbox2pi);
+     259             :       const Vector ccos(
+     260         720 :         w*std::cos(scaled[0]),
+     261         720 :         w*std::cos(scaled[1]),
+     262         720 :         w*std::cos(scaled[2])
+     263         720 :       );
+     264             :       const Vector csin(
+     265         720 :         w*std::sin(scaled[0]),
+     266         720 :         w*std::sin(scaled[1]),
+     267         720 :         w*std::sin(scaled[2])
+     268         720 :       );
+     269         720 :       center_cos+=ccos;
+     270         720 :       center_sin+=csin;
+     271        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     272             :           // k over real coordinates
+     273             :           // l over scaled coordinates
+     274        6480 :           dcenter_sin[i][l][k]=ccos[l]*invbox2pi[k][l];
+     275        6480 :           dcenter_cos[i][l][k]=-csin[l]*invbox2pi[k][l];
+     276             :         }
+     277             :     }
+     278             :     const Vector c(
+     279         240 :       std::atan2(center_sin[0],center_cos[0]),
+     280         240 :       std::atan2(center_sin[1],center_cos[1]),
+     281         240 :       std::atan2(center_sin[2],center_cos[2])
+     282         240 :     );
+     283             : 
+     284             :     // normalization is convenient for doing derivatives later
+     285         960 :     for(unsigned l=0; l<3; l++) {
+     286         720 :       double norm=1.0/(center_sin[l]*center_sin[l]+center_cos[l]*center_cos[l]);
+     287         720 :       center_sin[l]*=norm;
+     288         720 :       center_cos[l]*=norm;
+     289             :     }
+     290             : 
+     291         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     292         720 :       Tensor dd;
+     293        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     294             :           // k over real coordinates
+     295             :           // l over scaled coordinates
+     296        6480 :           dd[l][k]= (center_cos[l]*dcenter_sin[i][l][k] - center_sin[l]*dcenter_cos[i][l][k]);
+     297             :         }
+     298             :       // scaled to real
+     299         720 :       deriv[i]=matmul(dd,box2pi);
+     300             :     }
+     301         240 :     if(!isMassSet_) setMass(mass);
+     302           0 :     else setMass(mass_);
+     303             :     setAtomsDerivatives(deriv);
+     304             :     // scaled to real
+     305         240 :     setPosition(matmul(c,box2pi));
+     306             :   } else {
+     307       92341 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     308             :       double w=0;
+     309       78773 :       if(weight_mass) w=getMass(i)/mass;
+     310       43439 :       else w=weights[i]/wtot;
+     311       78773 :       pos+=w*getPosition(i);
+     312       78773 :       deriv[i]=w*Tensor::identity();
+     313             :     }
+     314             :     setPosition(pos);
+     315       13568 :     if(!isMassSet_) setMass(mass);
+     316          10 :     else setMass(mass_);
+     317             :     setAtomsDerivatives(deriv);
+     318             :   }
+     319       13808 : }
+     320             : 
+     321             : }
+     322             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func-sort-c.html b/coverage/vatom/FixedAtom.cpp.func-sort-c.html new file mode 100644 index 0000000000..eb2dc58b6f --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe976createERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom9FixedAtom9calculateEv603
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func.html b/coverage/vatom/FixedAtom.cpp.func.html new file mode 100644 index 0000000000..5e4ba5de84 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe976createERKNS_13ActionOptionsE9
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_121FixedAtomRegisterMe97D2Ev4168
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom9FixedAtom9calculateEv603
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.gcov.html b/coverage/vatom/FixedAtom.cpp.gcov.html new file mode 100644 index 0000000000..54a261ea29 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + 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-05-27 13:05: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 two atoms created
+      44             : using FIXEDATOM is invariant for translation.
+      45             : Additionally, if one first align atoms to a reference using \ref FIT_TO_TEMPLATE,
+      46             : then it is safe to add further fixed atoms without breaking translational invariance.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input instructs plumed to compute the angle between
+      51             : distance of atoms 15 and 20 and the z axis and keeping it close to zero.
+      52             : \plumedfile
+      53             : a: FIXEDATOM AT=0,0,0
+      54             : b: FIXEDATOM AT=0,0,1
+      55             : an: ANGLE ATOMS=a,b,15,20
+      56             : RESTRAINT ARG=an AT=0.0 KAPPA=100.0
+      57             : \endplumedfile
+      58             : 
+      59             : The following input instructs plumed to align a protein to a template
+      60             : and to then compute the distance between one of the atoms in the protein and the point
+      61             : (10,20,30).
+      62             : \plumedfile
+      63             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
+      64             : a: FIXEDATOM AT=10,20,30
+      65             : d: DISTANCE ATOMS=a,20
+      66             : PRINT ARG=d FILE=colvar
+      67             : \endplumedfile
+      68             : 
+      69             : The reference structure to align to is provided in a pdb file called ref.pdb as shown below:
+      70             : 
+      71             : \auxfile{ref.pdb}
+      72             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      73             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      74             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : END
+      78             : \endauxfile
+      79             : 
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : 
+      85             : class FixedAtom:
+      86             :   public ActionWithVirtualAtom
+      87             : {
+      88             :   Vector coord;
+      89             :   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       12522 : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
+      98             : 
+      99          11 : void FixedAtom::registerKeywords(Keywords& keys) {
+     100          11 :   ActionWithVirtualAtom::registerKeywords(keys);
+     101          22 :   keys.add("compulsory","AT","coordinates of the virtual atom");
+     102          22 :   keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
+     103          22 :   keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
+     104          22 :   keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
+     105          11 : }
+     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.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func-sort-c.html b/coverage/vatom/Ghost.cpp.func-sort-c.html new file mode 100644 index 0000000000..ebf2071d37 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe626createERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD5vatom5Ghost9calculateEv7
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func.html b/coverage/vatom/Ghost.cpp.func.html new file mode 100644 index 0000000000..e4d49460f4 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe626createERKNS_13ActionOptionsE3
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62C2Ev4168
_ZN4PLMD5vatom12_GLOBAL__N_117GhostRegisterMe62D2Ev4168
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD5vatom5Ghost9calculateEv7
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.gcov.html b/coverage/vatom/Ghost.cpp.gcov.html new file mode 100644 index 0000000000..128073acd3 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.gcov.html @@ -0,0 +1,260 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(Ghost,"GHOST")
+      63             : 
+      64           5 : void Ghost::registerKeywords(Keywords& keys) {
+      65           5 :   ActionWithVirtualAtom::registerKeywords(keys);
+      66          10 :   keys.add("atoms","COORDINATES","coordinates of the ghost atom in the local reference frame");
+      67           5 : }
+      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.16
+
+ + + diff --git a/coverage/vatom/index-sort-f.html b/coverage/vatom/index-sort-f.html new file mode 100644 index 0000000000..12d3fb083e --- /dev/null +++ b/coverage/vatom/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22122399.1 %
Date:2024-05-27 13:05: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 +
98.4%98.4%
+
98.4 %120 / 12290.0 %9 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index-sort-l.html b/coverage/vatom/index-sort-l.html new file mode 100644 index 0000000000..27bf9b3af9 --- /dev/null +++ b/coverage/vatom/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22122399.1 %
Date:2024-05-27 13:05:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
98.4%98.4%
+
98.4 %120 / 12290.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.16
+
+ + + diff --git a/coverage/vatom/index.html b/coverage/vatom/index.html new file mode 100644 index 0000000000..96d9980550 --- /dev/null +++ b/coverage/vatom/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22122399.1 %
Date:2024-05-27 13:05:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
98.4%98.4%
+
98.4 %120 / 12290.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.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html new file mode 100644 index 0000000000..c9877ef805 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99D2Ev4168
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func.html b/coverage/ves/BF_Chebyshev.cpp.func.html new file mode 100644 index 0000000000..71e1a8e0bd --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe996createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_ChebyshevRegisterMe99D2Ev4168
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.gcov.html b/coverage/ves/BF_Chebyshev.cpp.gcov.html new file mode 100644 index 0000000000..faf2e5562e --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(BF_Chebyshev,"BF_CHEBYSHEV")
+     100             : 
+     101             : 
+     102           6 : void BF_Chebyshev::registerKeywords(Keywords& keys) {
+     103           6 :   BasisFunctions::registerKeywords(keys);
+     104           6 : }
+     105             : 
+     106           4 : BF_Chebyshev::BF_Chebyshev(const ActionOptions&ao):
+     107           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     108             : {
+     109           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     110           8 :   setIntrinsicInterval("-1.0","+1.0");
+     111             :   setNonPeriodic();
+     112             :   setIntervalBounded();
+     113           4 :   setType("chebyshev-1st-kind");
+     114           4 :   setDescription("Chebyshev polynomials of the first kind");
+     115           4 :   setLabelPrefix("T");
+     116           4 :   setupBF();
+     117           4 :   checkRead();
+     118           4 : }
+     119             : 
+     120             : 
+     121        7882 : void BF_Chebyshev::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     122             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     123             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     124        7882 :   inside_range=true;
+     125        7882 :   argT=translateArgument(arg, inside_range);
+     126        7882 :   std::vector<double> derivsT(derivs.size());
+     127             :   //
+     128        7882 :   values[0]=1.0;
+     129        7882 :   derivsT[0]=0.0;
+     130        7882 :   derivs[0]=0.0;
+     131        7882 :   values[1]=argT;
+     132        7882 :   derivsT[1]=1.0;
+     133        7882 :   derivs[1]=intervalDerivf();
+     134      135100 :   for(unsigned int i=1; i < getOrder(); i++) {
+     135      127218 :     values[i+1]  = 2.0*argT*values[i]-values[i-1];
+     136      127218 :     derivsT[i+1] = 2.0*values[i]+2.0*argT*derivsT[i]-derivsT[i-1];
+     137      127218 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     138             :   }
+     139        9906 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     140        7882 : }
+     141             : 
+     142             : 
+     143           3 : void BF_Chebyshev::setupUniformIntegrals() {
+     144          56 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     145          53 :     double io = i;
+     146             :     double value = 0.0;
+     147          53 :     if(i % 2 == 0) {
+     148          28 :       value = -2.0/( pow(io,2.0)-1.0)*0.5;
+     149             :     }
+     150             :     setUniformIntegral(i,value);
+     151             :   }
+     152           3 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func-sort-c.html b/coverage/ves/BF_Combined.cpp.func-sort-c.html new file mode 100644 index 0000000000..109ca8053c --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func.html b/coverage/ves/BF_Combined.cpp.func.html new file mode 100644 index 0000000000..1d22dd4743 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe776createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_123BF_CombinedRegisterMe77D2Ev4168
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.gcov.html b/coverage/ves/BF_Combined.cpp.gcov.html new file mode 100644 index 0000000000..70f1bf48ff --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(BF_Combined,"BF_COMBINED")
+      78             : 
+      79             : 
+      80           4 : void BF_Combined::registerKeywords(Keywords& keys) {
+      81           4 :   BasisFunctions::registerKeywords(keys);
+      82           4 :   keys.remove("ORDER");
+      83           4 :   keys.remove("MAXIMUM");
+      84           4 :   keys.remove("MINIMUM");
+      85           4 :   keys.remove("NUMERICAL_INTEGRALS");
+      86           4 :   keys.remove("NGRID_POINTS");
+      87           8 :   keys.add("compulsory","BASIS_FUNCTIONS","Labels of the basis functions that should be combined. Note that the order used matters for the ordering of the basis functions. This needs to be kept in mind when restarting from previous coefficients.");
+      88           4 : }
+      89             : 
+      90             : 
+      91           2 : BF_Combined::BF_Combined(const ActionOptions&ao):
+      92             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+      93           2 :   basisf_pntrs_(0)
+      94             : {
+      95             :   std::vector<std::string> basisf_labels;
+      96           6 :   parseVector("BASIS_FUNCTIONS",basisf_labels); addKeywordToList("BASIS_FUNCTIONS",basisf_labels);
+      97           2 :   if(basisf_labels.size()==1) {
+      98           0 :     plumed_merror("using only one basis function in BF_COMBINED does not make sense");
+      99             :   }
+     100           2 :   std::string error_msg = "";
+     101           4 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     102           2 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     103             : 
+     104             :   unsigned int nbasisf_total_ = 1;
+     105             :   bool periodic = true;
+     106           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     107           5 :     nbasisf_total_ += basisf_pntrs_[i]->getNumberOfBasisFunctions() - 1;
+     108          15 :     if(basisf_pntrs_[i]->intervalMinStr()!=basisf_pntrs_[0]->intervalMinStr() || basisf_pntrs_[i]->intervalMaxStr()!=basisf_pntrs_[0]->intervalMaxStr()) {
+     109           0 :       plumed_merror("all the basis functions to be combined should have same MINIMUM and MAXIMUM");
+     110             :     }
+     111           5 :     if(!basisf_pntrs_[i]->arePeriodic()) {periodic=false;}
+     112             :   }
+     113           2 :   setOrder(nbasisf_total_-1);
+     114           2 :   setNumberOfBasisFunctions(nbasisf_total_);
+     115           4 :   setInterval(basisf_pntrs_[0]->intervalMinStr(),basisf_pntrs_[0]->intervalMaxStr());
+     116           4 :   setIntrinsicInterval("-1.0","+1.0");
+     117           2 :   if(periodic) {setPeriodic();}
+     118             :   else {setNonPeriodic();}
+     119             :   setIntervalBounded();
+     120           2 :   setType("combined");
+     121           2 :   setDescription("Combined");
+     122           2 :   setupBF();
+     123           2 :   checkRead();
+     124           2 : }
+     125             : 
+     126             : 
+     127             : // void BF_Combined::getBFandValueIndices(const unsigned int n, unsigned int& bf_index, unsigned int& value_index) const {
+     128             : //   bf_index = 0; value_index = 0;
+     129             : //   if(n==0){
+     130             : //     bf_index = 0;
+     131             : //     value_index = 0;
+     132             : //     return;
+     133             : //   }
+     134             : //   else{
+     135             : //     unsigned int r=1;
+     136             : //     for(unsigned int i=0; i<basisf_pntrs_.size(); i++){
+     137             : //       for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++){
+     138             : //         if(r==n){
+     139             : //           bf_index = i;
+     140             : //           value_index = l;
+     141             : //           return;
+     142             : //         }
+     143             : //         r++;
+     144             : //       }
+     145             : //     }
+     146             : //   }
+     147             : // }
+     148             : 
+     149             : 
+     150        3616 : void BF_Combined::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     151             :   // first BF, constant, argT, and inside_range taken from here
+     152             :   unsigned int r=0;
+     153        3616 :   std::vector<double> values_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     154        3616 :   std::vector<double> derivs_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     155        3616 :   basisf_pntrs_[0]->getAllValues(arg,argT,inside_range,values_tmp,derivs_tmp);
+     156       43392 :   for(unsigned int l=0; l<basisf_pntrs_[0]->numberOfBasisFunctions(); l++) {
+     157       39776 :     values[r] = values_tmp[l];
+     158       39776 :     derivs[r] = derivs_tmp[l];
+     159       39776 :     r++;
+     160             :   }
+     161             :   // other BF
+     162        9043 :   for(unsigned int i=1; i<basisf_pntrs_.size(); i++) {
+     163        5427 :     values_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     164        5427 :     derivs_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     165        5427 :     double dummy_dbl; bool dummy_bool=true;
+     166        5427 :     basisf_pntrs_[i]->getAllValues(arg,dummy_dbl,dummy_bool,values_tmp,derivs_tmp);
+     167       59697 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     168       54270 :       values[r] = values_tmp[l];
+     169       54270 :       derivs[r] = derivs_tmp[l];
+     170       54270 :       r++;
+     171             :     }
+     172             :   }
+     173        3616 : }
+     174             : 
+     175             : 
+     176           2 : void BF_Combined::setupLabels() {
+     177           2 :   setLabel(0,basisf_pntrs_[0]->getBasisFunctionLabel(0));
+     178             :   unsigned int r=1;
+     179           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     180          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     181          50 :       setLabel(r,basisf_pntrs_[i]->getBasisFunctionLabel(l));
+     182          50 :       r++;
+     183             :     }
+     184             :   }
+     185           2 : }
+     186             : 
+     187             : 
+     188           2 : void BF_Combined::setupUniformIntegrals() {
+     189           2 :   setUniformIntegral(0,basisf_pntrs_[0]->getUniformIntegrals()[0]);
+     190             :   unsigned int r=1;
+     191           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     192           5 :     std::vector<double> uniform_tmp = basisf_pntrs_[i]->getUniformIntegrals();
+     193          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     194          50 :       setUniformIntegral(r,uniform_tmp[l]);
+     195          50 :       r++;
+     196             :     }
+     197             :   }
+     198           2 : }
+     199             : 
+     200             : 
+     201             : }
+     202             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func-sort-c.html b/coverage/ves/BF_Cosine.cpp.func-sort-c.html new file mode 100644 index 0000000000..da8123c240 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94D2Ev4168
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func.html b/coverage/ves/BF_Cosine.cpp.func.html new file mode 100644 index 0000000000..22fe026e94 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe946createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121BF_CosineRegisterMe94D2Ev4168
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.gcov.html b/coverage/ves/BF_Cosine.cpp.gcov.html new file mode 100644 index 0000000000..2963c372b8 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(BF_Cosine,"BF_COSINE")
+      95             : 
+      96             : 
+      97           6 : void BF_Cosine::registerKeywords(Keywords& keys) {
+      98           6 :   BasisFunctions::registerKeywords(keys);
+      99           6 : }
+     100             : 
+     101             : 
+     102           4 : BF_Cosine::BF_Cosine(const ActionOptions&ao):
+     103           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     104             : {
+     105           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     106           8 :   setIntrinsicInterval("-pi","+pi");
+     107             :   setPeriodic();
+     108             :   setIntervalBounded();
+     109           4 :   setType("trigonometric_cos");
+     110           4 :   setDescription("Cosine");
+     111           4 :   setupBF();
+     112           4 :   checkRead();
+     113           4 : }
+     114             : 
+     115             : 
+     116        9229 : void BF_Cosine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     117             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     118             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     119        9229 :   inside_range=true;
+     120        9229 :   argT=translateArgument(arg, inside_range);
+     121        9229 :   values[0]=1.0;
+     122        9229 :   derivs[0]=0.0;
+     123      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     124       92290 :     double io = i;
+     125       92290 :     double cos_tmp = cos(io*argT);
+     126       92290 :     double sin_tmp = sin(io*argT);
+     127       92290 :     values[i] = cos_tmp;
+     128       92290 :     derivs[i] = -io*sin_tmp*intervalDerivf();
+     129             :   }
+     130        9229 :   if(!inside_range) {
+     131         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     132             :   }
+     133        9229 : }
+     134             : 
+     135             : 
+     136           4 : void BF_Cosine::setupLabels() {
+     137           4 :   setLabel(0,"1");
+     138          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          40 :     std::string is; Tools::convert(i,is);
+     140          80 :     setLabel(i,"cos("+is+"*s)");
+     141             :   }
+     142           4 : }
+     143             : 
+     144             : 
+     145           3 : void BF_Cosine::setupUniformIntegrals() {
+     146           3 :   setAllUniformIntegralsToZero();
+     147             :   setUniformIntegral(0,1.0);
+     148           3 : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html new file mode 100644 index 0000000000..a6eea40640 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99D2Ev4168
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func.html b/coverage/ves/BF_CubicBsplines.cpp.func.html new file mode 100644 index 0000000000..4bbcfa2855 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe996createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_128BF_CubicBsplinesRegisterMe99D2Ev4168
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.gcov.html b/coverage/ves/BF_CubicBsplines.cpp.gcov.html new file mode 100644 index 0000000000..cb7141db5e --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.gcov.html @@ -0,0 +1,277 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_ACTION(BF_CubicBsplines,"BF_CUBIC_B_SPLINES")
+     100             : 
+     101             : // See DOI 10.1007/s10614-007-9092-4 for more information;
+     102             : 
+     103             : 
+     104           5 : void BF_CubicBsplines::registerKeywords(Keywords& keys) {
+     105           5 :   BasisFunctions::registerKeywords(keys);
+     106          10 :   keys.add("optional","NORMALIZATION","the normalization factor that is used to normalize the basis functions by dividing the values. By default it is 2.");
+     107          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     108           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     109           5 : }
+     110             : 
+     111           3 : BF_CubicBsplines::BF_CubicBsplines(const ActionOptions&ao):
+     112           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     113             : {
+     114           3 :   log.printf("  Cubic B spline basis functions, see and cite ");
+     115           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     116             : 
+     117           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     118           3 :   spacing_=(intervalMax()-intervalMin())/static_cast<double>(getOrder());
+     119           3 :   inv_spacing_ = 1.0/spacing_;
+     120             : 
+     121           3 :   bool periodic = false;
+     122           3 :   parseFlag("PERIODIC",periodic);
+     123           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     124             : 
+     125             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     126           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     127           3 :   setNumberOfBasisFunctions(num_BFs);
+     128             : 
+     129           3 :   double normfactor_=2.0;
+     130           3 :   parse("NORMALIZATION",normfactor_);
+     131           3 :   if(normfactor_!=2.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     132           3 :   inv_normfactor_=1.0/normfactor_;
+     133             : 
+     134           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     135             :   setIntervalBounded();
+     136           3 :   setType("splines_2nd-order");
+     137           3 :   setDescription("Cubic B-splines (2nd order splines)");
+     138           3 :   setLabelPrefix("S");
+     139           3 :   setupBF();
+     140           3 :   log.printf("   normalization factor: %f\n",normfactor_);
+     141           3 :   checkRead();
+     142           3 : }
+     143             : 
+     144             : 
+     145        9236 : void BF_CubicBsplines::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     146             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     147             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     148        9236 :   inside_range=true;
+     149        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     150             :   //
+     151        9236 :   values[0]=1.0;
+     152        9236 :   derivs[0]=0.0;
+     153             :   //
+     154      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     155      202807 :     double argx = ((argT-intervalMin())*inv_spacing_) - (static_cast<double>(i) - 2.0);
+     156      202807 :     if(arePeriodic()) { // periodic range of argx is [-intervalRange/spacing,+intervalRange/spacing]
+     157       64140 :       argx /= intervalRange()*inv_spacing_;
+     158       64140 :       argx = Tools::pbc(argx);
+     159       64140 :       argx *= (intervalRange()*inv_spacing_);
+     160             :     }
+     161      202807 :     values[i] = spline(argx, derivs[i]);
+     162      202807 :     derivs[i] *= inv_spacing_;
+     163             :   }
+     164       11156 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     165        9236 : }
+     166             : 
+     167             : 
+     168      202807 : double BF_CubicBsplines::spline(const double arg, double& deriv) const {
+     169             :   double value=0.0;
+     170             :   double x=arg;
+     171             :   // derivative of abs(x);
+     172             :   double dx = 1.0;
+     173      202807 :   if(x < 0) {
+     174      101208 :     x=-x;
+     175             :     dx = -1.0;
+     176             :   }
+     177             :   //
+     178      202807 :   if(x > 2) {
+     179             :     value=0.0;
+     180      165556 :     deriv=0.0;
+     181             :   }
+     182       37251 :   else if(x >= 1) {
+     183       18896 :     value = ((2.0-x)*(2.0-x)*(2.0-x));
+     184       18896 :     deriv = dx*(-3.0*(2.0-x)*(2.0-x));
+     185             :     // value=((2.0-x)*(2.0-x)*(2.0-x))/6.0;
+     186             :     // deriv=-x*x*(2.0-x)*(2.0-x);
+     187             :   }
+     188             :   else {
+     189       18355 :     value = 4.0-6.0*x*x+3.0*x*x*x;
+     190       18355 :     deriv = dx*(-12.0*x+9.0*x*x);
+     191             :     // value=x*x*x*0.5-x*x+2.0/3.0;
+     192             :     // deriv=(3.0/2.0)*x*x-2.0*x;
+     193             :   }
+     194      202807 :   value *= inv_normfactor_;
+     195      202807 :   deriv *= inv_normfactor_;
+     196      202807 :   return value;
+     197             : }
+     198             : 
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func-sort-c.html b/coverage/ves/BF_Custom.cpp.func-sort-c.html new file mode 100644 index 0000000000..ba3faf4bc8 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE12
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126D2Ev4168
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func.html b/coverage/ves/BF_Custom.cpp.func.html new file mode 100644 index 0000000000..9ca97e38b9 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe1266createERKNS_13ActionOptionsE10
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122BF_CustomRegisterMe126D2Ev4168
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.gcov.html b/coverage/ves/BF_Custom.cpp.gcov.html new file mode 100644 index 0000000000..e3e3dc16bf --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + 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-05-27 13:05: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       12514 : PLUMED_REGISTER_ACTION(BF_Custom,"BF_CUSTOM")
+     127             : 
+     128          12 : void BF_Custom::registerKeywords(Keywords& keys) {
+     129          12 :   BasisFunctions::registerKeywords(keys);
+     130          12 :   keys.remove("ORDER");
+     131          24 :   keys.add("numbered","FUNC","The basis functions f_i(x) given in mathematical expressions using _x_ as a variable.");
+     132          24 :   keys.add("optional","TRANSFORM","An optional function that can be used to transform the argument before calculating the basis function values. You should use _t_ as a variable. You can use the variables _min_ and _max_ to give the minimum and the maximum of the interval.");
+     133          24 :   keys.addFlag("PERIODIC",false,"Indicate that the basis functions are periodic.");
+     134          24 :   keys.addFlag("CHECK_NAN_INF",false,"Check that the basis functions do not result in a not a number (nan) or infinity (inf).");
+     135          12 :   keys.remove("NUMERICAL_INTEGRALS");
+     136          12 : }
+     137             : 
+     138             : 
+     139          10 : BF_Custom::BF_Custom(const ActionOptions&ao):
+     140             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     141          10 :   transf_value_lepton_ref_(nullptr),
+     142          10 :   transf_deriv_lepton_ref_(nullptr),
+     143          10 :   bf_values_expressions_(0),
+     144          10 :   bf_derivs_expressions_(0),
+     145          10 :   bf_values_lepton_ref_(0,nullptr),
+     146          10 :   bf_derivs_lepton_ref_(0,nullptr),
+     147          10 :   variable_str_("x"),
+     148          10 :   transf_variable_str_("t"),
+     149          10 :   do_transf_(false),
+     150          20 :   check_nan_inf_(false)
+     151             : {
+     152             :   std::vector<std::string> bf_str;
+     153          10 :   std::string str_t1="1";
+     154          10 :   bf_str.push_back(str_t1);
+     155          10 :   for(int i=1;; i++) {
+     156             :     std::string str_t2;
+     157         112 :     if(!parseNumbered("FUNC",i,str_t2)) {break;}
+     158          46 :     std::string is; Tools::convert(i,is);
+     159          92 :     addKeywordToList("FUNC"+is,str_t2);
+     160          46 :     bf_str.push_back(str_t2);
+     161          46 :   }
+     162             :   //
+     163          10 :   if(bf_str.size()==1) {plumed_merror(getName()+" with label "+getLabel()+": No FUNC keywords given");}
+     164             : 
+     165          10 :   setOrder(bf_str.size()-1);
+     166          10 :   setNumberOfBasisFunctions(getOrder()+1);
+     167          10 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     168          10 :   bool periodic = false;
+     169          20 :   parseFlag("PERIODIC",periodic); addKeywordToList("PERIODIC",periodic);
+     170          10 :   if(periodic) {setPeriodic();}
+     171             :   else {setNonPeriodic();}
+     172             :   setIntervalBounded();
+     173          10 :   setType("custom_functions");
+     174          20 :   setDescription("Custom Functions");
+     175             :   //
+     176          10 :   std::vector<std::string> bf_values_parsed(getNumberOfBasisFunctions());
+     177          10 :   std::vector<std::string> bf_derivs_parsed(getNumberOfBasisFunctions());
+     178             :   bf_values_parsed[0] = "1";
+     179             :   bf_derivs_parsed[0] = "0";
+     180             :   //
+     181          10 :   bf_values_expressions_.resize(getNumberOfBasisFunctions());
+     182          10 :   bf_derivs_expressions_.resize(getNumberOfBasisFunctions());
+     183          10 :   bf_values_lepton_ref_.resize(getNumberOfBasisFunctions());
+     184          10 :   bf_derivs_lepton_ref_.resize(getNumberOfBasisFunctions());
+     185             :   //
+     186          56 :   for(unsigned int i=1; i<getNumberOfBasisFunctions(); i++) {
+     187          46 :     std::string is; Tools::convert(i,is);
+     188             :     try {
+     189          46 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(bf_str[i]).optimize(lepton::Constants());
+     190          46 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     191          46 :       bf_values_parsed[i] = tmp_stream.str();
+     192          46 :       bf_values_expressions_[i] = pe_value.createCompiledExpression();
+     193          46 :     }
+     194           0 :     catch(PLMD::lepton::Exception& exc) {
+     195           0 :       plumed_merror("There was some problem in parsing the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     196           0 :     }
+     197             : 
+     198             :     std::vector<std::string> var_str;
+     199          92 :     for(auto &p: bf_values_expressions_[i].getVariables()) {
+     200          46 :       var_str.push_back(p);
+     201             :     }
+     202          46 :     if(var_str.size()!=1) {
+     203           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": there should only be one variable");
+     204             :     }
+     205          46 :     if(var_str[0]!=variable_str_) {
+     206           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": you should use "+variable_str_+" as a variable");
+     207             :     }
+     208             : 
+     209             :     try {
+     210          92 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(bf_str[i]).differentiate(variable_str_).optimize(lepton::Constants());
+     211          46 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     212          46 :       bf_derivs_parsed[i] = tmp_stream2.str();
+     213          46 :       bf_derivs_expressions_[i] = pe_deriv.createCompiledExpression();
+     214          46 :     }
+     215           0 :     catch(PLMD::lepton::Exception& exc) {
+     216           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     217           0 :     }
+     218             : 
+     219             :     try {
+     220          46 :       bf_values_lepton_ref_[i] = &bf_values_expressions_[i].getVariableReference(variable_str_);
+     221           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     222             : 
+     223             :     try {
+     224          46 :       bf_derivs_lepton_ref_[i] = &bf_derivs_expressions_[i].getVariableReference(variable_str_);
+     225           8 :     } catch(PLMD::lepton::Exception& exc) {}
+     226             : 
+     227          46 :   }
+     228             : 
+     229             :   std::string transf_value_parsed;
+     230             :   std::string transf_deriv_parsed;
+     231             :   std::string transf_str;
+     232          20 :   parse("TRANSFORM",transf_str);
+     233          10 :   if(transf_str.size()>0) {
+     234           6 :     do_transf_ = true;
+     235          12 :     addKeywordToList("TRANSFORM",transf_str);
+     236             :     for(unsigned int k=0;; k++) {
+     237          14 :       if(transf_str.find("min")!=std::string::npos) {transf_str.replace(transf_str.find("min"), std::string("min").length(),intervalMinStr());}
+     238             :       else {break;}
+     239             :     }
+     240             :     for(unsigned int k=0;; k++) {
+     241          14 :       if(transf_str.find("max")!=std::string::npos) {transf_str.replace(transf_str.find("max"), std::string("max").length(),intervalMaxStr());}
+     242             :       else {break;}
+     243             :     }
+     244             : 
+     245             :     try {
+     246           6 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(transf_str).optimize(lepton::Constants());;
+     247           6 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     248           6 :       transf_value_parsed = tmp_stream.str();
+     249           6 :       transf_value_expression_ = pe_value.createCompiledExpression();
+     250           6 :     }
+     251           0 :     catch(PLMD::lepton::Exception& exc) {
+     252           0 :       plumed_merror("There was some problem in parsing the function "+transf_str+" given in TRANSFORM with lepton");
+     253           0 :     }
+     254             : 
+     255             :     std::vector<std::string> var_str;
+     256          12 :     for(auto &p: transf_value_expression_.getVariables()) {
+     257           6 :       var_str.push_back(p);
+     258             :     }
+     259           6 :     if(var_str.size()!=1) {
+     260           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: there should only be one variable");
+     261             :     }
+     262           6 :     if(var_str[0]!=transf_variable_str_) {
+     263           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: you should use "+transf_variable_str_+" as a variable");
+     264             :     }
+     265             : 
+     266             :     try {
+     267          12 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(transf_str).differentiate(transf_variable_str_).optimize(lepton::Constants());;
+     268           6 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     269           6 :       transf_deriv_parsed = tmp_stream2.str();
+     270           6 :       transf_deriv_expression_ = pe_deriv.createCompiledExpression();
+     271           6 :     }
+     272           0 :     catch(PLMD::lepton::Exception& exc) {
+     273           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+transf_str+" given in TRANSFORM with lepton");
+     274           0 :     }
+     275             : 
+     276             :     try {
+     277           6 :       transf_value_lepton_ref_ = &transf_value_expression_.getVariableReference(transf_variable_str_);
+     278           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     279             : 
+     280             :     try {
+     281           6 :       transf_deriv_lepton_ref_ = &transf_deriv_expression_.getVariableReference(transf_variable_str_);
+     282           3 :     } catch(PLMD::lepton::Exception& exc) {}
+     283             : 
+     284           6 :   }
+     285             :   //
+     286          10 :   log.printf("  Using the following functions [lepton parsed function and derivative]:\n");
+     287          66 :   for(unsigned int i=0; i<getNumberOfBasisFunctions(); i++) {
+     288          56 :     log.printf("   %u:  %s   [   %s   |   %s   ] \n",i,bf_str[i].c_str(),bf_values_parsed[i].c_str(),bf_derivs_parsed[i].c_str());
+     289             : 
+     290             :   }
+     291             :   //
+     292          10 :   if(do_transf_) {
+     293           6 :     log.printf("  Arguments are transformed using the following function [lepton parsed function and derivative]:\n");
+     294           6 :     log.printf("   %s   [   %s   |   %s   ] \n",transf_str.c_str(),transf_value_parsed.c_str(),transf_deriv_parsed.c_str());
+     295             :   }
+     296             :   else {
+     297           4 :     log.printf("  Arguments are not transformed\n");
+     298             :   }
+     299             :   //
+     300             : 
+     301          20 :   parseFlag("CHECK_NAN_INF",check_nan_inf_); addKeywordToList("CHECK_NAN_INF",check_nan_inf_);
+     302          10 :   if(check_nan_inf_) {
+     303           6 :     log.printf("  The code will check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     304             :   }
+     305             :   else {
+     306           4 :     log.printf("  The code will NOT check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     307             :   }
+     308             : 
+     309          10 :   setupBF();
+     310          10 :   checkRead();
+     311          20 : }
+     312             : 
+     313             : 
+     314       24204 : void BF_Custom::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     315       24204 :   inside_range=true;
+     316       24204 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     317       24204 :   double transf_derivf=1.0;
+     318             :   //
+     319       24204 :   if(do_transf_) {
+     320             : 
+     321       14062 :     if(transf_value_lepton_ref_) {*transf_value_lepton_ref_ = argT;}
+     322       14062 :     if(transf_deriv_lepton_ref_) {*transf_deriv_lepton_ref_ = argT;}
+     323             : 
+     324       14062 :     argT = transf_value_expression_.evaluate();
+     325       14062 :     transf_derivf = transf_deriv_expression_.evaluate();
+     326             : 
+     327       14062 :     if(check_nan_inf_ && (std::isnan(argT) || std::isinf(argT)) ) {
+     328           0 :       std::string vs; Tools::convert(argT,vs);
+     329           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, it gives " + vs);
+     330             :     }
+     331             : 
+     332       14062 :     if(check_nan_inf_ && (std::isnan(transf_derivf) || std::isinf(transf_derivf)) ) {
+     333           0 :       std::string vs; Tools::convert(transf_derivf,vs);
+     334           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, its derivative gives " + vs);
+     335             :     }
+     336             :   }
+     337             :   //
+     338       24204 :   values[0]=1.0;
+     339       24204 :   derivs[0]=0.0;
+     340      137488 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     341             : 
+     342      113284 :     if(bf_values_lepton_ref_[i]) {*bf_values_lepton_ref_[i] = argT;}
+     343      113284 :     if(bf_derivs_lepton_ref_[i]) {*bf_derivs_lepton_ref_[i] = argT;}
+     344             : 
+     345      113284 :     values[i] = bf_values_expressions_[i].evaluate();
+     346      113284 :     derivs[i] = bf_derivs_expressions_[i].evaluate();
+     347             : 
+     348      113284 :     if(do_transf_) {derivs[i]*=transf_derivf;}
+     349             :     // NaN checks
+     350      113284 :     if(check_nan_inf_ && (std::isnan(values[i]) || std::isinf(values[i])) ) {
+     351           0 :       std::string vs; Tools::convert(values[i],vs);
+     352           0 :       std::string is; Tools::convert(i,is);
+     353           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the basis function given in FUNC"+is+", it gives "+vs);
+     354             :     }
+     355             :     //
+     356      113284 :     if(check_nan_inf_ && (std::isnan(derivs[i])|| std::isinf(derivs[i])) ) {
+     357             :       std::string vs; Tools::convert(derivs[i],vs);
+     358           0 :       std::string is; Tools::convert(i,is);
+     359           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with derivative of the basis function given in FUNC"+is+", it gives "+vs);
+     360             :     }
+     361             :   }
+     362       26218 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     363       24204 : }
+     364             : 
+     365             : 
+     366             : 
+     367             : 
+     368             : }
+     369             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func-sort-c.html b/coverage/ves/BF_Fourier.cpp.func-sort-c.html new file mode 100644 index 0000000000..4417ae98d4 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE97
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95D2Ev4168
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func.html b/coverage/ves/BF_Fourier.cpp.func.html new file mode 100644 index 0000000000..9432708891 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE97
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe956createERKNS_13ActionOptionsE95
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122BF_FourierRegisterMe95D2Ev4168
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.gcov.html b/coverage/ves/BF_Fourier.cpp.gcov.html new file mode 100644 index 0000000000..930326bbfd --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + 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-05-27 13:05: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       12599 : PLUMED_REGISTER_ACTION(BF_Fourier,"BF_FOURIER")
+      96             : 
+      97             : 
+      98          97 : void BF_Fourier::registerKeywords(Keywords& keys) {
+      99          97 :   BasisFunctions::registerKeywords(keys);
+     100          97 : }
+     101             : 
+     102             : 
+     103          95 : BF_Fourier::BF_Fourier(const ActionOptions&ao):
+     104          95 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     105             : {
+     106          95 :   setNumberOfBasisFunctions(2*getOrder()+1);
+     107         190 :   setIntrinsicInterval("-pi","+pi");
+     108             :   setPeriodic();
+     109             :   setIntervalBounded();
+     110          95 :   setType("trigonometric_cos-sin");
+     111          95 :   setDescription("Trigonometric (cos/sin)");
+     112          95 :   setupBF();
+     113          95 :   checkRead();
+     114          95 : }
+     115             : 
+     116             : 
+     117     3244265 : void BF_Fourier::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     118             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     119             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     120     3244265 :   inside_range=true;
+     121     3244265 :   argT=translateArgument(arg, inside_range);
+     122     3244265 :   values[0]=1.0;
+     123     3244265 :   derivs[0]=0.0;
+     124    17806383 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     125    14562118 :     double io = i;
+     126    14562118 :     double cos_tmp = cos(io*argT);
+     127    14562118 :     double sin_tmp = sin(io*argT);
+     128    14562118 :     values[2*i-1] = cos_tmp;
+     129    14562118 :     derivs[2*i-1] = -io*sin_tmp*intervalDerivf();
+     130    14562118 :     values[2*i] = sin_tmp;
+     131    14562118 :     derivs[2*i] = io*cos_tmp*intervalDerivf();
+     132             :   }
+     133     3244265 :   if(!inside_range) {
+     134       23980 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     135             :   }
+     136     3244265 : }
+     137             : 
+     138             : 
+     139          95 : void BF_Fourier::setupLabels() {
+     140          95 :   setLabel(0,"1");
+     141         568 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     142         473 :     std::string is; Tools::convert(i,is);
+     143         946 :     setLabel(2*i-1,"cos("+is+"*s)");
+     144         946 :     setLabel(2*i,"sin("+is+"*s)");
+     145             :   }
+     146          95 : }
+     147             : 
+     148             : 
+     149          94 : void BF_Fourier::setupUniformIntegrals() {
+     150          94 :   setAllUniformIntegralsToZero();
+     151             :   setUniformIntegral(0,1.0);
+     152          94 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func-sort-c.html b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html new file mode 100644 index 0000000000..dcd546cd67 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114D2Ev4168
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func.html b/coverage/ves/BF_Gaussians.cpp.func.html new file mode 100644 index 0000000000..9ccfdbd4b4 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe1146createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_125BF_GaussiansRegisterMe114D2Ev4168
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.gcov.html b/coverage/ves/BF_Gaussians.cpp.gcov.html new file mode 100644 index 0000000000..fc0764093f --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.gcov.html @@ -0,0 +1,265 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_ACTION(BF_Gaussians,"BF_GAUSSIANS")
+     115             : 
+     116             : 
+     117           5 : void BF_Gaussians::registerKeywords(Keywords& keys) {
+     118           5 :   BasisFunctions::registerKeywords(keys);
+     119          10 :   keys.add("optional","WIDTH","The width (i.e. standart deviation) of the Gaussian functions. By default it is equal to the sub-intervall size.");
+     120          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     121           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     122           5 : }
+     123             : 
+     124           3 : BF_Gaussians::BF_Gaussians(const ActionOptions&ao):
+     125           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     126             : {
+     127           3 :   log.printf("  Gaussian basis functions, see and cite ");
+     128           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     129             : 
+     130           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     131             : 
+     132           3 :   double width = (intervalMax()-intervalMin()) / getOrder();
+     133           3 :   parse("WIDTH",width);
+     134           3 :   if(width <= 0.0) {plumed_merror("WIDTH should be larger than 0");}
+     135           4 :   if(width != (intervalMax()-intervalMin())/getOrder()) {addKeywordToList("WIDTH",width);}
+     136           3 :   inv_sigma_ = 1/(width);
+     137             : 
+     138           3 :   bool periodic = false;
+     139           3 :   parseFlag("PERIODIC",periodic);
+     140           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     141             : 
+     142             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     143           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     144           3 :   setNumberOfBasisFunctions(num_BFs);
+     145             : 
+     146           3 :   centers_.push_back(0.0); // constant one
+     147          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     148          66 :     centers_.push_back(intervalMin()+(static_cast<int>(i) - 1 - static_cast<int>(!periodic))*(intervalMax()-intervalMin())/getOrder());
+     149             :   }
+     150           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     151             :   setIntervalBounded();
+     152           3 :   setType("gaussian_functions");
+     153           3 :   setDescription("Gaussian functions with shifted centers that are being optimized in their height");
+     154           3 :   setupBF();
+     155           3 :   log.printf("   width: %f\n",width);
+     156           3 :   checkRead();
+     157           3 : }
+     158             : 
+     159             : 
+     160        9236 : void BF_Gaussians::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     161        9236 :   inside_range=true;
+     162        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     163        9236 :   values[0]=1.0;
+     164        9236 :   derivs[0]=0.0;
+     165      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     166      202807 :     double dist = argT - centers_[i];
+     167      202807 :     if(arePeriodic()) { // wrap around similar to MetaD
+     168       64140 :       dist /= intervalRange();
+     169       64140 :       dist = Tools::pbc(dist);
+     170       64140 :       dist *= intervalRange();
+     171             :     }
+     172      202807 :     values[i] = exp(-0.5*pow(dist*inv_sigma_,2.0));
+     173      202807 :     derivs[i] = -values[i] * (dist)*pow(inv_sigma_,2.0);
+     174             :   }
+     175       11156 :   if(!inside_range) {for (auto& d: derivs) {d=0.0;}}
+     176        9236 : }
+     177             : 
+     178             : 
+     179             : // label according to position of mean
+     180           3 : void BF_Gaussians::setupLabels() {
+     181           3 :   setLabel(0,"const");
+     182          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     183          66 :     std::string is; Tools::convert(centers_[i],is);
+     184         132 :     setLabel(i,"m="+is);
+     185             :   }
+     186           3 : }
+     187             : 
+     188             : }
+     189             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func-sort-c.html b/coverage/ves/BF_Legendre.cpp.func-sort-c.html new file mode 100644 index 0000000000..1b9ad6e79e --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE63
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106D2Ev4168
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func.html b/coverage/ves/BF_Legendre.cpp.func.html new file mode 100644 index 0000000000..2a42737d59 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe1066createERKNS_13ActionOptionsE61
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_LegendreRegisterMe106D2Ev4168
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.gcov.html b/coverage/ves/BF_Legendre.cpp.gcov.html new file mode 100644 index 0000000000..5ccf9c9fbf --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.gcov.html @@ -0,0 +1,248 @@ + + + + + + + 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-05-27 13:05: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       12565 : PLUMED_REGISTER_ACTION(BF_Legendre,"BF_LEGENDRE")
+     107             : 
+     108             : 
+     109          63 : void BF_Legendre::registerKeywords(Keywords& keys) {
+     110          63 :   BasisFunctions::registerKeywords(keys);
+     111         126 :   keys.addFlag("SCALED",false,"Scale the polynomials such that they are orthonormal to 1.");
+     112          63 : }
+     113             : 
+     114          61 : BF_Legendre::BF_Legendre(const ActionOptions&ao):
+     115             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     116          61 :   scaled_(false)
+     117             : {
+     118         183 :   parseFlag("SCALED",scaled_); addKeywordToList("SCALED",scaled_);
+     119          61 :   setNumberOfBasisFunctions(getOrder()+1);
+     120         122 :   setIntrinsicInterval("-1.0","+1.0");
+     121             :   setNonPeriodic();
+     122             :   setIntervalBounded();
+     123          61 :   setType("Legendre");
+     124          61 :   setDescription("Legendre polynomials");
+     125          61 :   setLabelPrefix("L");
+     126          61 :   setupBF();
+     127          61 :   checkRead();
+     128          61 : }
+     129             : 
+     130             : 
+     131     1625057 : void BF_Legendre::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     132             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     133             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     134     1625057 :   inside_range=true;
+     135     1625057 :   argT=translateArgument(arg, inside_range);
+     136     1625057 :   std::vector<double> derivsT(derivs.size());
+     137             :   //
+     138     1625057 :   values[0]=1.0;
+     139     1625057 :   derivsT[0]=0.0;
+     140     1625057 :   derivs[0]=0.0;
+     141     1625057 :   values[1]=argT;
+     142     1625057 :   derivsT[1]=1.0;
+     143     1625057 :   derivs[1]=intervalDerivf();
+     144    15470320 :   for(unsigned int i=1; i < getOrder(); i++) {
+     145    13845263 :     double io = static_cast<double>(i);
+     146    13845263 :     values[i+1]  = ((2.0*io+1.0)/(io+1.0))*argT*values[i] - (io/(io+1.0))*values[i-1];
+     147    13845263 :     derivsT[i+1] = ((2.0*io+1.0)/(io+1.0))*(values[i]+argT*derivsT[i])-(io/(io+1.0))*derivsT[i-1];
+     148    13845263 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     149             :   }
+     150     1625057 :   if(scaled_) {
+     151             :     // L0 is also scaled!
+     152     5088852 :     for(unsigned int i=0; i<values.size(); i++) {
+     153     4632062 :       double io = static_cast<double>(i);
+     154     4632062 :       double sf = sqrt(io+0.5);
+     155     4632062 :       values[i] *= sf;
+     156     4632062 :       derivs[i] *= sf;
+     157             :     }
+     158             :   }
+     159     1756541 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     160     1625057 : }
+     161             : 
+     162             : 
+     163          59 : void BF_Legendre::setupUniformIntegrals() {
+     164          59 :   setAllUniformIntegralsToZero();
+     165             :   double L0_int = 1.0;
+     166          59 :   if(scaled_) {L0_int = sqrt(0.5);}
+     167             :   setUniformIntegral(0,L0_int);
+     168          59 : }
+     169             : 
+     170             : 
+     171             : }
+     172             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func-sort-c.html b/coverage/ves/BF_Powers.cpp.func-sort-c.html new file mode 100644 index 0000000000..4c7303a7bf --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE18
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90D2Ev4168
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func.html b/coverage/ves/BF_Powers.cpp.func.html new file mode 100644 index 0000000000..e43684588f --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe906createERKNS_13ActionOptionsE16
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121BF_PowersRegisterMe90D2Ev4168
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.gcov.html b/coverage/ves/BF_Powers.cpp.gcov.html new file mode 100644 index 0000000000..99368341af --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + 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-05-27 13:05: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       12520 : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS")
+      91             : 
+      92             : 
+      93          18 : void BF_Powers::registerKeywords(Keywords& keys) {
+      94          18 :   BasisFunctions::registerKeywords(keys);
+      95          36 :   keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0.");
+      96          18 :   keys.remove("NUMERICAL_INTEGRALS");
+      97          18 : }
+      98             : 
+      99          16 : BF_Powers::BF_Powers(const ActionOptions&ao):
+     100          16 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     101             : {
+     102          16 :   setNumberOfBasisFunctions(getOrder()+1);
+     103          16 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     104          16 :   double normfactor_=1.0;
+     105          16 :   parse("NORMALIZATION",normfactor_);
+     106          16 :   if(normfactor_!=1.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     107          16 :   inv_normfactor_=1.0/normfactor_;
+     108             :   setNonPeriodic();
+     109             :   setIntervalBounded();
+     110          16 :   setType("polynom_powers");
+     111          16 :   setDescription("Polynomial Powers");
+     112          16 :   setupBF();
+     113          16 :   log.printf("   normalization factor: %f\n",normfactor_);
+     114          16 :   checkRead();
+     115          16 : }
+     116             : 
+     117             : 
+     118      842119 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     119      842119 :   inside_range=true;
+     120      842119 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     121             :   //
+     122      842119 :   values[0]=1.0;
+     123      842119 :   derivs[0]=0.0;
+     124             :   //
+     125     4210595 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     126             :     // double io = static_cast<double>(i);
+     127             :     // values[i] = pow(argT,io);
+     128             :     // derivs[i] = io*pow(argT,io-1.0);
+     129     3368476 :     values[i] = argT*values[i-1];
+     130     3368476 :     derivs[i]=values[i-1]+argT*derivs[i-1];
+     131             :   }
+     132      842599 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     133      842119 : }
+     134             : 
+     135             : 
+     136          16 : void BF_Powers::setupLabels() {
+     137          16 :   setLabel(0,"1");
+     138          80 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          64 :     std::string is; Tools::convert(i,is);
+     140         128 :     setLabel(i,"s^"+is);
+     141             :   }
+     142          16 : }
+     143             : 
+     144             : }
+     145             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func-sort-c.html b/coverage/ves/BF_Sine.cpp.func-sort-c.html new file mode 100644 index 0000000000..51ea6c63de --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93D2Ev4168
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func.html b/coverage/ves/BF_Sine.cpp.func.html new file mode 100644 index 0000000000..5504a99fb9 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe936createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_119BF_SineRegisterMe93D2Ev4168
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.gcov.html b/coverage/ves/BF_Sine.cpp.gcov.html new file mode 100644 index 0000000000..19558b196c --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(BF_Sine,"BF_SINE")
+      94             : 
+      95             : 
+      96           6 : void BF_Sine::registerKeywords(Keywords& keys) {
+      97           6 :   BasisFunctions::registerKeywords(keys);
+      98           6 : }
+      99             : 
+     100             : 
+     101           4 : BF_Sine::BF_Sine(const ActionOptions&ao):
+     102           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     103             : {
+     104           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     105           8 :   setIntrinsicInterval("-pi","+pi");
+     106             :   setPeriodic();
+     107             :   setIntervalBounded();
+     108           4 :   setType("trigonometric_sin");
+     109           4 :   setDescription("Sine");
+     110           4 :   setupBF();
+     111           4 :   checkRead();
+     112           4 : }
+     113             : 
+     114             : 
+     115        9229 : void BF_Sine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     116             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     117             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     118        9229 :   inside_range=true;
+     119        9229 :   argT=translateArgument(arg, inside_range);
+     120        9229 :   values[0]=1.0;
+     121        9229 :   derivs[0]=0.0;
+     122      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     123       92290 :     double io = i;
+     124       92290 :     double cos_tmp = cos(io*argT);
+     125       92290 :     double sin_tmp = sin(io*argT);
+     126       92290 :     values[i] = sin_tmp;
+     127       92290 :     derivs[i] = io*cos_tmp*intervalDerivf();
+     128             :   }
+     129        9229 :   if(!inside_range) {
+     130         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     131             :   }
+     132        9229 : }
+     133             : 
+     134             : 
+     135           4 : void BF_Sine::setupLabels() {
+     136           4 :   setLabel(0,"1");
+     137          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     138          40 :     std::string is; Tools::convert(i,is);
+     139          80 :     setLabel(i,"sin("+is+"*s)");
+     140             :   }
+     141           4 : }
+     142             : 
+     143             : 
+     144           3 : void BF_Sine::setupUniformIntegrals() {
+     145           3 :   setAllUniformIntegralsToZero();
+     146             :   setUniformIntegral(0,1.0);
+     147           3 : }
+     148             : 
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func-sort-c.html b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html new file mode 100644 index 0000000000..9fd86d9cc3 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE49
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218D2Ev4168
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func.html b/coverage/ves/BF_Wavelets.cpp.func.html new file mode 100644 index 0000000000..a63cab4779 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe2186createERKNS_13ActionOptionsE47
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124BF_WaveletsRegisterMe218D2Ev4168
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.gcov.html b/coverage/ves/BF_Wavelets.cpp.gcov.html new file mode 100644 index 0000000000..f6a0d0b99d --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.gcov.html @@ -0,0 +1,494 @@ + + + + + + + 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-05-27 13:05: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       12551 : PLUMED_REGISTER_ACTION(BF_Wavelets,"BF_WAVELETS")
+     219             : 
+     220             : 
+     221          49 : void BF_Wavelets::registerKeywords(Keywords& keys) {
+     222          49 :   BasisFunctions::registerKeywords(keys);
+     223          98 :   keys.add("compulsory","TYPE","Specify the wavelet type. Currently available are DAUBECHIES Wavelets with minimum phase and the more symmetric SYMLETS");
+     224          98 :   keys.add("optional","FUNCTION_LENGTH","The domain size of the individual basis functions. (length) This is used to alter the scaling of the basis functions. By default it is set to the total size of the interval. This also influences the number of actually used basis functions, as all shifted functions that are partially supported in the CV space are used.");
+     225          98 :   keys.add("optional","NUM_BF","The number of basis functions that should be used. Includes the constant one and N-1 shifted wavelets within the specified range. Cannot be used together with FUNCTION_LENGTH.");
+     226          98 :   keys.add("optional","TAILS_THRESHOLD","The threshold for cutting off tail wavelets as a fraction of the maximum value. All shifted wavelet functions that only have values smaller than the threshold in the bias range will be excluded from the basis set. Defaults to 0 (include all).");
+     227          98 :   keys.addFlag("MOTHER_WAVELET", false, "If this flag is set mother wavelets will be used instead of the scaling function (father wavelet). Makes only sense for multiresolution, which is at the moment not usable.");
+     228          98 :   keys.add("optional","MIN_GRID_SIZE","The minimal number of grid bins of the Wavelet function. The true number depends also on the used wavelet type and will probably be larger. Defaults to 1000.");
+     229          98 :   keys.addFlag("DUMP_WAVELET_GRID", false, "If this flag is set the grid with the wavelet values will be written to a file.  This file is called wavelet_grid.data.");
+     230          98 :   keys.add("optional","WAVELET_FILE_FMT","The number format of the wavelet grid values and derivatives written to file. By default it is %15.8f.\n");
+     231          98 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     232          49 :   keys.remove("NUMERICAL_INTEGRALS");
+     233          49 : }
+     234             : 
+     235             : 
+     236          47 : BF_Wavelets::BF_Wavelets(const ActionOptions& ao):
+     237             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     238          47 :   waveletGrid_(nullptr),
+     239          47 :   scale_(0.0)
+     240             : {
+     241          47 :   log.printf("  Wavelet basis functions, see and cite ");
+     242          94 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     243             : 
+     244             :   // parse properties for waveletGrid and set it up
+     245             :   bool use_mother_wavelet;
+     246          94 :   parseFlag("MOTHER_WAVELET", use_mother_wavelet);
+     247             : 
+     248             :   std::string wavelet_type_str;
+     249          47 :   parse("TYPE", wavelet_type_str);
+     250          94 :   addKeywordToList("TYPE", wavelet_type_str);
+     251             : 
+     252          47 :   unsigned min_grid_size = 1000;
+     253          47 :   parse("MIN_GRID_SIZE", min_grid_size);
+     254          83 :   if(min_grid_size != 1000) {addKeywordToList("MIN_GRID_SIZE",min_grid_size);}
+     255             : 
+     256          94 :   waveletGrid_ = WaveletGrid::setupGrid(getOrder(), min_grid_size, use_mother_wavelet, WaveletGrid::stringToType(wavelet_type_str));
+     257          47 :   bool dump_wavelet_grid=false;
+     258          47 :   parseFlag("DUMP_WAVELET_GRID", dump_wavelet_grid);
+     259          47 :   if (dump_wavelet_grid) {
+     260          36 :     OFile wavelet_gridfile;
+     261          36 :     std::string fmt = "%13.6f";
+     262          72 :     parse("WAVELET_FILE_FMT",fmt);
+     263             :     waveletGrid_->setOutputFmt(fmt); // property of grid not OFile determines fmt
+     264          36 :     wavelet_gridfile.link(*this);
+     265          36 :     wavelet_gridfile.enforceBackup();
+     266          72 :     wavelet_gridfile.open(getLabel()+".wavelet_grid.data");
+     267          36 :     waveletGrid_->writeToFile(wavelet_gridfile);
+     268          36 :   }
+     269             : 
+     270          47 :   bool periodic = false;
+     271          47 :   parseFlag("PERIODIC",periodic);
+     272          51 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     273             : 
+     274             :   // now set up properties of basis set
+     275          47 :   unsigned intrinsic_length = 2*getOrder() - 1; // length of unscaled wavelet
+     276          47 :   double bias_length = intervalMax() - intervalMin(); // intervalRange() is not yet set
+     277             : 
+     278             :   // parse threshold for tail wavelets and get respective cutoff points
+     279          47 :   double threshold = 0.0;
+     280          47 :   std::vector<double> cutoffpoints (2);
+     281          47 :   parse("TAILS_THRESHOLD",threshold);
+     282          47 :   plumed_massert(threshold < 1, "TAILS_THRESHOLD should be significantly smaller than 1.");
+     283          47 :   if(threshold == 0.0) {
+     284          45 :     cutoffpoints = {0.0, static_cast<double>(intrinsic_length)};
+     285             :   }
+     286             :   else {
+     287           2 :     plumed_massert(!periodic, "TAILS_THRESHOLD can't be used with the periodic wavelet variant");
+     288           2 :     addKeywordToList("TAILS_THRESHOLD",threshold);
+     289           4 :     cutoffpoints = getCutoffPoints(threshold);
+     290             :   };
+     291             : 
+     292          47 :   double function_length = bias_length;
+     293          47 :   parse("FUNCTION_LENGTH",function_length);
+     294          47 :   if(function_length != bias_length) {
+     295           4 :     if (periodic) {  // shifted functions need to fit into interval exactly -> reduce size if not
+     296           2 :       unsigned num_shifts = ceil(bias_length * intrinsic_length / function_length);
+     297           2 :       function_length = bias_length * intrinsic_length / num_shifts;
+     298             :     }
+     299           8 :     addKeywordToList("FUNCTION_LENGTH",function_length);
+     300             :   }
+     301             : 
+     302             :   // determine number of BFs and needed scaling
+     303          47 :   unsigned num_BFs = 0;
+     304          47 :   parse("NUM_BF",num_BFs);
+     305          47 :   if(num_BFs == 0) { // get from function length
+     306          43 :     scale_ = intrinsic_length / function_length;
+     307          43 :     if (periodic) {
+     308             :       // this is the same value as num_shifts above + constant
+     309           2 :       num_BFs = static_cast<unsigned>(bias_length * scale_) + 1;
+     310             :     }
+     311             :     else {
+     312          41 :       num_BFs = 1; // constant one
+     313             :       // left shifts (w/o left cutoff) + right shifts - right cutoff - 1
+     314          41 :       num_BFs += static_cast<unsigned>(ceil(cutoffpoints[1] + (bias_length)*scale_ - cutoffpoints[0]) - 1);
+     315             :     }
+     316             :   }
+     317             :   else {
+     318             :     plumed_massert(num_BFs > 0, "The number of basis functions has to be positive (NUM_BF > 0)");
+     319             :     // check does not work if function length was given as intrinsic length, but can't check for keyword use directly
+     320           4 :     plumed_massert(function_length==bias_length,"The keywords \"NUM_BF\" and \"FUNCTION_LENGTH\" cannot be used at the same time");
+     321           4 :     addKeywordToList("NUM_BF",num_BFs);
+     322             : 
+     323           4 :     if (periodic) {  // inverted num_BFs calculation from where FUNCTION_LENGTH is specified
+     324           2 :       scale_ = (num_BFs  - 1) / bias_length ;
+     325             :     }
+     326             :     else {
+     327           2 :       double cutoff_length = cutoffpoints[1] - cutoffpoints [0];
+     328           2 :       double intrinsic_bias_length = num_BFs - cutoff_length + 1; // length of bias in intrinsic scale of wavelets
+     329           2 :       scale_ = intrinsic_bias_length / bias_length;
+     330             :     }
+     331             :   }
+     332             : 
+     333          47 :   setNumberOfBasisFunctions(num_BFs);
+     334             : 
+     335             :   // now set up the starting points of the basis functions
+     336          47 :   shifts_.push_back(0.0); // constant BF – never used, just for clearer notation
+     337        1908 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     338        1861 :     shifts_.push_back(-intervalMin()*scale_ + cutoffpoints[1] - i);
+     339             :   }
+     340             : 
+     341             :   // set some properties
+     342          47 :   setIntrinsicInterval(0.0,intrinsic_length);
+     343          47 :   periodic ? setPeriodic() : setNonPeriodic();
+     344             :   setIntervalBounded();
+     345             :   setType(wavelet_type_str);
+     346          47 :   setDescription("Wavelets as localized basis functions");
+     347          47 :   setupBF();
+     348          47 :   checkRead();
+     349             : 
+     350          47 :   log.printf("  Each basisfunction spans %f in CV space\n", intrinsic_length/scale_);
+     351          47 : }
+     352             : 
+     353             : 
+     354       62249 : void BF_Wavelets::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     355       62249 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     356             :   //
+     357       62249 :   values[0]=1.0;
+     358       62249 :   derivs[0]=0.0;
+     359     2315762 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     360             :     // scale and shift argument to match current wavelet
+     361     2253513 :     double x = shifts_[i] + argT*scale_;
+     362     2253513 :     if (arePeriodic()) { // periodic interval [0,intervalRange*scale]
+     363      171766 :       x = x - floor(x/(intervalRange()*scale_))*intervalRange()*scale_;
+     364             :     }
+     365             : 
+     366     2253513 :     if (x < 0 || x >= intrinsicIntervalMax()) { // Wavelets are 0 outside the defined range
+     367      989659 :       values[i] = 0.0; derivs[i] = 0.0;
+     368             :     }
+     369             :     else {
+     370     1263854 :       std::vector<double> temp_deriv (1);
+     371     1263854 :       values[i] = GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation(waveletGrid_.get(), {x}, temp_deriv);
+     372     1263854 :       derivs[i] = temp_deriv[0] * scale_; // scale derivative
+     373             :     }
+     374             :   }
+     375       67885 :   if(!inside_range) {for(auto& deriv : derivs) {deriv=0.0;}}
+     376       62249 : }
+     377             : 
+     378             : 
+     379             : // returns left and right cutoff point of Wavelet
+     380             : // threshold is a percent value of maximum
+     381           2 : std::vector<double> BF_Wavelets::getCutoffPoints(const double& threshold) {
+     382           2 :   double threshold_value = threshold * waveletGrid_->getMaxValue();
+     383             :   std::vector<double> cutoffpoints;
+     384             : 
+     385         475 :   for (size_t i = 0; i < waveletGrid_->getSize(); ++i) {
+     386         475 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     387           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     388           2 :       break;
+     389             :     }
+     390             :   }
+     391             : 
+     392        1073 :   for (int i = waveletGrid_->getSize() - 1; i >= 0; --i) {
+     393        1073 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     394           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     395           2 :       break;
+     396             :     }
+     397             :   }
+     398             : 
+     399           2 :   return cutoffpoints;
+     400             : }
+     401             : 
+     402             : 
+     403             : // labels according to minimum position in CV space
+     404          47 : void BF_Wavelets::setupLabels() {
+     405          47 :   setLabel(0,"const");
+     406        1908 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     407        1861 :     double pos = -shifts_[i]/scale_;
+     408        1861 :     if (arePeriodic()) {
+     409          88 :       pos = pos - floor((pos-intervalMin())/intervalRange())*intervalRange();
+     410             :     }
+     411        1861 :     std::string is; Tools::convert(pos, is);
+     412        3722 :     setLabel(i,"i="+is);
+     413             :   }
+     414          47 : }
+     415             : 
+     416             : 
+     417             : }
+     418             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func-sort-c.html b/coverage/ves/BasisFunctions.cpp.func-sort-c.html new file mode 100644 index 0000000000..380f1d6bd9 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-05-27 13:05: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
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE271
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func.html b/coverage/ves/BasisFunctions.cpp.func.html new file mode 100644 index 0000000000..1774d59bfc --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func.html @@ -0,0 +1,156 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-05-27 13:05: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_8KeywordsE271
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_170
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalEdd79
_ZN4PLMD3ves14BasisFunctions21setupUniformIntegralsEv79
_ZN4PLMD3ves14BasisFunctions25numericalUniformIntegralsEv85
_ZN4PLMD3ves14BasisFunctions7setupBFEv249
_ZN4PLMD3ves14BasisFunctionsC2ERKNS_13ActionOptionsE249
_ZNK4PLMD3ves14BasisFunctions16getKeywordStringB5cxx11Ev142
_ZNK4PLMD3ves14BasisFunctions16getMultipleValueERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EESA_b71
_ZNK4PLMD3ves14BasisFunctions25writeBasisFunctionsToFileERNS_5OFileES3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_jbSB_SB_b71
_ZNK4PLMD3ves14BasisFunctions27getAllValuesNumericalDerivsEdRdRbRSt6vectorIdSaIdEES7_0
_ZNK4PLMD3ves14BasisFunctions30getTargetDistributionIntegralsEPKNS0_18TargetDistributionE247
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZNK4PLMD3ves14BasisFunctions9printInfoEv249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.gcov.html b/coverage/ves/BasisFunctions.cpp.gcov.html new file mode 100644 index 0000000000..09dd43f4d3 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.gcov.html @@ -0,0 +1,481 @@ + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-05-27 13:05: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         271 : void BasisFunctions::registerKeywords(Keywords& keys) {
+      37         271 :   Action::registerKeywords(keys);
+      38         542 :   keys.add("compulsory","ORDER","The order of the basis function expansion.");
+      39         542 :   keys.add("compulsory","MINIMUM","The minimum of the interval on which the basis functions are defined.");
+      40         542 :   keys.add("compulsory","MAXIMUM","The maximum of the interval on which the basis functions are defined.");
+      41         542 :   keys.add("hidden","NGRID_POINTS","The number of grid points used for numerical integrals");
+      42         542 :   keys.addFlag("DEBUG_INFO",false,"Print out more detailed information about the basis set. Useful for debugging.");
+      43         542 :   keys.addFlag("NUMERICAL_INTEGRALS",false,"Calculate basis function integral for the uniform distribution numerically. Useful for debugging.");
+      44         271 : }
+      45             : 
+      46             : 
+      47         249 : BasisFunctions::BasisFunctions(const ActionOptions&ao):
+      48             :   Action(ao),
+      49         249 :   print_debug_info_(false),
+      50         249 :   has_been_set(false),
+      51         498 :   description_("Undefined"),
+      52         249 :   type_("Undefined"),
+      53         249 :   norder_(0),
+      54         249 :   nbasis_(1),
+      55         249 :   bf_label_prefix_("f"),
+      56         249 :   bf_labels_(nbasis_,"f0"),
+      57         249 :   periodic_(false),
+      58         249 :   interval_bounded_(true),
+      59         249 :   interval_intrinsic_min_str_("1.0"),
+      60         249 :   interval_intrinsic_max_str_("-1.0"),
+      61         249 :   interval_intrinsic_min_(1.0),
+      62         249 :   interval_intrinsic_max_(-1.0),
+      63         249 :   interval_intrinsic_range_(0.0),
+      64         249 :   interval_intrinsic_mean_(0.0),
+      65         249 :   interval_min_str_(""),
+      66         249 :   interval_max_str_(""),
+      67         249 :   interval_min_(0.0),
+      68         249 :   interval_max_(0.0),
+      69         249 :   interval_range_(0.0),
+      70         249 :   interval_mean_(0.0),
+      71         249 :   argT_derivf_(1.0),
+      72         249 :   numerical_uniform_integrals_(false),
+      73         249 :   nbins_(1001),
+      74         249 :   uniform_integrals_(nbasis_,0.0),
+      75         249 :   vesbias_pntr_(NULL),
+      76         747 :   action_pntr_(NULL)
+      77             : {
+      78         249 :   bf_keywords_.push_back(getName());
+      79         498 :   if(keywords.exists("ORDER")) {
+      80         711 :     parse("ORDER",norder_); addKeywordToList("ORDER",norder_);
+      81             :   }
+      82         249 :   nbasis_=norder_+1;
+      83             :   //
+      84             :   std::string str_imin; std::string str_imax;
+      85         496 :   if(keywords.exists("MINIMUM") && keywords.exists("MAXIMUM")) {
+      86         741 :     parse("MINIMUM",str_imin); addKeywordToList("MINIMUM",str_imin);
+      87         741 :     parse("MAXIMUM",str_imax); addKeywordToList("MAXIMUM",str_imax);
+      88             :   }
+      89             :   else {
+      90             :     str_imin = "-1.0";
+      91             :     str_imax = "1.0";
+      92             :   }
+      93             :   interval_min_str_ = str_imin;
+      94             :   interval_max_str_ = str_imax;
+      95         249 :   if(!Tools::convertNoexcept(str_imin,interval_min_)) {
+      96           0 :     plumed_merror(getName()+": cannot convert the value given in MINIMUM to a double");
+      97             :   }
+      98         249 :   if(!Tools::convertNoexcept(str_imax,interval_max_)) {
+      99           0 :     plumed_merror(getName()+": cannot convert the value given in MAXIMUM to a double");
+     100             :   }
+     101         249 :   if(interval_min_>interval_max_) {plumed_merror(getName()+": MINIMUM and MAXIMUM are not correctly defined");}
+     102             :   //
+     103         249 :   parseFlag("DEBUG_INFO",print_debug_info_);
+     104         498 :   if(keywords.exists("NUMERICAL_INTEGRALS")) {
+     105         336 :     parseFlag("NUMERICAL_INTEGRALS",numerical_uniform_integrals_);
+     106             :   }
+     107         498 :   if(keywords.exists("NGRID_POINTS")) {
+     108         494 :     parse("NGRID_POINTS",nbins_);
+     109             :   }
+     110             :   // log.printf(" %s \n",getKeywordString().c_str());
+     111             : 
+     112         249 : }
+     113             : 
+     114             : 
+     115          79 : void BasisFunctions::setIntrinsicInterval(const double interval_intrinsic_min_in, const double interval_intrinsic_max_in) {
+     116          79 :   interval_intrinsic_min_ = interval_intrinsic_min_in;
+     117          79 :   interval_intrinsic_max_ = interval_intrinsic_max_in;
+     118          79 :   VesTools::convertDbl2Str(interval_intrinsic_min_,interval_intrinsic_min_str_);
+     119          79 :   VesTools::convertDbl2Str(interval_intrinsic_max_,interval_intrinsic_max_str_);
+     120          79 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     121          79 : }
+     122             : 
+     123             : 
+     124         170 : void BasisFunctions::setIntrinsicInterval(const std::string& interval_intrinsic_min_str_in, const std::string& interval_intrinsic_max_str_in) {
+     125         170 :   interval_intrinsic_min_str_ = interval_intrinsic_min_str_in;
+     126         170 :   interval_intrinsic_max_str_ = interval_intrinsic_max_str_in;
+     127         170 :   if(!Tools::convertNoexcept(interval_intrinsic_min_str_,interval_intrinsic_min_)) {
+     128           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the minimum of the intrinsic interval to a double");
+     129             :   }
+     130         170 :   if(!Tools::convertNoexcept(interval_intrinsic_max_str_,interval_intrinsic_max_)) {
+     131           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the maximum of the intrinsic interval to a double");
+     132             :   }
+     133         170 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     134         170 : }
+     135             : 
+     136             : 
+     137           0 : void BasisFunctions::setInterval(const double interval_min_in, const double interval_max_in) {
+     138           0 :   interval_min_ = interval_min_in;
+     139           0 :   interval_max_ = interval_max_in;
+     140           0 :   VesTools::convertDbl2Str(interval_min_,interval_min_str_);
+     141           0 :   VesTools::convertDbl2Str(interval_max_,interval_max_str_);
+     142           0 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     143           0 : }
+     144             : 
+     145             : 
+     146           2 : void BasisFunctions::setInterval(const std::string& interval_min_str_in, const std::string& interval_max_str_in) {
+     147           2 :   interval_min_str_ = interval_min_str_in;
+     148           2 :   interval_max_str_ = interval_max_str_in;
+     149           2 :   if(!Tools::convertNoexcept(interval_min_str_,interval_min_)) {
+     150           0 :     plumed_merror("setInterval: cannot convert string value given for the minimum of the interval to a double");
+     151             :   }
+     152           2 :   if(!Tools::convertNoexcept(interval_max_str_,interval_max_)) {
+     153           0 :     plumed_merror("setInterval: cannot convert string value given for the maximum of the interval to a double");
+     154             :   }
+     155           2 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     156           2 : }
+     157             : 
+     158             : 
+     159         249 : void BasisFunctions::setupInterval() {
+     160             :   // if(!intervalBounded()){plumed_merror("setupInterval() only works for bounded interval");}
+     161         249 :   interval_intrinsic_range_ = interval_intrinsic_max_-interval_intrinsic_min_;
+     162         249 :   interval_intrinsic_mean_  = 0.5*(interval_intrinsic_max_+interval_intrinsic_min_);
+     163         249 :   interval_range_ = interval_max_-interval_min_;
+     164         249 :   interval_mean_  = 0.5*(interval_max_+interval_min_);
+     165         249 :   argT_derivf_ = interval_intrinsic_range_/interval_range_;
+     166         249 : }
+     167             : 
+     168             : 
+     169          78 : void BasisFunctions::setupLabels() {
+     170         884 :   for(unsigned int i=0; i < nbasis_; i++) {
+     171         806 :     std::string is; Tools::convert(i,is);
+     172        1612 :     bf_labels_[i]=bf_label_prefix_+is+"(s)";
+     173             :   }
+     174          78 : }
+     175             : 
+     176             : 
+     177          79 : void BasisFunctions::setupUniformIntegrals() {
+     178          79 :   numerical_uniform_integrals_=true;
+     179          79 :   numericalUniformIntegrals();
+     180          79 : }
+     181             : 
+     182             : 
+     183         249 : void BasisFunctions::setupBF() {
+     184         249 :   if(interval_intrinsic_min_>interval_intrinsic_max_) {plumed_merror("setupBF: default intervals are not correctly set");}
+     185         249 :   setupInterval();
+     186         249 :   setupLabels();
+     187         249 :   if(bf_labels_.size()==1) {plumed_merror("setupBF: the labels of the basis functions are not correct.");}
+     188         249 :   if(!numerical_uniform_integrals_) {setupUniformIntegrals();}
+     189           6 :   else {numericalUniformIntegrals();}
+     190         249 :   if(uniform_integrals_.size()==1) {plumed_merror("setupBF: the integrals of the basis functions is not correct.");}
+     191         249 :   if(type_=="Undefined") {plumed_merror("setupBF: the type of the basis function is not defined.");}
+     192         249 :   if(description_=="Undefined") {plumed_merror("setupBF: the description of the basis function is not defined.");}
+     193         249 :   has_been_set=true;
+     194         249 :   printInfo();
+     195         249 : }
+     196             : 
+     197             : 
+     198         249 : void BasisFunctions::printInfo() const {
+     199         249 :   if(!has_been_set) {plumed_merror("the basis set has not be setup correctly");}
+     200         249 :   log.printf("  One-dimensional basis set\n");
+     201         249 :   log.printf("   Description: %s\n",description_.c_str());
+     202         249 :   log.printf("   Type: %s\n",type_.c_str());
+     203         249 :   if(periodic_) {log.printf("   The basis functions are periodic\n");}
+     204         249 :   log.printf("   Order of basis set: %u\n",norder_);
+     205         249 :   log.printf("   Number of basis functions: %u\n",nbasis_);
+     206             :   // log.printf("   Interval of basis set: %f to %f\n",interval_min_,interval_max_);
+     207         249 :   log.printf("   Interval of basis set: %s to %s\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     208         249 :   log.printf("   Description of basis functions:\n");
+     209        4293 :   for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %10s\n",i,bf_labels_[i].c_str());}
+     210             :   //
+     211         249 :   if(print_debug_info_) {
+     212          38 :     log.printf("  Debug information:\n");
+     213             :     // log.printf("   Default interval of basis set: [%f,%f]\n",interval_intrinsic_min_,interval_intrinsic_max_);
+     214          38 :     log.printf("   Intrinsic interval of basis set: [%s,%s]\n",interval_intrinsic_min_str_.c_str(),interval_intrinsic_max_str_.c_str());
+     215          38 :     log.printf("   Intrinsic interval of basis set: range=%f,  mean=%f\n",interval_intrinsic_range_,interval_intrinsic_mean_);
+     216             :     // log.printf("   Defined interval of basis set: [%f,%f]\n",interval_min_,interval_max_);
+     217          38 :     log.printf("   Defined interval of basis set: [%s,%s]\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     218          38 :     log.printf("   Defined interval of basis set: range=%f,  mean=%f\n",interval_range_,interval_mean_);
+     219          38 :     log.printf("   Derivative factor due to interval translation: %f\n",argT_derivf_);
+     220          38 :     log.printf("   Integral of basis functions over the interval:\n");
+     221          38 :     if(numerical_uniform_integrals_) {log.printf("   Note: calculated numerically\n");}
+     222         558 :     for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %16.10f\n",i,uniform_integrals_[i]);}
+     223          38 :     log.printf("   --------------------------\n");
+     224             :   }
+     225         249 : }
+     226             : 
+     227             : 
+     228           0 : void BasisFunctions::linkVesBias(VesBias* vesbias_pntr_in) {
+     229           0 :   vesbias_pntr_ = vesbias_pntr_in;
+     230           0 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     231           0 : }
+     232             : 
+     233             : 
+     234           0 : void BasisFunctions::linkAction(Action* action_pntr_in) {
+     235           0 :   action_pntr_ = action_pntr_in;
+     236           0 : }
+     237             : 
+     238             : 
+     239          85 : void BasisFunctions::numericalUniformIntegrals() {
+     240          85 :   std::vector<std::string> grid_min(1); grid_min[0]=intervalMinStr();
+     241          85 :   std::vector<std::string> grid_max(1); grid_max[0]=intervalMaxStr();
+     242          85 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins_;
+     243         170 :   std::vector<std::unique_ptr<Value>> arguments(1); arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     244         105 :   if(arePeriodic()) {arguments[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     245          75 :   else {arguments[0]->setNotPeriodic();}
+     246         170 :   auto uniform_grid = Tools::make_unique<Grid>("uniform",Tools::unique2raw(arguments),grid_min,grid_max,grid_bins,false,false);
+     247             :   //
+     248          85 :   double inverse_normalization = 1.0/(intervalMax()-intervalMin());
+     249       85245 :   for(Grid::index_t l=0; l<uniform_grid->getSize(); l++) {
+     250       85160 :     uniform_grid->setValue(l,inverse_normalization);
+     251             :   }
+     252          85 :   uniform_integrals_ = numericalTargetDistributionIntegralsFromGrid(uniform_grid.get());
+     253         170 : }
+     254             : 
+     255             : 
+     256         261 : std::vector<double> BasisFunctions::numericalTargetDistributionIntegralsFromGrid(const Grid* grid_pntr) const {
+     257         261 :   plumed_massert(grid_pntr!=NULL,"the grid is not defined");
+     258         261 :   plumed_massert(grid_pntr->getDimension()==1,"the target distribution grid should be one dimensional");
+     259             :   //
+     260         261 :   std::vector<double> targetdist_integrals(nbasis_,0.0);
+     261         522 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(grid_pntr);
+     262             : 
+     263      138336 :   for(Grid::index_t k=0; k < grid_pntr->getSize(); k++) {
+     264      138075 :     double arg = grid_pntr->getPoint(k)[0];
+     265      138075 :     std::vector<double> bf_values(nbasis_);
+     266      138075 :     std::vector<double> bf_derivs(nbasis_);
+     267      138075 :     bool inside=true;
+     268      138075 :     double argT=0.0;
+     269      138075 :     getAllValues(arg,argT,inside,bf_values,bf_derivs);
+     270     3336092 :     for(unsigned int i=0; i < nbasis_; i++) {
+     271     3198017 :       targetdist_integrals[i] += (integration_weights[k] * grid_pntr->getValue(k)) * bf_values[i];
+     272             :     }
+     273             :   }
+     274             :   // assume that the first function is the constant
+     275         261 :   bool inside=true;
+     276         261 :   double argT=0.0;
+     277         261 :   targetdist_integrals[0] = getValue(0.0,0,argT,inside);
+     278         261 :   return targetdist_integrals;
+     279             : }
+     280             : 
+     281             : 
+     282         247 : std::vector<double> BasisFunctions::getTargetDistributionIntegrals(const TargetDistribution* targetdist_pntr) const {
+     283         247 :   if(targetdist_pntr==NULL) {
+     284             :     return getUniformIntegrals();
+     285             :   }
+     286             :   else {
+     287             :     Grid* targetdist_grid = targetdist_pntr->getTargetDistGridPntr();
+     288         176 :     return numericalTargetDistributionIntegralsFromGrid(targetdist_grid);
+     289             :   }
+     290             : }
+     291             : 
+     292             : 
+     293         142 : std::string BasisFunctions::getKeywordString() const {
+     294         142 :   std::string str_keywords=bf_keywords_[0];
+     295         762 :   for(unsigned int i=1; i<bf_keywords_.size(); i++) {str_keywords+=" "+bf_keywords_[i];}
+     296         142 :   return str_keywords;
+     297             : }
+     298             : 
+     299             : 
+     300         261 : double BasisFunctions::getValue(const double arg, const unsigned int n, double& argT, bool& inside_range) const {
+     301         261 :   plumed_massert(n<numberOfBasisFunctions(),"getValue: n is outside range of the defined order of the basis set");
+     302         261 :   inside_range=true;
+     303         261 :   std::vector<double> tmp_values(numberOfBasisFunctions());
+     304         261 :   std::vector<double> tmp_derivs(numberOfBasisFunctions());
+     305         261 :   getAllValues(arg, argT, inside_range, tmp_values, tmp_derivs);
+     306         522 :   return tmp_values[n];
+     307             : }
+     308             : 
+     309             : 
+     310           0 : void BasisFunctions::getAllValuesNumericalDerivs(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     311             :   // use forward difference, unless very close to the boundary
+     312             :   double delta = sqrt(epsilon);
+     313           0 :   if((arg+delta)>intervalMax()) {
+     314             :     delta *= -1.0;
+     315             :   }
+     316           0 :   inside_range=true;
+     317           0 :   std::vector<double> values_delta(numberOfBasisFunctions());
+     318           0 :   std::vector<double> derivs_dummy(numberOfBasisFunctions());
+     319           0 :   getAllValues(arg+delta, argT, inside_range, values_delta, derivs_dummy);
+     320           0 :   getAllValues(arg, argT, inside_range, values, derivs_dummy);
+     321           0 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     322           0 :     derivs[i] = (values_delta[i]-values[i])/delta;
+     323             :   }
+     324           0 : }
+     325             : 
+     326             : 
+     327          71 : void BasisFunctions::getMultipleValue(const std::vector<double>& args, std::vector<double>& argsT, std::vector<std::vector<double> >& values, std::vector<std::vector<double> >& derivs, const bool numerical_deriv) const {
+     328          71 :   argsT.resize(args.size());
+     329             :   values.clear();
+     330             :   derivs.clear();
+     331       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     332       22948 :     std::vector<double> tmp_values(getNumberOfBasisFunctions());
+     333       22948 :     std::vector<double> tmp_derivs(getNumberOfBasisFunctions());
+     334       22948 :     bool inside_interval=true;
+     335       22948 :     if(!numerical_deriv) {
+     336       22948 :       getAllValues(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     337             :     } else {
+     338           0 :       getAllValuesNumericalDerivs(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     339             :     }
+     340       22948 :     values.push_back(tmp_values);
+     341       22948 :     derivs.push_back(tmp_derivs);
+     342             :   }
+     343          71 : }
+     344             : 
+     345             : 
+     346          71 : void BasisFunctions::writeBasisFunctionsToFile(OFile& ofile_values, OFile& ofile_derivs, const std::string& min_in, const std::string& max_in, unsigned int nbins_in, const bool ignore_periodicity, const std::string& output_fmt_values, const std::string& output_fmt_derivs, const bool numerical_deriv) const {
+     347          71 :   std::vector<std::string> min(1); min[0]=min_in;
+     348          71 :   std::vector<std::string> max(1); max[0]=max_in;
+     349          71 :   std::vector<unsigned int> nbins(1); nbins[0]=nbins_in;
+     350          71 :   std::vector<std::unique_ptr<Value>> value_pntr(1);
+     351         142 :   value_pntr[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     352         117 :   if(arePeriodic() && !ignore_periodicity) {value_pntr[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     353          48 :   else {value_pntr[0]->setNotPeriodic();}
+     354         142 :   Grid args_grid = Grid("grid",Tools::unique2raw(value_pntr),min,max,nbins,false,false);
+     355             : 
+     356          71 :   std::vector<double> args(args_grid.getSize(),0.0);
+     357       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     358       22948 :     args[i] = args_grid.getPoint(i)[0];
+     359             :   }
+     360             :   std::vector<double> argsT;
+     361             :   std::vector<std::vector<double> > values;
+     362             :   std::vector<std::vector<double> > derivs;
+     363             : 
+     364         142 :   ofile_values.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     365         142 :   ofile_derivs.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     366             : 
+     367         213 :   ofile_values.addConstantField("min").printField("min",intervalMinStr());
+     368         213 :   ofile_values.addConstantField("max").printField("max",intervalMaxStr());
+     369             : 
+     370         213 :   ofile_derivs.addConstantField("min").printField("min",intervalMinStr());
+     371         213 :   ofile_derivs.addConstantField("max").printField("max",intervalMaxStr());
+     372             : 
+     373         142 :   ofile_values.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     374         142 :   ofile_derivs.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     375             : 
+     376          71 :   if(arePeriodic()) {
+     377          52 :     ofile_values.addConstantField("periodic").printField("periodic","true");
+     378          52 :     ofile_derivs.addConstantField("periodic").printField("periodic","true");
+     379             :   }
+     380             :   else {
+     381          90 :     ofile_values.addConstantField("periodic").printField("periodic","false");
+     382          90 :     ofile_derivs.addConstantField("periodic").printField("periodic","false");
+     383             :   }
+     384             : 
+     385          71 :   getMultipleValue(args,argsT,values,derivs,numerical_deriv);
+     386          71 :   ofile_values.fmtField(output_fmt_values);
+     387          71 :   ofile_derivs.fmtField(output_fmt_derivs);
+     388       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     389       45896 :     ofile_values.printField("arg",args[i]);
+     390       22948 :     ofile_derivs.printField("arg",args[i]);
+     391      410060 :     for(unsigned int k=0; k<getNumberOfBasisFunctions(); k++) {
+     392      774224 :       ofile_values.printField(getBasisFunctionLabel(k),values[i][k]);
+     393      774224 :       ofile_derivs.printField("d_"+getBasisFunctionLabel(k),derivs[i][k]);
+     394             :     }
+     395       22948 :     ofile_values.printField();
+     396       22948 :     ofile_derivs.printField();
+     397             :   }
+     398          71 :   ofile_values.fmtField();
+     399          71 :   ofile_derivs.fmtField();
+     400             : 
+     401         213 : }
+     402             : 
+     403             : 
+     404             : }
+     405             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func-sort-c.html b/coverage/ves/BasisFunctions.h.func-sort-c.html new file mode 100644 index 0000000000..a10c271cdf --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func.html b/coverage/ves/BasisFunctions.h.func.html new file mode 100644 index 0000000000..48934dd8f4 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.gcov.html b/coverage/ves/BasisFunctions.h.gcov.html new file mode 100644 index 0000000000..f25a0a2669 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.gcov.html @@ -0,0 +1,393 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func-sort-c.html b/coverage/ves/CoeffsBase.cpp.func-sort-c.html new file mode 100644 index 0000000000..04040d39ed --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func-sort-c.html @@ -0,0 +1,200 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func.html b/coverage/ves/CoeffsBase.cpp.func.html new file mode 100644 index 0000000000..36cb7f43b2 --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func.html @@ -0,0 +1,200 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.gcov.html b/coverage/ves/CoeffsBase.cpp.gcov.html new file mode 100644 index 0000000000..bc56744fce --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.gcov.html @@ -0,0 +1,593 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func-sort-c.html b/coverage/ves/CoeffsBase.h.func-sort-c.html new file mode 100644 index 0000000000..bc4e7218b5 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func.html b/coverage/ves/CoeffsBase.h.func.html new file mode 100644 index 0000000000..42cf8378d5 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.gcov.html b/coverage/ves/CoeffsBase.h.gcov.html new file mode 100644 index 0000000000..93b5592186 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.gcov.html @@ -0,0 +1,335 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html new file mode 100644 index 0000000000..75bcc50874 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html @@ -0,0 +1,388 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func.html b/coverage/ves/CoeffsMatrix.cpp.func.html new file mode 100644 index 0000000000..a8a82a7913 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func.html @@ -0,0 +1,388 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.gcov.html b/coverage/ves/CoeffsMatrix.cpp.gcov.html new file mode 100644 index 0000000000..3c295f6cf9 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.gcov.html @@ -0,0 +1,791 @@ + + + + + + + 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-05-27 13:05: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         172 : CoeffsMatrix::~CoeffsMatrix() {}
+     130             : 
+     131             : 
+     132         172 : void CoeffsMatrix::setupMatrix() {
+     133         172 :   nrows_=numberOfCoeffs();
+     134         172 :   ncolumns_=nrows_;
+     135         172 :   if(diagonal_) {
+     136         172 :     size_=nrows_;
+     137             :   }
+     138             :   else {
+     139           0 :     size_=(nrows_*nrows_-nrows_)/2+nrows_;
+     140             :   }
+     141         172 :   clear();
+     142         172 : }
+     143             : 
+     144             : 
+     145         439 : size_t CoeffsMatrix::getSize() const {
+     146         439 :   return size_;
+     147             : }
+     148             : 
+     149             : 
+     150       23395 : bool CoeffsMatrix::isDiagonal() const {
+     151       23395 :   return diagonal_;
+     152             : }
+     153             : 
+     154             : 
+     155           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvector_in) const {
+     156           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     157             : }
+     158             : 
+     159             : 
+     160           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     161           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     162             : }
+     163             : 
+     164             : 
+     165           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     166           0 :   return coeffsmat0.sameShape(coeffsmat1);
+     167             : }
+     168             : 
+     169             : 
+     170           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvec, CoeffsMatrix& coeffsmat) {
+     171           0 :   return coeffsmat.sameShape(coeffsvec);
+     172             : }
+     173             : 
+     174             : 
+     175           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat, CoeffsVector& coeffsvec) {
+     176           0 :   return coeffsmat.sameShape(coeffsvec);
+     177             : }
+     178             : 
+     179             : 
+     180           0 : void CoeffsMatrix::sumCommMPI() {
+     181           0 :   mycomm.Sum(data);
+     182           0 : }
+     183             : 
+     184             : 
+     185           0 : void CoeffsMatrix::sumCommMPI(Communicator& cc) {
+     186           0 :   cc.Sum(data);
+     187           0 : }
+     188             : 
+     189             : 
+     190           0 : void CoeffsMatrix::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     191           0 :   if(mycomm.Get_rank()==0) {
+     192           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     193           0 :     multi_sim_cc.Sum(data);
+     194           0 :     scaleAllValues(1.0/nwalkers);
+     195             :   }
+     196           0 :   mycomm.Bcast(data,0);
+     197           0 : }
+     198             : 
+     199             : 
+     200     5425906 : size_t CoeffsMatrix::getMatrixIndex(const size_t index1, const size_t index2) const {
+     201             :   size_t matrix_idx;
+     202             :   plumed_dbg_assert(index1<nrows_);
+     203             :   plumed_dbg_assert(index2<ncolumns_);
+     204     5425906 :   if(diagonal_) {
+     205             :     // plumed_massert(index1==index2,"CoeffsMatrix: you trying to access a off-diagonal element of a diagonal coeffs matrix");
+     206             :     matrix_idx=index1;
+     207             :   }
+     208           0 :   else if (index1<=index2) {
+     209           0 :     matrix_idx=index2+index1*(nrows_-1)-index1*(index1-1)/2;
+     210             :   }
+     211             :   else {
+     212           0 :     matrix_idx=index1+index2*(nrows_-1)-index2*(index2-1)/2;
+     213             :   }
+     214     5425906 :   return matrix_idx;
+     215             : }
+     216             : 
+     217             : 
+     218         267 : void CoeffsMatrix::clear() {
+     219         267 :   data.resize(getSize());
+     220       19388 :   for(size_t i=0; i<data.size(); i++) {
+     221       19121 :     data[i]=0.0;
+     222             :   }
+     223         267 : }
+     224             : 
+     225             : 
+     226           0 : void CoeffsMatrix::setAllValuesToZero() {
+     227           0 :   for(size_t i=0; i<data.size(); i++) {
+     228           0 :     data[i]=0.0;
+     229             :   }
+     230           0 : }
+     231             : 
+     232             : 
+     233       27630 : double CoeffsMatrix::getValue(const size_t index1, const size_t index2) const {
+     234       27630 :   return data[getMatrixIndex(index1,index2)];
+     235             : }
+     236             : 
+     237             : 
+     238           0 : double CoeffsMatrix::getValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     239           0 :   return getValue(getIndex(indices1),getIndex(indices2));
+     240             : }
+     241             : 
+     242             : 
+     243         219 : void CoeffsMatrix::setValue(const size_t index1, const size_t index2, const double value) {
+     244         219 :   data[getMatrixIndex(index1,index2)]=value;
+     245         219 : }
+     246             : 
+     247             : 
+     248           0 : void CoeffsMatrix::setValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     249           0 :   setValue(getIndex(indices1),getIndex(indices2),value);
+     250           0 : }
+     251             : 
+     252             : 
+     253           0 : double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) {
+     254           0 :   return data[getMatrixIndex(index1,index2)];
+     255             : }
+     256             : 
+     257             : 
+     258     1790345 : const double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) const {
+     259     1790345 :   return data[getMatrixIndex(index1,index2)];
+     260             : }
+     261             : 
+     262             : 
+     263           0 : double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) {
+     264           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     265             : }
+     266             : 
+     267             : 
+     268           0 : const double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     269           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     270             : }
+     271             : 
+     272             : 
+     273       22735 : CoeffsVector operator*(const CoeffsMatrix& coeffs_matrix, const CoeffsVector& coeffs_vector) {
+     274       22735 :   CoeffsVector new_coeffs_vector(coeffs_vector);
+     275       22735 :   new_coeffs_vector.clear();
+     276       22735 :   plumed_massert(coeffs_vector.numberOfCoeffs()==coeffs_matrix.numberOfCoeffs(),"CoeffsMatrix and CoeffsVector are of the wrong size");
+     277             :   size_t numcoeffs = coeffs_vector.numberOfCoeffs();
+     278       22735 :   if(coeffs_matrix.isDiagonal()) {
+     279     1813080 :     for(size_t i=0; i<numcoeffs; i++) {
+     280     1790345 :       new_coeffs_vector(i) = coeffs_matrix(i,i)*coeffs_vector(i);
+     281             :     }
+     282             :   }
+     283             :   else {
+     284           0 :     for(size_t i=0; i<numcoeffs; i++) {
+     285           0 :       for(size_t j=0; j<numcoeffs; j++) {
+     286           0 :         new_coeffs_vector(i) += coeffs_matrix(i,j)*coeffs_vector(j);
+     287             :       }
+     288             :     }
+     289             :   }
+     290       22735 :   return new_coeffs_vector;
+     291           0 : }
+     292             : 
+     293             : 
+     294           0 : void CoeffsMatrix::addToValue(const size_t index1, const size_t index2, const double value) {
+     295           0 :   data[getMatrixIndex(index1,index2)]+=value;
+     296           0 : }
+     297             : 
+     298             : 
+     299           0 : void CoeffsMatrix::addToValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     300           0 :   addToValue(getIndex(indices1),getIndex(indices2),value);
+     301           0 : }
+     302             : 
+     303             : 
+     304       22810 : void CoeffsMatrix::scaleAllValues(const double scalef) {
+     305     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     306     1801040 :     data[i]*=scalef;
+     307             :   }
+     308       22810 : }
+     309             : 
+     310             : 
+     311       22810 : CoeffsMatrix& CoeffsMatrix::operator*=(const double scalef) {
+     312       22810 :   scaleAllValues(scalef);
+     313       22810 :   return *this;
+     314             : }
+     315             : 
+     316             : 
+     317           0 : CoeffsMatrix operator*(const double scalef, const CoeffsMatrix& coeffsmatrix) {
+     318           0 :   return CoeffsMatrix(coeffsmatrix)*=scalef;
+     319             : }
+     320             : 
+     321             : 
+     322           0 : CoeffsMatrix operator*(const CoeffsMatrix& coeffsmatrix, const double scalef) {
+     323           0 :   return scalef*coeffsmatrix;
+     324             : }
+     325             : 
+     326             : 
+     327           0 : CoeffsMatrix& CoeffsMatrix::operator*=(const CoeffsMatrix& other_coeffsmatrix) {
+     328           0 :   plumed_massert(data.size()==other_coeffsmatrix.getSize(),"Coeffs matrices do not have the same size");
+     329           0 :   for(size_t i=0; i<data.size(); i++) {
+     330           0 :     data[i]*=other_coeffsmatrix.data[i];
+     331             :   }
+     332           0 :   return *this;
+     333             : }
+     334             : 
+     335             : 
+     336           0 : CoeffsMatrix CoeffsMatrix::operator*(const CoeffsMatrix& other_coeffsmatrix) const {
+     337           0 :   return CoeffsMatrix(*this)*=other_coeffsmatrix;
+     338             : }
+     339             : 
+     340             : 
+     341           0 : void CoeffsMatrix::setValues(const double value) {
+     342           0 :   for(size_t i=0; i<data.size(); i++) {
+     343           0 :     data[i]=value;
+     344             :   }
+     345           0 : }
+     346             : 
+     347             : 
+     348       22810 : void CoeffsMatrix::setValues(const std::vector<double>& values) {
+     349       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     350     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     351     1801040 :     data[i]=values[i];
+     352             :   }
+     353       22810 : }
+     354             : 
+     355             : 
+     356           0 : void CoeffsMatrix::setValues(const CoeffsMatrix& other_coeffsmatrix) {
+     357           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     358           0 :   for(size_t i=0; i<data.size(); i++) {
+     359           0 :     data[i]=other_coeffsmatrix.data[i];
+     360             :   }
+     361           0 : }
+     362             : 
+     363             : 
+     364           0 : CoeffsMatrix& CoeffsMatrix::operator=(const double value) {
+     365           0 :   setValues(value);
+     366           0 :   return *this;
+     367             : }
+     368             : 
+     369             : 
+     370       22810 : CoeffsMatrix& CoeffsMatrix::operator=(const std::vector<double>& values) {
+     371       22810 :   setValues(values);
+     372       22810 :   return *this;
+     373             : }
+     374             : 
+     375             : 
+     376             : // CoeffsMatrix& CoeffsMatrix::operator=(const CoeffsMatrix& other_coeffsmatrix) {
+     377             : //   setValues(other_coeffsmatrix);
+     378             : //   return *this;
+     379             : // }
+     380             : 
+     381             : 
+     382           0 : CoeffsMatrix CoeffsMatrix::operator+() const {
+     383           0 :   return *this;
+     384             : }
+     385             : 
+     386             : 
+     387           0 : CoeffsMatrix CoeffsMatrix::operator-() const {
+     388           0 :   return CoeffsMatrix(*this)*=-1.0;
+     389             : }
+     390             : 
+     391             : 
+     392           0 : void CoeffsMatrix::addToValues(const double value) {
+     393           0 :   for(size_t i=0; i<data.size(); i++) {
+     394           0 :     data[i]+=value;
+     395             :   }
+     396           0 : }
+     397             : 
+     398             : 
+     399           0 : void CoeffsMatrix::addToValues(const std::vector<double>& values) {
+     400           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     401           0 :   for(size_t i=0; i<data.size(); i++) {
+     402           0 :     data[i]+=values[i];
+     403             :   }
+     404           0 : }
+     405             : 
+     406             : 
+     407           0 : void CoeffsMatrix::addToValues(const CoeffsMatrix& other_coeffsmatrix) {
+     408           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     409           0 :   for(size_t i=0; i<data.size(); i++) {
+     410           0 :     data[i]+=other_coeffsmatrix.data[i];
+     411             :   }
+     412           0 : }
+     413             : 
+     414             : 
+     415           0 : void CoeffsMatrix::subtractFromValues(const double value) {
+     416           0 :   for(size_t i=0; i<data.size(); i++) {
+     417           0 :     data[i]-=value;
+     418             :   }
+     419           0 : }
+     420             : 
+     421             : 
+     422           0 : void CoeffsMatrix::subtractFromValues(const std::vector<double>& values) {
+     423           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     424           0 :   for(size_t i=0; i<data.size(); i++) {
+     425           0 :     data[i]-=values[i];
+     426             :   }
+     427           0 : }
+     428             : 
+     429             : 
+     430           0 : void CoeffsMatrix::subtractFromValues(const CoeffsMatrix& other_coeffsmatrix) {
+     431           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     432           0 :   for(size_t i=0; i<data.size(); i++) {
+     433           0 :     data[i]-=other_coeffsmatrix.data[i];
+     434             :   }
+     435           0 : }
+     436             : 
+     437             : 
+     438           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const double value) {
+     439           0 :   addToValues(value);
+     440           0 :   return *this;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsMatrix operator+(const double value, const CoeffsMatrix& coeffsmatrix) {
+     445           0 :   return coeffsmatrix+value;
+     446             : }
+     447             : 
+     448             : 
+     449           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const double value) {
+     450           0 :   return CoeffsMatrix(coeffsmatrix)+=value;
+     451             : }
+     452             : 
+     453             : 
+     454           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const std::vector<double>& values) {
+     455           0 :   addToValues(values);
+     456           0 :   return *this;
+     457             : }
+     458             : 
+     459             : 
+     460           0 : CoeffsMatrix operator+(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     461           0 :   return coeffsmatrix+values;
+     462             : }
+     463             : 
+     464             : 
+     465           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     466           0 :   return CoeffsMatrix(coeffsmatrix)+=values;
+     467             : }
+     468             : 
+     469             : 
+     470           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const double value) {
+     471           0 :   subtractFromValues(value);
+     472           0 :   return *this;
+     473             : }
+     474             : 
+     475             : 
+     476           0 : CoeffsMatrix operator-(const double value, const CoeffsMatrix& coeffsmatrix) {
+     477           0 :   return -1.0*coeffsmatrix+value;
+     478             : }
+     479             : 
+     480             : 
+     481           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const double value) {
+     482           0 :   return CoeffsMatrix(coeffsmatrix)-=value;
+     483             : }
+     484             : 
+     485             : 
+     486           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const std::vector<double>& values) {
+     487           0 :   subtractFromValues(values);
+     488           0 :   return *this;
+     489             : }
+     490             : 
+     491             : 
+     492           0 : CoeffsMatrix operator-(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     493           0 :   return -1.0*coeffsmatrix+values;
+     494             : }
+     495             : 
+     496             : 
+     497           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     498           0 :   return CoeffsMatrix(coeffsmatrix)-=values;
+     499             : }
+     500             : 
+     501             : 
+     502           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const CoeffsMatrix& other_coeffsmatrix) {
+     503           0 :   addToValues(other_coeffsmatrix);
+     504           0 :   return *this;
+     505             : }
+     506             : 
+     507             : 
+     508           0 : CoeffsMatrix CoeffsMatrix::operator+(const CoeffsMatrix& other_coeffsmatrix) const {
+     509           0 :   return CoeffsMatrix(*this)+=other_coeffsmatrix;
+     510             : }
+     511             : 
+     512             : 
+     513           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const CoeffsMatrix& other_coeffsmatrix) {
+     514           0 :   subtractFromValues(other_coeffsmatrix);
+     515           0 :   return *this;
+     516             : }
+     517             : 
+     518             : 
+     519           0 : CoeffsMatrix CoeffsMatrix::operator-(const CoeffsMatrix& other_coeffsmatrix) const {
+     520           0 :   return CoeffsMatrix(*this)-=other_coeffsmatrix;
+     521             : }
+     522             : 
+     523             : 
+     524           0 : void CoeffsMatrix::averageMatrices(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     525           0 :   plumed_massert(sameShape(coeffsmat0,coeffsmat1),"both CoeffsMatrix objects need to have the same shape");
+     526           0 :   for(size_t i=0; i<coeffsmat0.getSize(); i++) {
+     527           0 :     coeffsmat0.data[i] = coeffsmat1.data[i] = 0.5 * (coeffsmat0.data[i]+coeffsmat1.data[i]);
+     528             :   }
+     529           0 : }
+     530             : 
+     531             : 
+     532           0 : void CoeffsMatrix::averageMatrices(const std::vector<CoeffsMatrix*>& coeffsmatSet) {
+     533           0 :   double norm_factor = 1.0/static_cast<double>(coeffsmatSet.size());
+     534           0 :   for(unsigned int k=1; k<coeffsmatSet.size(); k++) {
+     535           0 :     plumed_massert(coeffsmatSet[0]->sameShape(*coeffsmatSet[k]),"All CoeffsMatrix objects need to have the same shape");
+     536             :   }
+     537           0 :   for(size_t i=0; i<coeffsmatSet[0]->getSize(); i++) {
+     538             :     double value = 0.0;
+     539           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     540           0 :       value += coeffsmatSet[k]->data[i];
+     541             :     }
+     542           0 :     value *= norm_factor;
+     543           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     544           0 :       coeffsmatSet[k]->data[i] = value;
+     545             :     }
+     546             :   }
+     547           0 : }
+     548             : 
+     549             : 
+     550             : 
+     551           0 : double CoeffsMatrix::getMinValue() const {
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(data[i]<min_value) {
+     555             :       min_value=data[i];
+     556             :     }
+     557             :   }
+     558           0 :   return min_value;
+     559             : }
+     560             : 
+     561             : 
+     562           0 : double CoeffsMatrix::getMaxValue() const {
+     563             :   double max_value=DBL_MIN;
+     564           0 :   for(size_t i=0; i<data.size(); i++) {
+     565           0 :     if(data[i]>max_value) {
+     566             :       max_value=data[i];
+     567             :     }
+     568             :   }
+     569           0 :   return max_value;
+     570             : }
+     571             : 
+     572             : 
+     573           0 : void CoeffsMatrix::randomizeValuesGaussian(int randomSeed) {
+     574           0 :   Random rnd;
+     575             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     576           0 :   rnd.setSeed(-randomSeed);
+     577           0 :   for(size_t i=0; i<data.size(); i++) {
+     578           0 :     data[i]=rnd.Gaussian();
+     579             :   }
+     580           0 : }
+     581             : 
+     582             : 
+     583           0 : void CoeffsMatrix::resetAveraging() {
+     584           0 :   clear();
+     585             :   resetAveragingCounter();
+     586           0 : }
+     587             : 
+     588             : 
+     589           0 : void CoeffsMatrix::addToAverage(const CoeffsMatrix& coeffsmat) {
+     590           0 :   plumed_massert( data.size()==coeffsmat.getSize(), "Incorrect size");
+     591             :   //
+     592           0 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     593           0 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     594           0 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     595             :   }
+     596             :   //
+     597           0 :   for(size_t i=0; i<data.size(); i++) {
+     598           0 :     data[i]+=(coeffsmat.data[i]-data[i])*aver_decay;
+     599             :   }
+     600           0 :   averaging_counter++;
+     601           0 : }
+     602             : 
+     603             : 
+     604         660 : void CoeffsMatrix::writeToFile(OFile& ofile) {
+     605         660 :   writeHeaderToFile(ofile);
+     606         660 :   writeDataToFile(ofile);
+     607         660 : }
+     608             : 
+     609             : 
+     610           0 : void CoeffsMatrix::writeToFile(const std::string& filepath, const bool append_file, Action* action_pntr) {
+     611           0 :   OFile file;
+     612           0 :   if(action_pntr!=NULL) {
+     613           0 :     file.link(*action_pntr);
+     614             :   }
+     615             :   else {
+     616           0 :     file.link(mycomm);
+     617             :   }
+     618           0 :   if(append_file) { file.enforceRestart(); }
+     619           0 :   file.open(filepath);
+     620           0 :   writeToFile(file);
+     621           0 :   file.close();
+     622           0 : }
+     623             : 
+     624             : 
+     625         660 : void CoeffsMatrix::writeMatrixInfoToFile(OFile& ofile) {
+     626         660 :   std::string field_diagonal = "diagonal_matrix";
+     627         660 :   ofile.addConstantField(field_diagonal).printField(field_diagonal,isDiagonal());
+     628         660 : }
+     629             : 
+     630             : 
+     631         660 : void CoeffsMatrix::writeHeaderToFile(OFile& ofile) {
+     632         660 :   ofile.clearFields();
+     633         660 :   if(isIterationCounterActive()) {
+     634         660 :     writeIterationCounterAndTimeToFile(ofile);
+     635             :   }
+     636         660 :   writeCoeffsInfoToFile(ofile);
+     637         660 :   writeMatrixInfoToFile(ofile);
+     638         660 : }
+     639             : 
+     640             : 
+     641         660 : void CoeffsMatrix::writeDataToFile(OFile& ofile) {
+     642         660 :   if(diagonal_) {
+     643         660 :     writeDataDiagonalToFile(ofile);
+     644             :   }
+     645             :   else {
+     646           0 :     writeDataFullToFile(ofile);
+     647             :   }
+     648         660 : }
+     649             : 
+     650             : 
+     651         660 : void CoeffsMatrix::writeDataDiagonalToFile(OFile& ofile) {
+     652             :   //
+     653         660 :   std::string field_indices_prefix = "idx_";
+     654             :   std::string field_coeffs = getDataLabel();
+     655         660 :   std::string field_index = "index";
+     656             :   //
+     657         660 :   std::string int_fmt = "%8d";
+     658         660 :   std::string str_separate = "#!-------------------";
+     659             :   //
+     660         660 :   std::vector<char> s1(20);
+     661         660 :   std::vector<unsigned int> indices(numberOfDimensions());
+     662         660 :   std::vector<std::string> ilabels(numberOfDimensions());
+     663        1520 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     664        1720 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     665             :   }
+     666             :   //
+     667       28290 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     668       27630 :     indices=getIndices(i);
+     669       77540 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     670       49910 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     671       99820 :       ofile.printField(ilabels[k],s1.data());
+     672             :     }
+     673       55260 :     ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,i));
+     674       27630 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     675       27630 :     ofile.printField();
+     676             :   }
+     677         660 :   ofile.fmtField();
+     678             :   // blank line between iterations to allow proper plotting with gnuplot
+     679         660 :   ofile.printf("%s\n",str_separate.c_str());
+     680         660 :   ofile.printf("\n");
+     681         660 :   ofile.printf("\n");
+     682        1320 : }
+     683             : 
+     684             : 
+     685           0 : void CoeffsMatrix::writeDataFullToFile(OFile& ofile) {
+     686             :   //
+     687           0 :   std::string field_index_row = "idx_row";
+     688           0 :   std::string field_index_column = "idx_column";
+     689             :   std::string field_coeffs = getDataLabel();
+     690             :   //
+     691           0 :   std::string int_fmt = "%8d";
+     692           0 :   std::string str_separate = "#!-------------------";
+     693             :   //
+     694           0 :   std::vector<char> s1(20);
+     695             :   //
+     696           0 :   for(size_t i=0; i<nrows_; i++) {
+     697           0 :     for(size_t j=0; j<ncolumns_; j++) {
+     698             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i);
+     699           0 :       ofile.printField(field_index_row,s1.data());
+     700             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),j);
+     701           0 :       ofile.printField(field_index_column,s1.data());
+     702           0 :       ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,j));
+     703           0 :       ofile.printField();
+     704             :     }
+     705             :   }
+     706           0 :   ofile.fmtField();
+     707             :   // blank line between iterations to allow proper plotting with gnuplot
+     708           0 :   ofile.printf("%s\n",str_separate.c_str());
+     709           0 :   ofile.printf("\n");
+     710           0 :   ofile.printf("\n");
+     711           0 : }
+     712             : 
+     713             : 
+     714             : }
+     715             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func-sort-c.html b/coverage/ves/CoeffsMatrix.h.func-sort-c.html new file mode 100644 index 0000000000..a3122ab3cd --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func.html b/coverage/ves/CoeffsMatrix.h.func.html new file mode 100644 index 0000000000..4635000ae0 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.gcov.html b/coverage/ves/CoeffsMatrix.h.gcov.html new file mode 100644 index 0000000000..c8ee5649c3 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.gcov.html @@ -0,0 +1,287 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func-sort-c.html b/coverage/ves/CoeffsVector.cpp.func-sort-c.html new file mode 100644 index 0000000000..b23c291d17 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func-sort-c.html @@ -0,0 +1,468 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func.html b/coverage/ves/CoeffsVector.cpp.func.html new file mode 100644 index 0000000000..c4ce06d5e9 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func.html @@ -0,0 +1,468 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.gcov.html b/coverage/ves/CoeffsVector.cpp.gcov.html new file mode 100644 index 0000000000..9771d16df7 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.gcov.html @@ -0,0 +1,971 @@ + + + + + + + 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-05-27 13:05: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      341962 : CoeffsVector::~CoeffsVector() {}
+     109             : 
+     110             : 
+     111       23209 : void CoeffsVector::clear() {
+     112       23209 :   data.resize(getSize());
+     113     1833419 :   for(size_t i=0; i<data.size(); i++) {
+     114     1810210 :     data[i]=0.0;
+     115             :   }
+     116       23209 : }
+     117             : 
+     118             : 
+     119           2 : void CoeffsVector::setAllValuesToZero() {
+     120          24 :   for(size_t i=0; i<data.size(); i++) {
+     121          22 :     data[i]=0.0;
+     122             :   }
+     123           2 : }
+     124             : 
+     125             : 
+     126           6 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvector_in) const {
+     127           6 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     128             : }
+     129             : 
+     130             : 
+     131           0 : bool CoeffsVector::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     132           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     133             : }
+     134             : 
+     135             : 
+     136           0 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     137           0 :   return coeffsvec0.sameShape(coeffsvec1);
+     138             : }
+     139             : 
+     140             : 
+     141           0 : void CoeffsVector::resizeCoeffs(const std::vector<unsigned int>& indices_shape_new) {
+     142           0 :   CoeffsVector coeffsVecOld(*this);
+     143           0 :   resizeIndices(indices_shape_new);
+     144           0 :   clear();
+     145           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     146           0 : }
+     147             : 
+     148             : 
+     149           0 : void CoeffsVector::resizeCoeffs(std::vector<BasisFunctions*>& basisf_new) {
+     150           0 :   CoeffsVector coeffsVecOld(*this);
+     151           0 :   resizeIndices(basisf_new);
+     152           0 :   clear();
+     153           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     154           0 : }
+     155             : 
+     156             : 
+     157           0 : void CoeffsVector::sumCommMPI() {
+     158           0 :   mycomm.Sum(data);
+     159           0 : }
+     160             : 
+     161             : 
+     162           0 : void CoeffsVector::sumCommMPI(Communicator& cc) {
+     163           0 :   cc.Sum(data);
+     164           0 : }
+     165             : 
+     166             : 
+     167           0 : void CoeffsVector::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     168           0 :   if(mycomm.Get_rank()==0) {
+     169           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     170           0 :     multi_sim_cc.Sum(data);
+     171           0 :     scaleAllValues(1.0/nwalkers);
+     172             :   }
+     173           0 :   mycomm.Bcast(data,0);
+     174           0 : }
+     175             : 
+     176             : 
+     177         178 : double& CoeffsVector::operator[](const size_t index) {
+     178             :   plumed_dbg_assert(index<data.size());
+     179         178 :   return data[index];
+     180             : }
+     181             : 
+     182             : 
+     183           0 : const double& CoeffsVector::operator[](const size_t index) const {
+     184             :   plumed_dbg_assert(index<data.size());
+     185           0 :   return data[index];
+     186             : }
+     187             : 
+     188             : 
+     189           0 : double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) {
+     190           0 :   return data[getIndex(indices)];
+     191             : }
+     192             : 
+     193             : 
+     194           0 : const double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) const {
+     195           0 :   return data[getIndex(indices)];
+     196             : }
+     197             : 
+     198             : 
+     199     1790345 : double& CoeffsVector::operator()(const size_t index) {
+     200             :   plumed_dbg_assert(index<data.size());
+     201     1790345 :   return data[index];
+     202             : }
+     203             : 
+     204             : 
+     205     1790345 : const double& CoeffsVector::operator()(const size_t index) const {
+     206             :   plumed_dbg_assert(index<data.size());
+     207     1790345 :   return data[index];
+     208             : }
+     209             : 
+     210             : 
+     211           0 : double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) {
+     212           0 :   return data[getIndex(indices)];
+     213             : }
+     214             : 
+     215             : 
+     216           0 : const double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) const {
+     217           0 :   return data[getIndex(indices)];
+     218             : }
+     219             : 
+     220             : 
+     221         219 : void CoeffsVector::setValue(const size_t index, const double value) {
+     222             :   plumed_dbg_assert(index<data.size());
+     223         219 :   data[index]=value;
+     224         219 : }
+     225             : 
+     226             : 
+     227           0 : void CoeffsVector::setValue(const std::vector<unsigned int>& indices, const double value) {
+     228           0 :   setValue(getIndex(indices),value);
+     229           0 : }
+     230             : 
+     231             : 
+     232           0 : void CoeffsVector::addToValue(const size_t index, const double value) {
+     233             :   plumed_dbg_assert(index<data.size());
+     234           0 :   data[index]+=value;
+     235           0 : }
+     236             : 
+     237             : 
+     238           0 : void CoeffsVector::addToValue(const std::vector<unsigned int>& indices, const double value) {
+     239           0 :   addToValue(getIndex(indices),value);
+     240           0 : }
+     241             : 
+     242             : 
+     243       45477 : void CoeffsVector::scaleAllValues(const double scalef) {
+     244     3626338 :   for(size_t i=0; i<data.size(); i++) {
+     245     3580861 :     data[i]*=scalef;
+     246             :   }
+     247       45477 : }
+     248             : 
+     249             : 
+     250       45470 : CoeffsVector& CoeffsVector::operator*=(const double scalef) {
+     251       45470 :   scaleAllValues(scalef);
+     252       45470 :   return *this;
+     253             : }
+     254             : 
+     255             : 
+     256       45430 : CoeffsVector operator*(const double scalef, const CoeffsVector& coeffsvector) {
+     257       45430 :   return CoeffsVector(coeffsvector)*=scalef;
+     258             : }
+     259             : 
+     260             : 
+     261           0 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const double scalef) {
+     262           0 :   return scalef*coeffsvector;
+     263             : }
+     264             : 
+     265             : 
+     266          20 : void CoeffsVector::multiplyWithValues(const std::vector<double>& values) {
+     267          20 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     268         240 :   for(size_t i=0; i<data.size(); i++) {
+     269         220 :     data[i]*=values[i];
+     270             :   }
+     271          20 : }
+     272             : 
+     273             : 
+     274       22765 : CoeffsVector& CoeffsVector::operator*=(const CoeffsVector& other_coeffsvector) {
+     275       22765 :   plumed_massert(data.size()==other_coeffsvector.getSize(),"Coeffs vectors do not have the same size");
+     276     1813440 :   for(size_t i=0; i<data.size(); i++) {
+     277     1790675 :     data[i]*=other_coeffsvector.data[i];
+     278             :   }
+     279       22765 :   return *this;
+     280             : }
+     281             : 
+     282             : 
+     283       22765 : CoeffsVector CoeffsVector::operator*(const CoeffsVector& other_coeffsvector) const {
+     284       22765 :   return CoeffsVector(*this)*=other_coeffsvector;
+     285             : }
+     286             : 
+     287             : 
+     288           0 : CoeffsVector operator*(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     289           0 :   return coeffsvector*values;
+     290             : }
+     291             : 
+     292             : 
+     293          20 : CoeffsVector& CoeffsVector::operator*=(const std::vector<double>& values) {
+     294          20 :   multiplyWithValues(values);
+     295          20 :   return *this;
+     296             : }
+     297             : 
+     298             : 
+     299          20 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     300          20 :   return CoeffsVector(coeffsvector)*=values;
+     301             : }
+     302             : 
+     303             : 
+     304         174 : void CoeffsVector::setValues(const double value) {
+     305        8402 :   for(size_t i=0; i<data.size(); i++) {
+     306        8228 :     data[i]=value;
+     307             :   }
+     308         174 : }
+     309             : 
+     310             : 
+     311         700 : void CoeffsVector::setValues(const std::vector<double>& values) {
+     312         700 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     313       23133 :   for(size_t i=0; i<data.size(); i++) {
+     314       22433 :     data[i]=values[i];
+     315             :   }
+     316         700 : }
+     317             : 
+     318             : 
+     319       23410 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
+     320       23410 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     321     1847404 :   for(size_t i=0; i<data.size(); i++) {
+     322     1823994 :     data[i]=other_coeffsvector.data[i];
+     323             :   }
+     324       23410 : }
+     325             : 
+     326             : 
+     327           0 : CoeffsVector& CoeffsVector::operator=(const double value) {
+     328           0 :   setValues(value);
+     329           0 :   return *this;
+     330             : }
+     331             : 
+     332             : 
+     333         453 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
+     334         453 :   setValues(values);
+     335         453 :   return *this;
+     336             : }
+     337             : 
+     338             : 
+     339             : // CoeffsVector& CoeffsVector::operator=(const CoeffsVector& other_coeffsvector) {
+     340             : //   setValues(other_coeffsvector);
+     341             : //   return *this;
+     342             : // }
+     343             : 
+     344             : 
+     345           0 : CoeffsVector CoeffsVector::operator+() const {
+     346           0 :   return *this;
+     347             : }
+     348             : 
+     349             : 
+     350           0 : CoeffsVector CoeffsVector::operator-() const {
+     351           0 :   return CoeffsVector(*this)*=-1.0;
+     352             : }
+     353             : 
+     354             : 
+     355           0 : void CoeffsVector::addToValues(const double value) {
+     356           0 :   for(size_t i=0; i<data.size(); i++) {
+     357           0 :     data[i]+=value;
+     358             :   }
+     359           0 : }
+     360             : 
+     361             : 
+     362           0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
+     363           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     364           0 :   for(size_t i=0; i<data.size(); i++) {
+     365           0 :     data[i]+=values[i];
+     366             :   }
+     367           0 : }
+     368             : 
+     369             : 
+     370       68145 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
+     371       68145 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     372     5438520 :   for(size_t i=0; i<data.size(); i++) {
+     373     5370375 :     data[i]+=other_coeffsvector.data[i];
+     374             :   }
+     375       68145 : }
+     376             : 
+     377             : 
+     378           0 : void CoeffsVector::subtractFromValues(const double value) {
+     379           0 :   for(size_t i=0; i<data.size(); i++) {
+     380           0 :     data[i]-=value;
+     381             :   }
+     382           0 : }
+     383             : 
+     384             : 
+     385       22810 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
+     386       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     387     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     388     1801040 :     data[i]-=values[i];
+     389             :   }
+     390       22810 : }
+     391             : 
+     392             : 
+     393       45440 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
+     394       45440 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     395     3625800 :   for(size_t i=0; i<data.size(); i++) {
+     396     3580360 :     data[i]-=other_coeffsvector.data[i];
+     397             :   }
+     398       45440 : }
+     399             : 
+     400             : 
+     401           0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
+     402           0 :   addToValues(value);
+     403           0 :   return *this;
+     404             : }
+     405             : 
+     406             : 
+     407           0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
+     408           0 :   return coeffsvector+value;
+     409             : }
+     410             : 
+     411             : 
+     412           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
+     413           0 :   return CoeffsVector(coeffsvector)+=value;
+     414             : }
+     415             : 
+     416             : 
+     417           0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
+     418           0 :   addToValues(values);
+     419           0 :   return *this;
+     420             : }
+     421             : 
+     422             : 
+     423           0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     424           0 :   return coeffsvector+values;
+     425             : }
+     426             : 
+     427             : 
+     428           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     429           0 :   return CoeffsVector(coeffsvector)+=values;
+     430             : }
+     431             : 
+     432             : 
+     433           0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
+     434           0 :   subtractFromValues(value);
+     435           0 :   return *this;
+     436             : }
+     437             : 
+     438             : 
+     439           0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
+     440           0 :   return -1.0*coeffsvector+value;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
+     445           0 :   return CoeffsVector(coeffsvector)-=value;
+     446             : }
+     447             : 
+     448             : 
+     449       22810 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
+     450       22810 :   subtractFromValues(values);
+     451       22810 :   return *this;
+     452             : }
+     453             : 
+     454             : 
+     455           0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     456           0 :   return -1.0*coeffsvector+values;
+     457             : }
+     458             : 
+     459             : 
+     460       22810 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     461       22810 :   return CoeffsVector(coeffsvector)-=values;
+     462             : }
+     463             : 
+     464             : 
+     465       68145 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
+     466       68145 :   addToValues(other_coeffsvector);
+     467       68145 :   return *this;
+     468             : }
+     469             : 
+     470             : 
+     471       22735 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
+     472       22735 :   return CoeffsVector(*this)+=other_coeffsvector;
+     473             : }
+     474             : 
+     475             : 
+     476       45440 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
+     477       45440 :   subtractFromValues(other_coeffsvector);
+     478       45440 :   return *this;
+     479             : }
+     480             : 
+     481             : 
+     482       45420 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
+     483       45420 :   return CoeffsVector(*this)-=other_coeffsvector;
+     484             : }
+     485             : 
+     486             : 
+     487           0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
+     488           0 :   plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
+     489           0 :   for(size_t i=0; i<data.size(); i++) {
+     490           0 :     std::vector<unsigned int> indices=getIndices(i);
+     491           0 :     if(other_coeffsvector.indicesExist(indices)) {
+     492           0 :       size_t oidx = other_coeffsvector.getIndex(indices);
+     493           0 :       data[i] = other_coeffsvector.data[oidx];
+     494             :     }
+     495             :   }
+     496           0 : }
+     497             : 
+     498             : 
+     499           0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     500           0 :   plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
+     501           0 :   for(size_t i=0; i<coeffsvec0.getSize(); i++) {
+     502           0 :     coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
+     503             :   }
+     504           0 : }
+     505             : 
+     506             : 
+     507           0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
+     508           0 :   const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
+     509           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     510           0 :     plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
+     511             :   }
+     512           0 :   for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
+     513             :     double value = 0.0;
+     514           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     515           0 :       value += coeffsvecSet[k]->data[i];
+     516             :     }
+     517           0 :     value *= norm_factor;
+     518           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     519           0 :       coeffsvecSet[k]->data[i] = value;
+     520             :     }
+     521             :   }
+     522           0 : }
+     523             : 
+     524             : 
+     525           0 : double CoeffsVector::getMinValue() const {
+     526           0 :   size_t min_index=0;
+     527           0 :   return getMinValue(min_index);
+     528             : }
+     529             : 
+     530             : 
+     531           0 : double CoeffsVector::getMinValue(size_t& min_index) const {
+     532           0 :   min_index=0;
+     533             :   double min_value=DBL_MAX;
+     534           0 :   for(size_t i=0; i<data.size(); i++) {
+     535           0 :     if(data[i]<min_value) {
+     536             :       min_value=data[i];
+     537           0 :       min_index=i;
+     538             :     }
+     539             :   }
+     540           0 :   return min_value;
+     541             : }
+     542             : 
+     543             : 
+     544           0 : double CoeffsVector::getMinAbsValue() const {
+     545           0 :   size_t min_index=0;
+     546           0 :   return getMinAbsValue(min_index);
+     547             : }
+     548             : 
+     549             : 
+     550           0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
+     551           0 :   min_index=0;
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(std::abs(data[i])<min_value) {
+     555             :       min_value=std::abs(data[i]);
+     556           0 :       min_index=i;
+     557             :     }
+     558             :   }
+     559           0 :   return min_value;
+     560             : }
+     561             : 
+     562             : 
+     563           0 : double CoeffsVector::getMaxValue() const {
+     564           0 :   size_t max_index=0;
+     565           0 :   return getMaxValue(max_index);
+     566             : }
+     567             : 
+     568             : 
+     569           0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
+     570           0 :   max_index=0;
+     571             :   double max_value=DBL_MIN;
+     572           0 :   for(size_t i=0; i<data.size(); i++) {
+     573           0 :     if(data[i]>max_value) {
+     574             :       max_value=data[i];
+     575           0 :       max_index=i;
+     576             :     }
+     577             :   }
+     578           0 :   return max_value;
+     579             : }
+     580             : 
+     581             : 
+     582           0 : double CoeffsVector::getMaxAbsValue() const {
+     583           0 :   size_t max_index=0;
+     584           0 :   return getMaxAbsValue(max_index);
+     585             : }
+     586             : 
+     587             : 
+     588          80 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
+     589          80 :   max_index=0;
+     590             :   double max_value=0.0;
+     591         960 :   for(size_t i=0; i<data.size(); i++) {
+     592         880 :     if(std::abs(data[i])>max_value) {
+     593             :       max_value=std::abs(data[i]);
+     594         180 :       max_index=i;
+     595             :     }
+     596             :   }
+     597          80 :   return max_value;
+     598             : }
+     599             : 
+     600             : 
+     601          80 : double CoeffsVector::getNorm() const {
+     602          80 :   return getL2Norm();
+     603             : }
+     604             : 
+     605             : 
+     606           0 : double CoeffsVector::getL1Norm() const {
+     607             :   double norm=0.0;
+     608           0 :   for(size_t i=0; i<data.size(); i++) {
+     609           0 :     norm+=std::abs(data[i]);
+     610             :   }
+     611           0 :   return norm;
+     612             : }
+     613             : 
+     614             : 
+     615          80 : double CoeffsVector::getL2Norm() const {
+     616             :   double norm=0.0;
+     617         960 :   for(size_t i=0; i<data.size(); i++) {
+     618         880 :     norm+=data[i]*data[i];
+     619             :   }
+     620          80 :   norm=sqrt(norm);
+     621          80 :   return norm;
+     622             : }
+     623             : 
+     624             : 
+     625           0 : double CoeffsVector::getLpNorm(const double p) const {
+     626             :   double norm=0.0;
+     627           0 :   for(size_t i=0; i<data.size(); i++) {
+     628           0 :     norm+=pow(data[i],p);
+     629             :   }
+     630           0 :   norm=pow(norm,(1.0/p));
+     631           0 :   return norm;
+     632             : }
+     633             : 
+     634             : 
+     635          80 : double CoeffsVector::getRMS() const {
+     636          80 :   return getNorm()/sqrt(numberOfCoeffs());
+     637             : }
+     638             : 
+     639             : 
+     640           0 : void CoeffsVector::normalizeCoeffs() {
+     641           0 :   double norm=getNorm();
+     642           0 :   scaleAllValues(norm);
+     643           0 : }
+     644             : 
+     645             : 
+     646           0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
+     647           0 :   Random rnd;
+     648             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     649           0 :   rnd.setSeed(-randomSeed);
+     650           0 :   for(size_t i=0; i<data.size(); i++) {
+     651           0 :     data[i]=rnd.Gaussian();
+     652             :   }
+     653           0 : }
+     654             : 
+     655             : 
+     656           0 : void CoeffsVector::resetAveraging() {
+     657           0 :   clear();
+     658             :   resetAveragingCounter();
+     659           0 : }
+     660             : 
+     661             : 
+     662          20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
+     663          20 :   plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
+     664             :   //
+     665          20 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     666          20 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     667           9 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     668             :   }
+     669             :   //
+     670         240 :   for(size_t i=0; i<data.size(); i++) {
+     671         220 :     data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
+     672             :   }
+     673          20 :   averaging_counter++;
+     674          20 : }
+     675             : 
+     676             : 
+     677           1 : size_t CoeffsVector::countValues(const double value) const {
+     678             :   size_t numvalues=0;
+     679          12 :   for(size_t i=0; i<data.size(); i++) {
+     680          11 :     if(data[i]==value) {
+     681           2 :       numvalues++;
+     682             :     }
+     683             :   }
+     684           1 :   return numvalues;
+     685             : }
+     686             : 
+     687             : 
+     688           0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     689           0 :   OFile file;
+     690           0 :   if(action_pntr!=NULL) {
+     691           0 :     file.link(*action_pntr);
+     692             :   }
+     693             :   else {
+     694           0 :     file.link(mycomm);
+     695             :   }
+     696           0 :   if(append_file) { file.enforceRestart(); }
+     697           0 :   file.open(filepath);
+     698           0 :   writeToFile(file,print_coeffs_descriptions);
+     699           0 :   file.close();
+     700           0 : }
+     701             : 
+     702             : 
+     703        1467 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
+     704             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     705        1467 :   CoeffsSetTmp.push_back(this);
+     706        1467 :   writeHeaderToFile(ofile);
+     707        1467 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     708        1467 : }
+     709             : 
+     710             : 
+     711         881 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
+     712             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     713         881 :   CoeffsSetTmp.push_back(this);
+     714         881 :   CoeffsSetTmp.push_back(aux_coeffsvector);
+     715         881 :   writeHeaderToFile(ofile);
+     716         881 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     717         881 : }
+     718             : 
+     719             : 
+     720           0 : void CoeffsVector::writeToFile(const std::string& filepath, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     721           0 :   OFile file;
+     722           0 :   if(action_pntr!=NULL) {
+     723           0 :     file.link(*action_pntr);
+     724             :   }
+     725             :   else {
+     726           0 :     file.link(coeffsvecSet[0]->getCommunicator());
+     727             :   }
+     728           0 :   if(append_file) { file.enforceRestart(); }
+     729           0 :   file.open(filepath);
+     730           0 :   writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
+     731           0 :   file.close();
+     732           0 : }
+     733             : 
+     734             : 
+     735           0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     736           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     737           0 :     plumed_massert(coeffsvecSet[k]->sameShape(*coeffsvecSet[0]),"Error in writing a set of coeffs to file: The coeffs do not have the same shape and size");
+     738             :   }
+     739           0 :   coeffsvecSet[0]->writeHeaderToFile(ofile);
+     740           0 :   writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
+     741           0 : }
+     742             : 
+     743             : 
+     744        2348 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
+     745        2348 :   ofile.clearFields();
+     746        2348 :   if(isIterationCounterActive()) {
+     747        2061 :     writeIterationCounterAndTimeToFile(ofile);
+     748             :   }
+     749        2348 :   writeCoeffsInfoToFile(ofile);
+     750        2348 : }
+     751             : 
+     752             : 
+     753        2348 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     754             :   //
+     755        2348 :   std::string field_indices_prefix = "idx_";
+     756        2348 :   std::string field_index = "index";
+     757        2348 :   std::string field_description = "description";
+     758             :   //
+     759        2348 :   std::string int_fmt = "%8d";
+     760        2348 :   std::string str_separate = "#!-------------------";
+     761             :   //
+     762        2348 :   unsigned int numvec = coeffsvecSet.size();
+     763        2348 :   unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
+     764             :   unsigned int numcoeffs = coeffsvecSet[0]->getSize();
+     765             :   std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
+     766        2348 :   std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
+     767        2348 :   std::vector<std::string> coeffs_datalabels(numvec);
+     768        5577 :   for(unsigned int k=0; k<numvec; k++) {
+     769        6458 :     coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
+     770             :   }
+     771             :   //
+     772        2348 :   std::vector<char> s1(20);
+     773        2348 :   std::vector<unsigned int> indices(numdim);
+     774        2348 :   std::vector<std::string> ilabels(numdim);
+     775        5260 :   for(unsigned int k=0; k<numdim; k++) {
+     776        5824 :     ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
+     777             :   }
+     778             :   //
+     779       86666 :   for(size_t i=0; i<numcoeffs; i++) {
+     780       84318 :     indices=coeffsvecSet[0]->getIndices(i);
+     781      233206 :     for(unsigned int k=0; k<numdim; k++) {
+     782      148888 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     783      297776 :       ofile.printField(ilabels[k],s1.data());
+     784             :     }
+     785      203216 :     for(unsigned int l=0; l<numvec; l++) {
+     786      237796 :       ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
+     787             :     }
+     788       84318 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     789       89064 :     if(print_coeffs_descriptions) { ofile.printField(field_description,"  "+coeffs_descriptions[i]);}
+     790       84318 :     ofile.printField();
+     791             :   }
+     792        2348 :   ofile.fmtField();
+     793             :   // blank line between iterations to allow proper plotting with gnuplot
+     794        2348 :   ofile.printf("%s\n",str_separate.c_str());
+     795        2348 :   ofile.printf("\n");
+     796        2348 :   ofile.printf("\n");
+     797        9392 : }
+     798             : 
+     799             : 
+     800          75 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
+     801          75 :   ifile.allowIgnoredFields();
+     802             :   size_t ncoeffs_read=0;
+     803         594 :   while(ifile) {
+     804         444 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     805         444 :     if(ifile) {
+     806         409 :       ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
+     807             :     }
+     808             :   }
+     809          75 :   return ncoeffs_read;
+     810             : }
+     811             : 
+     812             : 
+     813          36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
+     814          36 :   ifile.allowIgnoredFields();
+     815             :   size_t ncoeffs_read=0;
+     816          36 :   if(ifile) {
+     817          36 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     818          36 :     if(ifile) {ncoeffs_read=readDataFromFile(ifile,false);}
+     819             :   }
+     820          36 :   return ncoeffs_read;
+     821             : }
+     822             : 
+     823             : 
+     824          40 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
+     825          40 :   IFile file;
+     826          40 :   file.link(mycomm);
+     827          40 :   file.open(filepath);
+     828          40 :   size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
+     829          40 :   file.close();
+     830          40 :   return ncoeffs_read;
+     831          40 : }
+     832             : 
+     833             : 
+     834         406 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
+     835         406 :   if(ifile && isIterationCounterActive()) {
+     836         406 :     getIterationCounterAndTimeFromFile(ifile);
+     837             :   }
+     838         406 :   if(ifile) {
+     839         368 :     getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
+     840             :   }
+     841         406 : }
+     842             : 
+     843             : 
+     844         442 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
+     845             :   //
+     846         442 :   std::string field_indices_prefix = "idx_";
+     847             :   std::string field_coeffs = getDataLabel();
+     848         442 :   std::string field_index = "index";
+     849         442 :   std::string field_description = "description";
+     850             :   //
+     851         442 :   std::vector<std::string> ilabels(numberOfDimensions());
+     852         903 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     853         922 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     854             :   }
+     855             :   //
+     856         442 :   std::vector<unsigned int> indices(numberOfDimensions());
+     857         442 :   double coeff_tmp=0.0;
+     858             :   std::string str_tmp;
+     859             :   size_t ncoeffs_read=0;
+     860             :   //
+     861        5475 :   while(ifile.scanField(field_coeffs,coeff_tmp)) {
+     862             :     int idx_tmp;
+     863       12131 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     864        6696 :       ifile.scanField(ilabels[k],idx_tmp);
+     865        6696 :       indices[k] = static_cast<unsigned int>(idx_tmp);
+     866             :     }
+     867        5435 :     data[getIndex(indices)] = coeff_tmp;
+     868        5435 :     ifile.scanField(field_index,idx_tmp);
+     869        5435 :     if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
+     870           0 :       std::string is1; Tools::convert(idx_tmp,is1);
+     871           0 :       std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
+     872           0 :       plumed_merror(msg);
+     873             :     }
+     874        5435 :     if(ifile.FieldExist(field_description)) { ifile.scanField(field_description,str_tmp); }
+     875             :     //
+     876        5435 :     ifile.scanField();
+     877        5435 :     ncoeffs_read++;
+     878        5435 :     if(ncoeffs_read==numberOfCoeffs()) {
+     879         402 :       if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
+     880           0 :         plumed_merror("something strange about the coefficient file that is being read in, perhaps multiple entries or missing values");
+     881             :       }
+     882         402 :       break;
+     883             :     }
+     884             :   }
+     885             :   // checks on the coeffs read
+     886         442 :   if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
+     887           0 :     plumed_merror("ERROR: missing coefficients when reading from file");
+     888             :   }
+     889             :   //
+     890         442 :   return ncoeffs_read;
+     891         442 : }
+     892             : 
+     893             : 
+     894             : }
+     895             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func-sort-c.html b/coverage/ves/CoeffsVector.h.func-sort-c.html new file mode 100644 index 0000000000..06024f3ddd --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func.html b/coverage/ves/CoeffsVector.h.func.html new file mode 100644 index 0000000000..5e3054d336 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.gcov.html b/coverage/ves/CoeffsVector.h.gcov.html new file mode 100644 index 0000000000..0965830e8b --- /dev/null +++ b/coverage/ves/CoeffsVector.h.gcov.html @@ -0,0 +1,316 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 0000000000..e3afeb68ac --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func.html b/coverage/ves/FermiSwitchingFunction.cpp.func.html new file mode 100644 index 0000000000..2f1a8f08e4 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.gcov.html b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html new file mode 100644 index 0000000000..39c752b68e --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html @@ -0,0 +1,218 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html new file mode 100644 index 0000000000..51271dc4a6 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func.html b/coverage/ves/GridIntegrationWeights.cpp.func.html new file mode 100644 index 0000000000..3e3fc46e0c --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.gcov.html b/coverage/ves/GridIntegrationWeights.cpp.gcov.html new file mode 100644 index 0000000000..0bae77fb63 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html new file mode 100644 index 0000000000..79493b37be --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func.html b/coverage/ves/GridLinearInterpolation.cpp.func.html new file mode 100644 index 0000000000..acb1211b6c --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.gcov.html b/coverage/ves/GridLinearInterpolation.cpp.gcov.html new file mode 100644 index 0000000000..b43fd88782 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.gcov.html @@ -0,0 +1,311 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func-sort-c.html b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html new file mode 100644 index 0000000000..317fdc3366 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func.html b/coverage/ves/GridLinearInterpolation.h.func.html new file mode 100644 index 0000000000..62ff276e1d --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.gcov.html b/coverage/ves/GridLinearInterpolation.h.gcov.html new file mode 100644 index 0000000000..8cb96accf1 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func-sort-c.html b/coverage/ves/GridProjWeights.h.func-sort-c.html new file mode 100644 index 0000000000..ee38d58d87 --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func.html b/coverage/ves/GridProjWeights.h.func.html new file mode 100644 index 0000000000..4fee0a5a2b --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.gcov.html b/coverage/ves/GridProjWeights.h.gcov.html new file mode 100644 index 0000000000..59574b17bb --- /dev/null +++ b/coverage/ves/GridProjWeights.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html new file mode 100644 index 0000000000..7084cad27b --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html @@ -0,0 +1,216 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func.html b/coverage/ves/LinearBasisSetExpansion.cpp.func.html new file mode 100644 index 0000000000..adb2d67fc1 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func.html @@ -0,0 +1,216 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html new file mode 100644 index 0000000000..e2c3ba4ede --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html @@ -0,0 +1,693 @@ + + + + + + + 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-05-27 13:05: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         390 : }
+     106             : 
+     107             : 
+     108           0 : bool LinearBasisSetExpansion::isStaticTargetDistFileOutputActive() const {
+     109             :   bool output_static_targetdist_files=true;
+     110           0 :   if(vesbias_pntr_!=NULL) {
+     111             :     output_static_targetdist_files = vesbias_pntr_->isStaticTargetDistFileOutputActive();
+     112             :   }
+     113           0 :   return output_static_targetdist_files;
+     114             : }
+     115             : 
+     116             : 
+     117          90 : void LinearBasisSetExpansion::linkVesBias(VesBias* vesbias_pntr_in) {
+     118          90 :   vesbias_pntr_ = vesbias_pntr_in;
+     119          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     120             : 
+     121          90 : }
+     122             : 
+     123             : 
+     124           0 : void LinearBasisSetExpansion::linkAction(Action* action_pntr_in) {
+     125           0 :   action_pntr_ = action_pntr_in;
+     126           0 : }
+     127             : 
+     128             : 
+     129         129 : void LinearBasisSetExpansion::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     130         129 :   plumed_massert(grid_bins_in.size()==nargs_,"the number of grid bins given doesn't match the number of arguments");
+     131         129 :   plumed_massert(!bias_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     132         129 :   plumed_massert(!fes_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     133         129 :   grid_bins_=grid_bins_in;
+     134         129 : }
+     135             : 
+     136             : 
+     137          39 : void LinearBasisSetExpansion::setGridBins(const unsigned int nbins) {
+     138          39 :   std::vector<unsigned int> grid_bins_in(nargs_,nbins);
+     139          39 :   setGridBins(grid_bins_in);
+     140          39 : }
+     141             : 
+     142             : 
+     143         220 : std::unique_ptr<Grid> LinearBasisSetExpansion::setupGeneralGrid(const std::string& label_suffix, const bool usederiv) {
+     144         220 :   bool use_spline = false;
+     145         440 :   auto grid_pntr = Tools::make_unique<Grid>(label_+"."+label_suffix,args_pntrs_,grid_min_,grid_max_,grid_bins_,use_spline,usederiv);
+     146         220 :   return grid_pntr;
+     147             : }
+     148             : 
+     149             : 
+     150         166 : void LinearBasisSetExpansion::setupBiasGrid(const bool usederiv) {
+     151         166 :   if(bias_grid_pntr_) {return;}
+     152         258 :   bias_grid_pntr_ = setupGeneralGrid("bias",usederiv);
+     153         129 :   if(biasCutoffActive()) {
+     154           6 :     bias_withoutcutoff_grid_pntr_ = setupGeneralGrid("bias_withoutcutoff",usederiv);
+     155             :   }
+     156             : }
+     157             : 
+     158             : 
+     159         120 : void LinearBasisSetExpansion::setupFesGrid() {
+     160         120 :   if(fes_grid_pntr_) {return;}
+     161          88 :   if(!bias_grid_pntr_) {
+     162          37 :     setupBiasGrid(true);
+     163             :   }
+     164         176 :   fes_grid_pntr_ = setupGeneralGrid("fes",false);
+     165             : }
+     166             : 
+     167             : 
+     168           8 : void LinearBasisSetExpansion::setupFesProjGrid() {
+     169           8 :   if(!fes_grid_pntr_) {
+     170           1 :     setupFesGrid();
+     171             :   }
+     172           8 : }
+     173             : 
+     174             : 
+     175         829 : void LinearBasisSetExpansion::updateBiasGrid() {
+     176         829 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     177         829 :   if(action_pntr_!=NULL &&  getStepOfLastBiasGridUpdate()==action_pntr_->getStep()) {
+     178             :     return;
+     179             :   }
+     180     1982290 :   for(Grid::index_t l=0; l<bias_grid_pntr_->getSize(); l++) {
+     181     1981698 :     std::vector<double> forces(nargs_);
+     182     1981698 :     std::vector<double> args = bias_grid_pntr_->getPoint(l);
+     183     1981698 :     bool all_inside=true;
+     184     1981698 :     double bias=getBiasAndForces(args,all_inside,forces);
+     185             :     //
+     186     1981698 :     if(biasCutoffActive()) {
+     187         600 :       vesbias_pntr_->applyBiasCutoff(bias,forces);
+     188             :     }
+     189             :     //
+     190     1981698 :     if(bias_grid_pntr_->hasDerivatives()) {
+     191     1473981 :       bias_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     192             :     }
+     193             :     else {
+     194      507717 :       bias_grid_pntr_->setValue(l,bias);
+     195             :     }
+     196             :     //
+     197             :   }
+     198         592 :   if(vesbias_pntr_!=NULL) {
+     199         475 :     vesbias_pntr_->setCurrentBiasMaxValue(bias_grid_pntr_->getMaxValue());
+     200             :   }
+     201         592 :   if(action_pntr_!=NULL) {
+     202         475 :     setStepOfLastBiasGridUpdate(action_pntr_->getStep());
+     203             :   }
+     204             : }
+     205             : 
+     206             : 
+     207          27 : void LinearBasisSetExpansion::updateBiasWithoutCutoffGrid() {
+     208          27 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     209          27 :   plumed_massert(biasCutoffActive(),"the bias cutoff has to be active");
+     210          27 :   plumed_massert(vesbias_pntr_!=NULL,"has to be linked to a VesBias to work");
+     211          27 :   if(action_pntr_!=NULL &&  getStepOfLastBiasWithoutCutoffGridUpdate()==action_pntr_->getStep()) {
+     212             :     return;
+     213             :   }
+     214             :   //
+     215        2423 :   for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     216        2400 :     std::vector<double> forces(nargs_);
+     217        2400 :     std::vector<double> args = bias_withoutcutoff_grid_pntr_->getPoint(l);
+     218        2400 :     bool all_inside=true;
+     219        2400 :     double bias=getBiasAndForces(args,all_inside,forces);
+     220        2400 :     if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     221        2400 :       bias_withoutcutoff_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     222             :     }
+     223             :     else {
+     224           0 :       bias_withoutcutoff_grid_pntr_->setValue(l,bias);
+     225             :     }
+     226             :   }
+     227             :   //
+     228          23 :   double bias_max = bias_withoutcutoff_grid_pntr_->getMaxValue();
+     229          23 :   double bias_min = bias_withoutcutoff_grid_pntr_->getMinValue();
+     230             :   double shift = 0.0;
+     231             :   bool bias_shifted=false;
+     232          23 :   if(bias_min < 0.0) {
+     233          22 :     shift += -bias_min;
+     234             :     bias_shifted=true;
+     235          22 :     BiasCoeffs()[0] -= bias_min;
+     236          22 :     bias_max -= bias_min;
+     237             :   }
+     238          23 :   if(bias_max > vesbias_pntr_->getBiasCutoffValue()) {
+     239          22 :     shift += -(bias_max-vesbias_pntr_->getBiasCutoffValue());
+     240             :     bias_shifted=true;
+     241          22 :     BiasCoeffs()[0] -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     242          22 :     bias_max -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     243             :   }
+     244          23 :   if(bias_shifted) {
+     245             :     // this should be done inside a grid function really,
+     246             :     // need to define my grid class for that
+     247        2322 :     for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     248        2300 :       if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     249        2300 :         std::vector<double> zeros(nargs_,0.0);
+     250        2300 :         bias_withoutcutoff_grid_pntr_->addValueAndDerivatives(l,shift,zeros);
+     251             :       }
+     252             :       else {
+     253           0 :         bias_withoutcutoff_grid_pntr_->addValue(l,shift);
+     254             :       }
+     255             :     }
+     256             :   }
+     257          23 :   if(vesbias_pntr_!=NULL) {
+     258             :     vesbias_pntr_->setCurrentBiasMaxValue(bias_max);
+     259             :   }
+     260          23 :   if(action_pntr_!=NULL) {
+     261          23 :     setStepOfLastBiasWithoutCutoffGridUpdate(action_pntr_->getStep());
+     262             :   }
+     263             : }
+     264             : 
+     265             : 
+     266         539 : void LinearBasisSetExpansion::updateFesGrid() {
+     267         539 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     268         539 :   updateBiasGrid();
+     269         539 :   if(action_pntr_!=NULL && getStepOfLastFesGridUpdate() == action_pntr_->getStep()) {
+     270             :     return;
+     271             :   }
+     272             :   //
+     273             :   double bias2fes_scalingf = -1.0;
+     274     1474154 :   for(Grid::index_t l=0; l<fes_grid_pntr_->getSize(); l++) {
+     275     1473681 :     double fes_value = bias2fes_scalingf*bias_grid_pntr_->getValue(l);
+     276     1473681 :     if(log_targetdist_grid_pntr_!=NULL) {
+     277     1224051 :       fes_value += kBT()*log_targetdist_grid_pntr_->getValue(l);
+     278             :     }
+     279     1473681 :     fes_grid_pntr_->setValue(l,fes_value);
+     280             :   }
+     281         473 :   fes_grid_pntr_->setMinToZero();
+     282         473 :   if(action_pntr_!=NULL) {
+     283         473 :     setStepOfLastFesGridUpdate(action_pntr_->getStep());
+     284             :   }
+     285             : }
+     286             : 
+     287             : 
+     288         212 : void LinearBasisSetExpansion::writeBiasGridToFile(OFile& ofile, const bool append_file) const {
+     289         212 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     290         212 :   if(append_file) {ofile.enforceRestart();}
+     291         212 :   bias_grid_pntr_->writeToFile(ofile);
+     292         212 : }
+     293             : 
+     294             : 
+     295           5 : void LinearBasisSetExpansion::writeBiasWithoutCutoffGridToFile(OFile& ofile, const bool append_file) const {
+     296           5 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     297           5 :   if(append_file) {ofile.enforceRestart();}
+     298           5 :   bias_withoutcutoff_grid_pntr_->writeToFile(ofile);
+     299           5 : }
+     300             : 
+     301             : 
+     302         169 : void LinearBasisSetExpansion::writeFesGridToFile(OFile& ofile, const bool append_file) const {
+     303         169 :   plumed_massert(fes_grid_pntr_!=NULL,"the FES grid is not defined");
+     304         169 :   if(append_file) {ofile.enforceRestart();}
+     305         169 :   fes_grid_pntr_->writeToFile(ofile);
+     306         169 : }
+     307             : 
+     308             : 
+     309          36 : void LinearBasisSetExpansion::writeFesProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     310          36 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     311          36 :   auto Fw = Tools::make_unique<FesWeight>(beta_);
+     312          36 :   Grid proj_grid = fes_grid_pntr_->project(proj_arg,Fw.get());
+     313          36 :   proj_grid.setMinToZero();
+     314          36 :   if(append_file) {ofile.enforceRestart();}
+     315          36 :   proj_grid.writeToFile(ofile);
+     316          36 : }
+     317             : 
+     318             : 
+     319          82 : void LinearBasisSetExpansion::writeTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     320          82 :   if(targetdist_grid_pntr_==NULL) {return;}
+     321          82 :   if(append_file) {ofile.enforceRestart();}
+     322          82 :   targetdist_grid_pntr_->writeToFile(ofile);
+     323             : }
+     324             : 
+     325             : 
+     326          82 : void LinearBasisSetExpansion::writeLogTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     327          82 :   if(log_targetdist_grid_pntr_==NULL) {return;}
+     328          82 :   if(append_file) {ofile.enforceRestart();}
+     329          82 :   log_targetdist_grid_pntr_->writeToFile(ofile);
+     330             : }
+     331             : 
+     332             : 
+     333          20 : void LinearBasisSetExpansion::writeTargetDistProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     334          20 :   if(targetdist_grid_pntr_==NULL) {return;}
+     335          20 :   if(append_file) {ofile.enforceRestart();}
+     336          20 :   Grid proj_grid = TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_,proj_arg);
+     337          20 :   proj_grid.writeToFile(ofile);
+     338          20 : }
+     339             : 
+     340             : 
+     341           0 : void LinearBasisSetExpansion::writeTargetDistributionToFile(const std::string& filename) const {
+     342           0 :   OFile of1; OFile of2;
+     343           0 :   if(action_pntr_!=NULL) {
+     344           0 :     of1.link(*action_pntr_); of2.link(*action_pntr_);
+     345             :   }
+     346           0 :   of1.enforceBackup(); of2.enforceBackup();
+     347           0 :   of1.open(filename);
+     348           0 :   of2.open(FileBase::appendSuffix(filename,".log"));
+     349           0 :   writeTargetDistGridToFile(of1);
+     350           0 :   writeLogTargetDistGridToFile(of2);
+     351           0 :   of1.close(); of2.close();
+     352           0 : }
+     353             : 
+     354             : 
+     355     2011787 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     356     2011787 :   unsigned int nargs = args_values.size();
+     357     2011787 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     358     2011787 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     359     2011787 :   plumed_assert(forces.size()==nargs);
+     360     2011787 :   plumed_assert(coeffsderivs_values.size()==coeffs_pntr_in->numberOfCoeffs());
+     361             : 
+     362     2011787 :   std::vector<double> args_values_trsfrm(nargs);
+     363             :   // std::vector<bool>   inside_interval(nargs,true);
+     364     2011787 :   all_inside = true;
+     365             :   //
+     366     2011787 :   std::vector< std::vector <double> > bf_values(nargs);
+     367     2011787 :   std::vector< std::vector <double> > bf_derivs(nargs);
+     368             :   //
+     369     5966255 :   for(unsigned int k=0; k<nargs; k++) {
+     370     3954468 :     bf_values[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     371     3954468 :     bf_derivs[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     372     3954468 :     bool curr_inside=true;
+     373     3954468 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],curr_inside,bf_values[k],bf_derivs[k]);
+     374             :     // inside_interval[k]=curr_inside;
+     375     3954468 :     if(!curr_inside) {all_inside=false;}
+     376     3954468 :     forces[k]=0.0;
+     377             :   }
+     378             :   //
+     379             :   size_t stride=1;
+     380             :   size_t rank=0;
+     381     2011787 :   if(comm_in!=NULL)
+     382             :   {
+     383     2011787 :     stride=comm_in->Get_size();
+     384     2011787 :     rank=comm_in->Get_rank();
+     385             :   }
+     386             :   // loop over coeffs
+     387     2011787 :   double bias=0.0;
+     388   144769949 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     389   142758162 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     390             :     double coeff = coeffs_pntr_in->getValue(i);
+     391             :     double bf_curr=1.0;
+     392   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     393   292286646 :       bf_curr*=bf_values[k][indices[k]];
+     394             :     }
+     395   142758162 :     bias+=coeff*bf_curr;
+     396   142758162 :     coeffsderivs_values[i] = bf_curr;
+     397   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     398             :       double der = 1.0;
+     399   898592256 :       for(unsigned int l=0; l<nargs; l++) {
+     400   606305610 :         if(l!=k) {der*=bf_values[l][indices[l]];}
+     401   292286646 :         else {der*=bf_derivs[l][indices[l]];}
+     402             :       }
+     403   292286646 :       forces[k]-=coeff*der;
+     404             :       // maybe faster but dangerous
+     405             :       // forces[k]-=coeff*bf_curr*(bf_derivs[k][indices[k]]/bf_values[k][indices[k]]);
+     406             :     }
+     407             :   }
+     408             :   //
+     409     2011787 :   if(comm_in!=NULL) {
+     410             :     // coeffsderivs_values is not summed as the mpi Sum is done later on for the averages
+     411     2011787 :     comm_in->Sum(bias);
+     412     2011787 :     comm_in->Sum(forces);
+     413             :   }
+     414     2011787 :   return bias;
+     415     2011787 : }
+     416             : 
+     417             : 
+     418      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     419      862315 :   unsigned int nargs = args_values.size();
+     420      862315 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     421      862315 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     422             : 
+     423      862315 :   std::vector<double> args_values_trsfrm(nargs);
+     424             :   std::vector< std::vector <double> > bf_values;
+     425             :   //
+     426     2583312 :   for(unsigned int k=0; k<nargs; k++) {
+     427     1720997 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     428     1720997 :     std::vector<double> tmp_der(tmp_val.size());
+     429     1720997 :     bool inside=true;
+     430     1720997 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     431     1720997 :     bf_values.push_back(tmp_val);
+     432             :   }
+     433             :   //
+     434             :   size_t stride=1;
+     435             :   size_t rank=0;
+     436      862315 :   if(comm_in!=NULL)
+     437             :   {
+     438           0 :     stride=comm_in->Get_size();
+     439           0 :     rank=comm_in->Get_rank();
+     440             :   }
+     441             :   // loop over basis set
+     442    95955507 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     443    95093192 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     444             :     double bf_curr=1.0;
+     445   298507612 :     for(unsigned int k=0; k<nargs; k++) {
+     446   203414420 :       bf_curr*=bf_values[k][indices[k]];
+     447             :     }
+     448    95093192 :     basisset_values[i] = bf_curr;
+     449             :   }
+     450             :   //
+     451      862315 :   if(comm_in!=NULL) {
+     452           0 :     comm_in->Sum(basisset_values);
+     453             :   }
+     454     1724630 : }
+     455             : 
+     456             : 
+     457         408 : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t index, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in) {
+     458         408 :   unsigned int nargs = args_values.size();
+     459         408 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     460         408 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     461             : 
+     462         408 :   std::vector<double> args_values_trsfrm(nargs);
+     463             :   std::vector< std::vector <double> > bf_values;
+     464             :   //
+     465         938 :   for(unsigned int k=0; k<nargs; k++) {
+     466         530 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     467         530 :     std::vector<double> tmp_der(tmp_val.size());
+     468         530 :     bool inside=true;
+     469         530 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     470         530 :     bf_values.push_back(tmp_val);
+     471             :   }
+     472             :   //
+     473         408 :   std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(index);
+     474             :   double bf_value=1.0;
+     475         938 :   for(unsigned int k=0; k<nargs; k++) {
+     476         530 :     bf_value*=bf_values[k][indices[k]];
+     477             :   }
+     478         408 :   return bf_value;
+     479         408 : }
+     480             : 
+     481             : 
+     482          45 : void LinearBasisSetExpansion::setupUniformTargetDistribution() {
+     483          45 :   std::vector< std::vector <double> > bf_integrals(0);
+     484          45 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     485             :   //
+     486         100 :   for(unsigned int k=0; k<nargs_; k++) {
+     487         110 :     bf_integrals.push_back(basisf_pntrs_[k]->getUniformIntegrals());
+     488             :   }
+     489             :   //
+     490        1672 :   for(size_t i=0; i<ncoeffs_; i++) {
+     491        1627 :     std::vector<unsigned int> indices=bias_coeffs_pntr_->getIndices(i);
+     492             :     double value = 1.0;
+     493        4492 :     for(unsigned int k=0; k<nargs_; k++) {
+     494        2865 :       value*=bf_integrals[k][indices[k]];
+     495             :     }
+     496        1627 :     targetdist_averages[i]=value;
+     497             :   }
+     498          45 :   TargetDistAverages() = targetdist_averages;
+     499          45 : }
+     500             : 
+     501             : 
+     502          45 : void LinearBasisSetExpansion::setupTargetDistribution(TargetDistribution* targetdist_pntr_in) {
+     503          45 :   targetdist_pntr_ = targetdist_pntr_in;
+     504             :   //
+     505          45 :   targetdist_pntr_->setupGrids(args_pntrs_,grid_min_,grid_max_,grid_bins_);
+     506          45 :   targetdist_grid_pntr_      = targetdist_pntr_->getTargetDistGridPntr();
+     507          45 :   log_targetdist_grid_pntr_  = targetdist_pntr_->getLogTargetDistGridPntr();
+     508             :   //
+     509          45 :   if(targetdist_pntr_->isDynamic()) {
+     510          39 :     vesbias_pntr_->enableDynamicTargetDistribution();
+     511             :   }
+     512             :   //
+     513          45 :   if(targetdist_pntr_->biasGridNeeded()) {
+     514           0 :     setupBiasGrid(true);
+     515           0 :     targetdist_pntr_->linkBiasGrid(bias_grid_pntr_.get());
+     516             :   }
+     517          45 :   if(targetdist_pntr_->biasWithoutCutoffGridNeeded()) {
+     518           3 :     setupBiasGrid(true);
+     519           3 :     targetdist_pntr_->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_.get());
+     520             :   }
+     521          45 :   if(targetdist_pntr_->fesGridNeeded()) {
+     522          36 :     setupFesGrid();
+     523          36 :     targetdist_pntr_->linkFesGrid(fes_grid_pntr_.get());
+     524             :   }
+     525             :   //
+     526          45 :   targetdist_pntr_->updateTargetDist();
+     527          45 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     528          45 : }
+     529             : 
+     530             : 
+     531         355 : void LinearBasisSetExpansion::updateTargetDistribution() {
+     532         355 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     533         355 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     534         355 :   if(targetdist_pntr_->biasGridNeeded()) {updateBiasGrid();}
+     535         355 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     536         355 :   if(targetdist_pntr_->fesGridNeeded()) {updateFesGrid();}
+     537         355 :   targetdist_pntr_->updateTargetDist();
+     538         355 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     539         355 : }
+     540             : 
+     541             : 
+     542           8 : void LinearBasisSetExpansion::readInRestartTargetDistribution(const std::string& grid_fname) {
+     543           8 :   targetdist_pntr_->readInRestartTargetDistGrid(grid_fname);
+     544           8 :   if(biasCutoffActive()) {targetdist_pntr_->clearLogTargetDistGrid();}
+     545           8 : }
+     546             : 
+     547             : 
+     548           8 : void LinearBasisSetExpansion::restartTargetDistribution() {
+     549           8 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     550           8 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     551           8 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     552           8 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     553           8 : }
+     554             : 
+     555             : 
+     556         408 : void LinearBasisSetExpansion::calculateTargetDistAveragesFromGrid(const Grid* targetdist_grid_pntr) {
+     557         408 :   plumed_assert(targetdist_grid_pntr!=NULL);
+     558         408 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     559         816 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr);
+     560         408 :   Grid::index_t stride=mycomm_.Get_size();
+     561         408 :   Grid::index_t rank=mycomm_.Get_rank();
+     562      862723 :   for(Grid::index_t l=rank; l<targetdist_grid_pntr->getSize(); l+=stride) {
+     563      862315 :     std::vector<double> args_values = targetdist_grid_pntr->getPoint(l);
+     564      862315 :     std::vector<double> basisset_values(ncoeffs_);
+     565             :     // parallelization done over the grid -> should NOT use parallel in getBasisSetValues!!
+     566      862315 :     getBasisSetValues(args_values,basisset_values,false);
+     567      862315 :     double weight = integration_weights[l]*targetdist_grid_pntr->getValue(l);
+     568    95955507 :     for(unsigned int i=0; i<ncoeffs_; i++) {
+     569    95093192 :       targetdist_averages[i] += weight*basisset_values[i];
+     570             :     }
+     571             :   }
+     572         408 :   mycomm_.Sum(targetdist_averages);
+     573             :   // the overall constant;
+     574         408 :   targetdist_averages[0] = getBasisSetConstant();
+     575         408 :   TargetDistAverages() = targetdist_averages;
+     576         408 : }
+     577             : 
+     578             : 
+     579          39 : void LinearBasisSetExpansion::setBiasMinimumToZero() {
+     580          39 :   plumed_massert(bias_grid_pntr_,"setBiasMinimumToZero can only be used if the bias grid is defined");
+     581          39 :   updateBiasGrid();
+     582          39 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMinValue();
+     583          39 : }
+     584             : 
+     585             : 
+     586           0 : void LinearBasisSetExpansion::setBiasMaximumToZero() {
+     587           0 :   plumed_massert(bias_grid_pntr_,"setBiasMaximumToZero can only be used if the bias grid is defined");
+     588           0 :   updateBiasGrid();
+     589           0 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMaxValue();
+     590           0 : }
+     591             : 
+     592             : 
+     593     1982225 : bool LinearBasisSetExpansion::biasCutoffActive() const {
+     594     1982225 :   if(vesbias_pntr_!=NULL) {return vesbias_pntr_->biasCutoffActive();}
+     595             :   else {return false;}
+     596             : }
+     597             : 
+     598             : 
+     599           0 : double LinearBasisSetExpansion::calculateReweightFactor() const {
+     600           0 :   plumed_massert(targetdist_grid_pntr_!=NULL,"calculateReweightFactor only be used if the target distribution grid is defined");
+     601           0 :   plumed_massert(bias_grid_pntr_,"calculateReweightFactor only be used if the bias grid is defined");
+     602             :   double sum = 0.0;
+     603           0 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_);
+     604             :   //
+     605           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++) {
+     606           0 :     sum += integration_weights[l] * targetdist_grid_pntr_->getValue(l) * exp(+beta_*bias_grid_pntr_->getValue(l));
+     607             :   }
+     608           0 :   if(sum==0.0) sum=std::numeric_limits<double>::min();
+     609           0 :   return (1.0/beta_)*std::log(sum);
+     610             : }
+     611             : 
+     612             : 
+     613             : 
+     614             : 
+     615             : }
+     616             : 
+     617             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html new file mode 100644 index 0000000000..ab1d41e8c8 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func.html b/coverage/ves/LinearBasisSetExpansion.h.func.html new file mode 100644 index 0000000000..86eb43472e --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05:14Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.gcov.html b/coverage/ves/LinearBasisSetExpansion.h.gcov.html new file mode 100644 index 0000000000..4c5e177462 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.gcov.html @@ -0,0 +1,326 @@ + + + + + + + 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-05-27 13:05: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 long int step_of_last_biasgrid_update;
+      78             :   long long int step_of_last_biaswithoutcutoffgrid_update;
+      79             :   long long int step_of_last_fesgrid_update;
+      80             :   //
+      81             :   std::unique_ptr<Grid> bias_grid_pntr_;
+      82             :   std::unique_ptr<Grid> bias_withoutcutoff_grid_pntr_;
+      83             :   std::unique_ptr<Grid> fes_grid_pntr_;
+      84             :   Grid* log_targetdist_grid_pntr_;
+      85             :   Grid* targetdist_grid_pntr_;
+      86             :   //
+      87             :   TargetDistribution* targetdist_pntr_;
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   // Constructor
+      91             :   explicit LinearBasisSetExpansion(
+      92             :     const std::string&,
+      93             :     const double,
+      94             :     Communicator&,
+      95             :     const std::vector<Value*>&,
+      96             :     std::vector<BasisFunctions*>&,
+      97             :     CoeffsVector* bias_coeffs_pntr_in=NULL);
+      98             :   //
+      99             : private:
+     100             :   // copy constructor is disabled (private and unimplemented)
+     101             :   explicit LinearBasisSetExpansion(const LinearBasisSetExpansion&);
+     102             : public:
+     103             :   ~LinearBasisSetExpansion();
+     104             :   //
+     105             :   std::vector<Value*> getPntrsToArguments() const {return args_pntrs_;}
+     106             :   std::vector<BasisFunctions*> getPntrsToBasisFunctions() const {return basisf_pntrs_;}
+     107             :   CoeffsVector* getPntrToBiasCoeffs() const {return bias_coeffs_pntr_;}
+     108             :   Grid* getPntrToBiasGrid() const {return bias_grid_pntr_.get();};
+     109             :   //
+     110             :   unsigned int getNumberOfArguments() const {return nargs_;};
+     111             :   std::vector<unsigned int> getNumberOfBasisFunctions() const {return nbasisf_;};
+     112             :   size_t getNumberOfCoeffs() const {return ncoeffs_;};
+     113             :   //
+     114          83 :   CoeffsVector& BiasCoeffs() const {return *bias_coeffs_pntr_;};
+     115             :   CoeffsVector& TargetDistAverages() const {return *targetdist_averages_pntr_;};
+     116             :   //
+     117             :   void setSerial() {serial_=true;}
+     118             :   void setParallel() {serial_=false;}
+     119             :   //
+     120             :   void linkVesBias(VesBias*);
+     121             :   void linkAction(Action*);
+     122             :   // calculate bias and derivatives
+     123             :   static double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     124             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&);
+     125             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&);
+     126             :   double getBias(const std::vector<double>&, bool&, const bool parallel=true);
+     127             :   //
+     128             :   static void getBasisSetValues(const std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     129             :   void getBasisSetValues(const std::vector<double>&, std::vector<double>&, const bool parallel=true);
+     130             :   //
+     131             :   static double getBasisSetValue(const std::vector<double>&, const size_t, std::vector<BasisFunctions*>&, CoeffsVector*);
+     132             :   double getBasisSetValue(const std::vector<double>&, const size_t);
+     133             :   double getBasisSetConstant();
+     134             :   // Bias grid and output stuff
+     135             :   void setupBiasGrid(const bool usederiv=false);
+     136             :   void updateBiasGrid();
+     137          36 :   void resetStepOfLastBiasGridUpdate() {step_of_last_biasgrid_update = -1000;}
+     138         475 :   void setStepOfLastBiasGridUpdate(long long int step) {step_of_last_biasgrid_update = step;}
+     139         712 :   long long int getStepOfLastBiasGridUpdate() const {return step_of_last_biasgrid_update;}
+     140             :   void writeBiasGridToFile(OFile&, const bool append=false) const;
+     141             :   //
+     142             :   void updateBiasWithoutCutoffGrid();
+     143             :   void resetStepOfLastBiasWithoutCutoffGridUpdate() {step_of_last_biaswithoutcutoffgrid_update = -1000;}
+     144          23 :   void setStepOfLastBiasWithoutCutoffGridUpdate(long long int step) {step_of_last_biaswithoutcutoffgrid_update = step;}
+     145          27 :   long long int getStepOfLastBiasWithoutCutoffGridUpdate() const {return step_of_last_biaswithoutcutoffgrid_update;}
+     146             :   void writeBiasWithoutCutoffGridToFile(OFile&, const bool append=false) const;
+     147             :   //
+     148             :   void setBiasMinimumToZero();
+     149             :   void setBiasMaximumToZero();
+     150             :   //
+     151             :   void setupFesGrid();
+     152             :   void updateFesGrid();
+     153          36 :   void resetStepOfLastFesGridUpdate() {step_of_last_fesgrid_update = -1000;}
+     154         473 :   void setStepOfLastFesGridUpdate(long long int step) {step_of_last_fesgrid_update = step;}
+     155         539 :   long long int getStepOfLastFesGridUpdate() const {return step_of_last_fesgrid_update;}
+     156             :   void writeFesGridToFile(OFile&, const bool append=false) const;
+     157             :   //
+     158             :   void setupFesProjGrid();
+     159             :   void writeFesProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     160             :   //
+     161             :   void writeTargetDistGridToFile(OFile&, const bool append=false) const;
+     162             :   void writeLogTargetDistGridToFile(OFile&, const bool append=false) const;
+     163             :   void writeTargetDistProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     164             :   void writeTargetDistributionToFile(const std::string&) const;
+     165             :   //
+     166             :   std::vector<unsigned int> getGridBins() const {return grid_bins_;}
+     167             :   void setGridBins(const std::vector<unsigned int>&);
+     168             :   void setGridBins(const unsigned int);
+     169             :   //
+     170             :   double getBeta() const {return beta_;}
+     171             :   double getKbT() const {return kbt_;}
+     172             :   double beta() const {return beta_;}
+     173     1224051 :   double kBT() const {return kbt_;}
+     174             :   //
+     175             :   void setupUniformTargetDistribution();
+     176             :   void setupTargetDistribution(TargetDistribution*);
+     177             :   void updateTargetDistribution();
+     178             :   //
+     179             :   void readInRestartTargetDistribution(const std::string&);
+     180             :   void restartTargetDistribution();
+     181             :   //
+     182             :   bool biasCutoffActive() const;
+     183             :   //
+     184             :   double calculateReweightFactor() const;
+     185             :   //
+     186             : private:
+     187             :   //
+     188             :   std::unique_ptr<Grid> setupGeneralGrid(const std::string&, const bool usederiv=false);
+     189             :   //
+     190             :   void calculateTargetDistAveragesFromGrid(const Grid*);
+     191             :   //
+     192             :   bool isStaticTargetDistFileOutputActive() const;
+     193             : };
+     194             : 
+     195             : 
+     196             : inline
+     197             : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values) {
+     198       23750 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     199             : }
+     200             : 
+     201             : 
+     202             : inline
+     203     1988037 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces) {
+     204     1988037 :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     205     3976074 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     206             : }
+     207             : 
+     208             : 
+     209             : inline
+     210             : double LinearBasisSetExpansion::getBias(const std::vector<double>& args_values, bool& all_inside, const bool parallel) {
+     211             :   std::vector<double> forces_dummy(nargs_);
+     212             :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     213             :   if(parallel) {
+     214             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     215             :   }
+     216             :   else {
+     217             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     218             :   }
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, const bool parallel) {
+     224      862315 :   if(parallel) {
+     225           0 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     226             :   }
+     227             :   else {
+     228      862315 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     229             :   }
+     230      862315 : }
+     231             : 
+     232             : 
+     233             : inline
+     234             : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t basisset_index) {
+     235             :   return getBasisSetValue(args_values,basisset_index,basisf_pntrs_, bias_coeffs_pntr_);
+     236             : }
+     237             : 
+     238             : 
+     239             : inline
+     240         408 : double LinearBasisSetExpansion::getBasisSetConstant() {
+     241         408 :   std::vector<double> args_dummy(nargs_,0.0);
+     242         816 :   return getBasisSetValue(args_dummy,0,basisf_pntrs_, bias_coeffs_pntr_);
+     243             : }
+     244             : 
+     245             : 
+     246             : }
+     247             : 
+     248             : }
+     249             : 
+     250             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html new file mode 100644 index 0000000000..0c1c02c53a --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev4168
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func.html b/coverage/ves/MD_LinearExpansionPES.cpp.func.html new file mode 100644 index 0000000000..254e69a1f1 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev4168
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE4168
_ZN4PLMD3ves21MD_LinearExpansionPES4mainEP8_IO_FILES3_RNS_12CommunicatorE40
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves21MD_LinearExpansionPESC2ERKNS_13CLToolOptionsE44
_ZNK4PLMD3ves21MD_LinearExpansionPES11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html new file mode 100644 index 0000000000..062020e1be --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html @@ -0,0 +1,757 @@ + + + + + + + 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-05-27 13:05: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       12548 : PLUMED_REGISTER_CLTOOL(MD_LinearExpansionPES,"ves_md_linearexpansion")
+     151             : 
+     152        4168 : void MD_LinearExpansionPES::registerKeywords( Keywords& keys ) {
+     153        4168 :   CLTool::registerKeywords( keys );
+     154        8336 :   keys.add("compulsory","nstep","10","The number of steps of dynamics you want to run.");
+     155        8336 :   keys.add("compulsory","tstep","0.005","The integration timestep.");
+     156        8336 :   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        8336 :   keys.add("compulsory","friction","10.","The friction of the Langevin thermostat. For multiple replica you can give a separate value for each replica.");
+     158        8336 :   keys.add("compulsory","random_seed","5293818","Value of random number seed.");
+     159        8336 :   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        8336 :   keys.add("compulsory","dimension","1","Number of dimensions, supports 1 to 3.");
+     161        8336 :   keys.add("compulsory","initial_position","Initial position of the particle. For multiple replica you can give a separate value for each replica.");
+     162        8336 :   keys.add("compulsory","replicas","1","Number of replicas.");
+     163        8336 :   keys.add("compulsory","basis_functions_1","Basis functions for dimension 1.");
+     164        8336 :   keys.add("optional","basis_functions_2","Basis functions for dimension 2 if needed.");
+     165        8336 :   keys.add("optional","basis_functions_3","Basis functions for dimension 3 if needed.");
+     166        8336 :   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        8336 :   keys.add("compulsory","output_coeffs","potential-coeffs.out.data","Filename of the output coefficient file for the potential.");
+     168        8336 :   keys.add("compulsory","output_coeffs_fmt","%30.16e","Format of the output coefficient file for the potential. Useful for regtests.");
+     169        8336 :   keys.add("optional","coeffs_prefactor","prefactor for multiplying the coefficients with. For multiple replica you can give a separate value for each replica.");
+     170        8336 :   keys.add("optional","template_coeffs_file","only generate a template coefficient file with the filename given and exit.");
+     171        8336 :   keys.add("compulsory","output_potential_grid","100","The number of grid points used for the potential and histogram output files.");
+     172        8336 :   keys.add("compulsory","output_potential","potential.data","Filename of the potential output file.");
+     173        8336 :   keys.add("compulsory","output_histogram","histogram.data","Filename of the histogram output file.");
+     174        4168 : }
+     175             : 
+     176             : 
+     177          44 : MD_LinearExpansionPES::MD_LinearExpansionPES( const CLToolOptions& co ):
+     178             :   CLTool(co),
+     179          44 :   dim(0),
+     180          44 :   dim_string_prefix("dim")
+     181             : {
+     182          44 :   inputdata=ifile; //commandline;
+     183          44 : }
+     184             : 
+     185             : inline
+     186        3939 : double MD_LinearExpansionPES::calc_energy( const std::vector<Vector>& pos, std::vector<Vector>& forces) {
+     187        3939 :   std::vector<double> pos_tmp(dim);
+     188        3939 :   std::vector<double> forces_tmp(dim,0.0);
+     189        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     190        4646 :     pos_tmp[j]=pos[0][j];
+     191             :   }
+     192        3939 :   bool all_inside = true;
+     193        3939 :   double potential = potential_expansion_pntr->getBiasAndForces(pos_tmp,all_inside,forces_tmp);
+     194        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     195        4646 :     forces[0][j] = forces_tmp[j];
+     196             :   }
+     197        3939 :   return potential;
+     198             : }
+     199             : 
+     200             : 
+     201             : inline
+     202        3939 : double MD_LinearExpansionPES::calc_temp( const std::vector<Vector>& vel) {
+     203             :   double total_KE=0.0;
+     204             :   //! Double the total kinetic energy of the system
+     205        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     206        4646 :     total_KE+=vel[0][j]*vel[0][j];
+     207             :   }
+     208        3939 :   return total_KE / (double) dim; // total_KE is actually 2*KE
+     209             : }
+     210             : 
+     211          40 : int MD_LinearExpansionPES::main( FILE* in, FILE* out, PLMD::Communicator& pc) {
+     212             :   int plumedWantsToStop;
+     213          40 :   Random random;
+     214             :   unsigned int stepWrite=1000;
+     215             : 
+     216          40 :   std::unique_ptr<PLMD::PlumedMain> plumed;
+     217             : 
+     218             :   size_t replicas;
+     219             :   unsigned int coresPerReplica;
+     220          40 :   parse("replicas",replicas);
+     221          40 :   if(replicas==1) {
+     222           9 :     coresPerReplica = pc.Get_size();
+     223             :   } else {
+     224          31 :     if(pc.Get_size()%replicas!=0) {
+     225           0 :       error("the number of MPI processes is not a multiple of the number of replicas.");
+     226             :     }
+     227          31 :     coresPerReplica = pc.Get_size()/replicas;
+     228             :   }
+     229             :   // create intra and inter communicators
+     230          40 :   Communicator intra, inter;
+     231          40 :   if(Communicator::initialized()) {
+     232          33 :     int iworld=(pc.Get_rank() / coresPerReplica);
+     233          33 :     pc.Split(iworld,0,intra);
+     234          33 :     pc.Split(intra.Get_rank(),0,inter);
+     235             :   }
+     236             : 
+     237             :   long long unsigned int nsteps;
+     238          40 :   parse("nstep",nsteps);
+     239             :   double tstep;
+     240          40 :   parse("tstep",tstep);
+     241             :   // initialize to solve a cppcheck 1.86 warning
+     242          40 :   double temp=0.0;
+     243          40 :   std::vector<double> temps_vec(0);
+     244          80 :   parseVector("temperature",temps_vec);
+     245          40 :   if(temps_vec.size()==1) {
+     246          36 :     temp = temps_vec[0];
+     247             :   }
+     248           4 :   else if(replicas > 1 && temps_vec.size()==replicas) {
+     249           4 :     temp = temps_vec[inter.Get_rank()];
+     250             :   }
+     251             :   else {
+     252           0 :     error("problem with temperature keyword, you need to give either one value or a value for each replica.");
+     253             :   }
+     254             :   //
+     255             :   double friction;
+     256          40 :   std::vector<double> frictions_vec(0);
+     257          80 :   parseVector("friction",frictions_vec);
+     258          40 :   if(frictions_vec.size()==1) {
+     259          36 :     friction = frictions_vec[0];
+     260             :   }
+     261           4 :   else if(frictions_vec.size()==replicas) {
+     262           4 :     friction = frictions_vec[inter.Get_rank()];
+     263             :   }
+     264             :   else {
+     265           0 :     error("problem with friction keyword, you need to give either one value or a value for each replica.");
+     266             :   }
+     267             :   //
+     268             :   int seed;
+     269          40 :   std::vector<int> seeds_vec(0);
+     270          40 :   parseVector("random_seed",seeds_vec);
+     271          92 :   for(unsigned int i=0; i<seeds_vec.size(); i++) {
+     272          52 :     if(seeds_vec[i]>0) {seeds_vec[i] = -seeds_vec[i];}
+     273             :   }
+     274          40 :   if(replicas==1) {
+     275           9 :     if(seeds_vec.size()>1) {error("problem with random_seed keyword, for a single replica you should only give one value");}
+     276           9 :     seed = seeds_vec[0];
+     277             :   }
+     278             :   else {
+     279          31 :     if(seeds_vec.size()!=1 && seeds_vec.size()!=replicas) {
+     280           0 :       error("problem with random_seed keyword, for multiple replicas you should give either one value or a separate value for each replica");
+     281             :     }
+     282          31 :     if(seeds_vec.size()==1) {
+     283          27 :       seeds_vec.resize(replicas);
+     284         109 :       for(unsigned int i=1; i<seeds_vec.size(); i++) {seeds_vec[i] = seeds_vec[0] + i;}
+     285             :     }
+     286          31 :     seed = seeds_vec[inter.Get_rank()];
+     287             :   }
+     288             : 
+     289             :   //
+     290          80 :   parse("dimension",dim);
+     291             : 
+     292             :   std::vector<std::string> plumed_inputfiles;
+     293          80 :   parseVector("plumed_input",plumed_inputfiles);
+     294          40 :   if(plumed_inputfiles.size()!=1 && plumed_inputfiles.size()!=replicas) {
+     295           0 :     error("in plumed_input you should either give one file or separate files for each replica.");
+     296             :   }
+     297             : 
+     298          40 :   std::vector<Vector> initPos(replicas);
+     299             :   std::vector<double> initPosTmp;
+     300          80 :   parseVector("initial_position",initPosTmp);
+     301          40 :   if(initPosTmp.size()==dim) {
+     302          48 :     for(unsigned int i=0; i<replicas; i++) {
+     303          72 :       for(unsigned int k=0; k<dim; k++) {
+     304          38 :         initPos[i][k]=initPosTmp[k];
+     305             :       }
+     306             :     }
+     307             :   }
+     308          26 :   else if(initPosTmp.size()==dim*replicas) {
+     309         126 :     for(unsigned int i=0; i<replicas; i++) {
+     310         216 :       for(unsigned int k=0; k<dim; k++) {
+     311         116 :         initPos[i][k]=initPosTmp[i*dim+k];
+     312             :       }
+     313             :     }
+     314             :   }
+     315             :   else {
+     316           0 :     error("problem with initial_position keyword, you need to give either one value or a value for each replica.");
+     317             :   }
+     318             : 
+     319          79 :   auto deleter=[](FILE* f) { fclose(f); };
+     320          40 :   FILE* file_dummy = fopen("/dev/null","w+");
+     321          40 :   plumed_assert(file_dummy);
+     322             :   // call fclose when file_dummy_deleter goes out of scope
+     323             :   std::unique_ptr<FILE,decltype(deleter)> file_dummy_deleter(file_dummy,deleter);
+     324             :   // Note: this should be declared before plumed_bf to make sure the file is closed after plumed_bf has been destroyed
+     325             : 
+     326          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                       %llu\n",nsteps);
+     489          15 :     std::fprintf(out,"Timestep                              %f\n",tstep);
+     490          15 :     std::fprintf(out,"Temperature                           %f",temps_vec[0]);
+     491          18 :     for(unsigned int i=1; i<temps_vec.size(); i++) {std::fprintf(out,",%f",temps_vec[i]);}
+     492             :     std::fprintf(out,"\n");
+     493          15 :     std::fprintf(out,"Friction                              %f",frictions_vec[0]);
+     494          18 :     for(unsigned int i=1; i<frictions_vec.size(); i++) {std::fprintf(out,",%f",frictions_vec[i]);}
+     495             :     std::fprintf(out,"\n");
+     496          15 :     std::fprintf(out,"Random seed                           %d",seeds_vec[0]);
+     497          38 :     for(unsigned int i=1; i<seeds_vec.size(); i++) {std::fprintf(out,",%d",seeds_vec[i]);}
+     498             :     std::fprintf(out,"\n");
+     499          15 :     std::fprintf(out,"Dimensions                            %zu\n",dim);
+     500          34 :     for(unsigned int i=0; i<dim; i++) {
+     501          19 :       std::fprintf(out,"Basis Function %u                      %s\n",i+1,basisf_keywords[i].c_str());
+     502             :     }
+     503             :     std::fprintf(out,"PLUMED input                          %s",plumed_inputfiles[0].c_str());
+     504          16 :     for(unsigned int i=1; i<plumed_inputfiles.size(); i++) {std::fprintf(out,",%s",plumed_inputfiles[i].c_str());}
+     505             :     std::fprintf(out,"\n");
+     506             :     std::fprintf(out,"kBoltzmann taken as 1, use NATURAL_UNITS in the plumed input\n");
+     507          15 :     if(diff_input_coeffs) {std::fprintf(out,"using different coefficients for each replica\n");}
+     508             :   }
+     509             : 
+     510             : 
+     511          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 :     long long unsigned int step_tmp = 0;
+     596          78 :     plumed->cmd("setStepLongLong",&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(long long unsigned int istep=0; istep<nsteps; ++istep) {
+     605             :     //if( istep%20==0 && pc.Get_rank()==0 ) printf("Doing step %llu\n",istep);
+     606             : 
+     607             :     // Langevin thermostat
+     608        3900 :     double lscale=exp(-0.5*tstep*friction); //exp(-0.5*tstep/friction);
+     609        3900 :     double lrand=sqrt((1.-lscale*lscale)*temp);
+     610        8500 :     for(unsigned k=0; k<dim; ++k) {
+     611        4600 :       therm_eng=therm_eng+0.5*velocities[0][k]*velocities[0][k];
+     612        4600 :       velocities[0][k]=lscale*velocities[0][k]+lrand*random.Gaussian();
+     613        4600 :       therm_eng=therm_eng-0.5*velocities[0][k]*velocities[0][k];
+     614             :     }
+     615             : 
+     616             :     // First step of velocity verlet
+     617        8500 :     for(unsigned k=0; k<dim; ++k) {
+     618        4600 :       velocities[0][k] = velocities[0][k] + 0.5*tstep*forces[0][k];
+     619        4600 :       positions[0][k] = positions[0][k] + tstep*velocities[0][k];
+     620             : 
+     621        4600 :       if(periodic[k]) {
+     622         400 :         positions[0][k] = positions[0][k] - floor((positions[0][k]-interval_min[k])/interval_range[k])*interval_range[k];
+     623             :       }
+     624             :       else {
+     625        4200 :         if(positions[0][k]>interval_max[k]) {
+     626           7 :           positions[0][k]=interval_max[k];
+     627           7 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     628             :         }
+     629        4200 :         if(positions[0][k]<interval_min[k]) {
+     630           2 :           positions[0][k]=interval_min[k];
+     631           2 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     632             :         }
+     633             :       }
+     634             :     }
+     635             : 
+     636        3900 :     potential=calc_energy(positions,forces);
+     637             : 
+     638        3900 :     if(plumed) {
+     639        3900 :       long long unsigned int istepplusone=istep+1;
+     640        3900 :       plumedWantsToStop=0;
+     641        7800 :       plumed->cmd("setStepLongLong",&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,"%llu %f %f %f %f %f %f %f %f \n", istep, istep*tstep, positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     671             :     }
+     672             :   }
+     673             : 
+     674             :   //printf("Rank: %d, Size: %d \n", pc.Get_rank(), pc.Get_size() );
+     675             :   //printf("Rank: %d, Size: %d, MultiSimCommRank: %d, MultiSimCommSize: %d \n", pc.Get_rank(), pc.Get_size(), multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     676             : 
+     677             :   return 0;
+     678         395 : }
+     679             : 
+     680             : }
+     681             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func-sort-c.html b/coverage/ves/Opt_Adam.cpp.func-sort-c.html new file mode 100644 index 0000000000..f470e933bd --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func.html b/coverage/ves/Opt_Adam.cpp.func.html new file mode 100644 index 0000000000..ddacd4c77c --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe756createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_120Opt_AdamRegisterMe75D2Ev4168
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.gcov.html b/coverage/ves/Opt_Adam.cpp.gcov.html new file mode 100644 index 0000000000..089e091462 --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(Opt_Adam,"OPT_ADAM")
+      76             : 
+      77             : 
+      78           4 : void Opt_Adam::registerKeywords(Keywords& keys) {
+      79           4 :   Optimizer::registerKeywords(keys);
+      80           4 :   Optimizer::useFixedStepSizeKeywords(keys);
+      81           4 :   Optimizer::useMultipleWalkersKeywords(keys);
+      82           4 :   Optimizer::useMaskKeywords(keys);
+      83           4 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      84           8 :   keys.add("optional","BETA_1","Parameter for the first moment estimate. Defaults to 0.9");
+      85           8 :   keys.add("optional","BETA_2","Parameter for the second moment estimate. Defaults to 0.999");
+      86           8 :   keys.add("optional","EPSILON","Small parameter to avoid division by zero. Defaults to 1e-8");
+      87           8 :   keys.add("optional","ADAMW_WEIGHT_DECAY","Weight decay parameter for the AdamW variant. Defaults to 0");
+      88           8 :   keys.addFlag("AMSGRAD", false, "Use the AMSGrad variant");
+      89           4 : }
+      90             : 
+      91             : 
+      92           2 : Opt_Adam::Opt_Adam(const ActionOptions&ao):
+      93             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      94           2 :   time_(0),
+      95           2 :   beta_1_(0.9),
+      96           2 :   beta_2_(0.999),
+      97           2 :   epsilon_(0.00000001),
+      98           2 :   one_minus_weight_decay_(1.0),
+      99           2 :   amsgrad_(false),
+     100           2 :   adamw_(false),
+     101           2 :   var_coeffs_pntrs_(0)
+     102             : {
+     103             :   // add citation and print it to log
+     104           2 :   log << "  Adam type stochastic gradient decent\n";
+     105           2 :   parseFlag("AMSGRAD",amsgrad_);
+     106           2 :   if (amsgrad_) {
+     107           1 :     log << "  Using the AMSGrad variant of the Adam algorithm, see and cite\n";
+     108             :   }
+     109             : 
+     110           2 :   double tmp_weight_decay = 0.0;
+     111           2 :   parse("ADAMW_WEIGHT_DECAY",tmp_weight_decay);
+     112           2 :   if (tmp_weight_decay != 0.0) {
+     113           0 :     adamw_ = true;
+     114           0 :     log << "  Using the AdamW variant (Adam with weight decay), see and cite\n";
+     115           0 :     one_minus_weight_decay_ = 1 - tmp_weight_decay;
+     116           0 :     log << "    weight decay parameter: " << tmp_weight_decay << "\n";
+     117             :   }
+     118             : 
+     119           2 :   log << "  Adam parameters:\n";
+     120           2 :   parse("BETA_1",beta_1_);
+     121           2 :   plumed_massert(beta_1_ > 0 && beta_1_ <= 1, "BETA_1 must be between 0 and 1");
+     122           2 :   log << "    beta_1: " << beta_1_ << "\n";
+     123             : 
+     124           2 :   parse("BETA_2",beta_2_);
+     125           2 :   plumed_massert(beta_2_ > 0 && beta_2_ <= 1, "BETA_2 must be between 0 and 1");
+     126           2 :   log << "    beta_2: " << beta_2_ << "\n";
+     127             : 
+     128           2 :   parse("EPSILON",epsilon_);
+     129           2 :   plumed_massert(epsilon_ > 0 && epsilon_ <= 1, "EPSILON must be between 0 and 1");
+     130           2 :   log << "    epsilon: " << epsilon_ << "\n";
+     131             : 
+     132             : 
+     133             :   // set up the coeff vector for the 2nd moment of the gradient (variance)
+     134           4 :   for (unsigned i = 0; i < numberOfCoeffsSets(); ++i) {
+     135           2 :     var_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(Coeffs(i))));
+     136           4 :     VarCoeffs(i).replaceLabelString("coeffs","grad_var");
+     137           2 :     VarCoeffs(i).setAllValuesToZero(); // can Coeffs(i) even be non-zero at this point?
+     138             : 
+     139             :     // add second set of coefficients to store the maximum values of the 2nd moment
+     140           2 :     if (amsgrad_) {
+     141           1 :       varmax_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(VarCoeffs(i))));
+     142           2 :       VarmaxCoeffs(i).replaceLabelString("coeffs","grad_varmax");
+     143             :     }
+     144             : 
+     145             :     // also rename the Coeffs used for the mean of the gradient
+     146           4 :     AuxCoeffs(i).replaceLabelString("coeffs","grad_mean");
+     147             :   }
+     148             : 
+     149           2 :   checkRead();
+     150           2 : }
+     151             : 
+     152             : 
+     153          20 : void Opt_Adam::coeffsUpdate(const unsigned int c_id) {
+     154          20 :   time_++;
+     155             :   // AuxCoeffs is used for first moment (mean)
+     156          20 :   AuxCoeffs(c_id) *= beta_1_;
+     157          20 :   AuxCoeffs(c_id) += (1 - beta_1_ ) * Gradient(c_id) * CoeffsMask(c_id);
+     158          20 :   VarCoeffs(c_id) *= beta_2_;
+     159          20 :   VarCoeffs(c_id) += (1 - beta_2_ ) * Gradient(c_id) * Gradient(c_id) * CoeffsMask(c_id);
+     160             : 
+     161          20 :   if (amsgrad_) {
+     162         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     163         110 :       if (VarCoeffs(c_id).getValue(i) > VarmaxCoeffs(c_id).getValue(i)) {
+     164          95 :         VarmaxCoeffs(c_id)[i] = VarCoeffs(c_id).getValue(i);
+     165             :       }
+     166             :     }
+     167             :   }
+     168             : 
+     169             :   // store sqrt of VarCoeffs in vector, easier than writing a CoeffsVector::sqrt() function
+     170             :   // also directly add epsilon and invert to multiply with the Coeffs in last step
+     171             :   std::vector<double> var_coeffs_sqrt;
+     172          20 :   if (!amsgrad_) {
+     173         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     174         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarCoeffs(c_id).getValue(i)) + epsilon));
+     175             :     }
+     176             :   }
+     177             :   else { // use VarmaxCoffs instead of VarCoeffs
+     178         120 :     for (size_t i = 0; i< VarmaxCoeffs(c_id).getSize(); ++i) {
+     179         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarmaxCoeffs(c_id).getValue(i)) + epsilon));
+     180             :     }
+     181             :   }
+     182             : 
+     183             :   // bias correction
+     184          20 :   double scalefactor = StepSize(c_id) * sqrt(1 - pow(beta_2_, time_)) / (1 - pow(beta_1_, time_));
+     185             : 
+     186          20 :   if (adamw_) { // check is not necessary but probably faster than always multiplying by 1
+     187           0 :     Coeffs(c_id) *= one_minus_weight_decay_ * CoeffsMask(c_id);
+     188             :   }
+     189             : 
+     190             :   // coeff update
+     191          20 :   Coeffs(c_id) -= scalefactor * AuxCoeffs(c_id) * var_coeffs_sqrt * CoeffsMask(c_id);
+     192          20 : }
+     193             : 
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html new file mode 100644 index 0000000000..b934739f6d --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE77
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199D2Ev4168
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html new file mode 100644 index 0000000000..95182ded66 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe1996createERKNS_13ActionOptionsE75
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_132Opt_BachAveragedSGDRegisterMe199D2Ev4168
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE77
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html new file mode 100644 index 0000000000..2bc032c36c --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html @@ -0,0 +1,378 @@ + + + + + + + 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-05-27 13:05: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       12654 : PLUMED_REGISTER_ACTION(Opt_BachAveragedSGD,"OPT_AVERAGED_SGD")
+     200             : 
+     201             : 
+     202          77 : void Opt_BachAveragedSGD::registerKeywords(Keywords& keys) {
+     203          77 :   Optimizer::registerKeywords(keys);
+     204          77 :   Optimizer::useFixedStepSizeKeywords(keys);
+     205          77 :   Optimizer::useMultipleWalkersKeywords(keys);
+     206          77 :   Optimizer::useHessianKeywords(keys);
+     207          77 :   Optimizer::useMaskKeywords(keys);
+     208          77 :   Optimizer::useRestartKeywords(keys);
+     209          77 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+     210          77 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+     211         154 :   keys.add("hidden","COMBINED_GRADIENT_FILE","the name of output file for the combined gradient (gradient + Hessian term)");
+     212         154 :   keys.add("hidden","COMBINED_GRADIENT_OUTPUT","how often the combined gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if COMBINED_GRADIENT_FILE is specficed");
+     213         154 :   keys.add("hidden","COMBINED_GRADIENT_FMT","specify format for combined gradient file(s) (useful for decrease the number of digits in regtests)");
+     214         154 :   keys.add("optional","EXP_DECAYING_AVER","calculate the averaged coefficients using exponentially decaying averaging using the decaying constant given here in the number of iterations");
+     215          77 : }
+     216             : 
+     217             : 
+     218             : 
+     219          75 : Opt_BachAveragedSGD::Opt_BachAveragedSGD(const ActionOptions&ao):
+     220             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+     221          75 :   combinedgradient_wstride_(100),
+     222          75 :   decaying_aver_tau_(0.0)
+     223             : {
+     224          75 :   log.printf("  Averaged stochastic gradient decent, see and cite ");
+     225         150 :   log << plumed.cite("Bach and Moulines, NIPS 26, 773-781 (2013)");
+     226          75 :   log.printf("\n");
+     227          75 :   unsigned int decaying_aver_tau_int=0;
+     228          75 :   parse("EXP_DECAYING_AVER",decaying_aver_tau_int);
+     229          75 :   if(decaying_aver_tau_int>0) {
+     230           2 :     decaying_aver_tau_ = static_cast<double>(decaying_aver_tau_int);
+     231           2 :     log.printf("  Coefficients calculated using an exponentially decaying average with a decaying constant of %u iterations, see and cite ",decaying_aver_tau_int);
+     232           4 :     log << plumed.cite("Invernizzi, Valsson, and Parrinello, Proc. Natl. Acad. Sci. USA 114, 3370-3374 (2017)");
+     233           2 :     log.printf("\n");
+     234             :   }
+     235             :   //
+     236             :   std::vector<std::string> combinedgradient_fnames;
+     237          75 :   parseFilenames("COMBINED_GRADIENT_FILE",combinedgradient_fnames);
+     238         150 :   parse("COMBINED_GRADIENT_OUTPUT",combinedgradient_wstride_);
+     239          75 :   setupOFiles(combinedgradient_fnames,combinedgradientOFiles_,useMultipleWalkers());
+     240          75 :   std::string combinedgradient_fmt="";
+     241         150 :   parse("COMBINED_GRADIENT_FMT",combinedgradient_fmt);
+     242          75 :   if(combinedgradient_fnames.size()>0) {
+     243          12 :     for(unsigned int i=0; i<numberOfCoeffsSets(); i++) {
+     244          12 :       auto combinedgradient_tmp = Tools::make_unique<CoeffsVector>(*getGradientPntrs()[i]);
+     245           6 :       std::string label = getGradientPntrs()[i]->getLabel();
+     246           6 :       if(label.find("gradient")!=std::string::npos) {
+     247          12 :         label.replace(label.find("gradient"), std::string("gradient").length(), "combined_gradient");
+     248             :       }
+     249             :       else {
+     250             :         label += "_combined";
+     251             :       }
+     252           6 :       combinedgradient_tmp->setLabels(label);
+     253           6 :       if(combinedgradient_fmt.size()>0) {
+     254             :         combinedgradient_tmp->setOutputFmt(combinedgradient_fmt);
+     255             :       }
+     256           6 :       combinedgradient_pntrs_.emplace_back(std::move(combinedgradient_tmp));
+     257           6 :     }
+     258             :     //
+     259           6 :     if(numberOfCoeffsSets()==1) {
+     260          12 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to file %s every %u iterations\n",combinedgradientOFiles_[0]->getPath().c_str(),combinedgradient_wstride_);
+     261             :     }
+     262             :     else {
+     263           0 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to the following files every %u iterations:\n",combinedgradient_wstride_);
+     264           0 :       for(unsigned int i=0; i<combinedgradientOFiles_.size(); i++) {
+     265           0 :         log.printf("   coefficient set %u: %s\n",i,combinedgradientOFiles_[i]->getPath().c_str());
+     266             :       }
+     267             :     }
+     268             :   }
+     269             :   //
+     270             : 
+     271          75 :   turnOnHessian();
+     272          75 :   checkRead();
+     273          75 : }
+     274             : 
+     275             : 
+     276       22675 : void Opt_BachAveragedSGD::coeffsUpdate(const unsigned int c_id) {
+     277             :   //
+     278       22675 :   if(combinedgradientOFiles_.size()>0 && (getIterationCounter()+1)%combinedgradient_wstride_==0) {
+     279          60 :     CombinedGradient(c_id).setValues( ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) ) );
+     280          60 :     combinedgradient_pntrs_[c_id]->setIterationCounterAndTime(getIterationCounter()+1,getTime());
+     281          60 :     combinedgradient_pntrs_[c_id]->writeToFile(*combinedgradientOFiles_[c_id]);
+     282             :   }
+     283             :   //
+     284             :   double aver_decay = getAverDecay();
+     285       22675 :   AuxCoeffs(c_id) += - StepSize(c_id)*CoeffsMask(c_id) * ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) );
+     286             :   //AuxCoeffs() = AuxCoeffs() - StepSize() * ( Gradient() + Hessian()*(AuxCoeffs()-Coeffs()) );
+     287       22675 :   Coeffs(c_id) += aver_decay * ( AuxCoeffs(c_id)-Coeffs(c_id) );
+     288       22675 : }
+     289             : 
+     290             : 
+     291             : inline
+     292             : double Opt_BachAveragedSGD::getAverDecay() const {
+     293       22675 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+     294       22675 :   if(decaying_aver_tau_ > 0.0 && (getIterationCounterDbl() + 1.0) > decaying_aver_tau_) {
+     295          14 :     aver_decay = 1.0 / decaying_aver_tau_;
+     296             :   }
+     297             :   return aver_decay;
+     298             : }
+     299             : 
+     300             : 
+     301             : }
+     302             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func-sort-c.html b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html new file mode 100644 index 0000000000..189f8ad06e --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func.html b/coverage/ves/Opt_Dummy.cpp.func.html new file mode 100644 index 0000000000..5e5cc9de99 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe856createERKNS_13ActionOptionsE1
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_121Opt_DummyRegisterMe85D2Ev4168
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.gcov.html b/coverage/ves/Opt_Dummy.cpp.gcov.html new file mode 100644 index 0000000000..bcc48aee38 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(Opt_Dummy,"OPT_DUMMY")
+      86             : 
+      87             : 
+      88           3 : void Opt_Dummy::registerKeywords(Keywords& keys) {
+      89           3 :   Optimizer::registerKeywords(keys);
+      90             :   //
+      91           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      92           3 :   Optimizer::useHessianKeywords(keys);
+      93           3 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+      94           6 :   keys.addFlag("MONITOR_HESSIAN",false,"also monitor the Hessian");
+      95           3 : }
+      96             : 
+      97             : 
+      98           1 : Opt_Dummy::Opt_Dummy(const ActionOptions&ao):
+      99           1 :   PLUMED_VES_OPTIMIZER_INIT(ao)
+     100             : {
+     101           1 :   log.printf("  fake optimizer that does not update coefficients\n");
+     102           1 :   log.printf("  can be used to monitor gradient and Hessian for debugging purposes\n");
+     103           1 :   bool monitor_hessian = false;
+     104           1 :   parseFlag("MONITOR_HESSIAN",monitor_hessian);
+     105           1 :   if(monitor_hessian) {
+     106           1 :     turnOnHessian();
+     107           1 :     log.printf("  the Hessian will also be monitored\n");
+     108             :   }
+     109             :   else {
+     110           0 :     turnOffHessian();
+     111             :   }
+     112           1 :   turnOffCoeffsOutputFiles();
+     113           1 :   checkRead();
+     114           1 : }
+     115             : 
+     116             : 
+     117          10 : void Opt_Dummy::coeffsUpdate(const unsigned int c_id) {}
+     118             : 
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html new file mode 100644 index 0000000000..a27c5d6647 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html new file mode 100644 index 0000000000..92fa27462b --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe546createERKNS_13ActionOptionsE1
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131Opt_RobbinsMonroSGDRegisterMe54D2Ev4168
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html new file mode 100644 index 0000000000..94ca01d9d9 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05: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       12506 : PLUMED_REGISTER_ACTION(Opt_RobbinsMonroSGD,"OPT_ROBBINS_MONRO_SGD")
+      55             : 
+      56             : 
+      57           3 : void Opt_RobbinsMonroSGD::registerKeywords(Keywords& keys) {
+      58           3 :   Optimizer::registerKeywords(keys);
+      59           3 :   Optimizer::useDynamicStepSizeKeywords(keys);
+      60           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      61           3 :   Optimizer::useMaskKeywords(keys);
+      62           3 :   Optimizer::useRestartKeywords(keys);
+      63             :   // Optimizer::useMonitorAveragesKeywords(keys);
+      64           3 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      65           6 :   keys.add("optional","DECAY_CONSTANT","the decay constant used for the step size.");
+      66           3 : }
+      67             : 
+      68             : 
+      69           1 : Opt_RobbinsMonroSGD::Opt_RobbinsMonroSGD(const ActionOptions&ao):
+      70             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      71           1 :   decay_constant_(1.0)
+      72             : {
+      73           1 :   parse("DECAY_CONSTANT",decay_constant_);
+      74           1 :   if(decay_constant_<1.0) {
+      75           0 :     plumed_merror("the value given in DECAY_CONSTANT doesn't make sense, it should be larger than 1.0");
+      76             :   }
+      77           1 :   if(decay_constant_>1.0) {
+      78           1 :     log.printf("  using a decay constant of %f\n",decay_constant_);
+      79             :   }
+      80           1 :   checkRead();
+      81           1 : }
+      82             : 
+      83             : 
+      84          10 : void Opt_RobbinsMonroSGD::coeffsUpdate(const unsigned int c_id) {
+      85             :   // getIterationCounterDbl() gives n-1 as it is updated afterwards.
+      86          10 :   double current_stepsize =  StepSize(c_id) /(1.0 + getIterationCounterDbl()/decay_constant_);
+      87             :   setCurrentStepSize(current_stepsize,c_id);
+      88          10 :   Coeffs(c_id) += - current_stepsize * CoeffsMask(c_id) * Gradient(c_id);
+      89             :   //
+      90          10 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+      91          10 :   AuxCoeffs(c_id) += aver_decay * ( Coeffs(c_id)-AuxCoeffs(c_id) );
+      92          10 : }
+      93             : 
+      94             : 
+      95             : }
+      96             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func-sort-c.html b/coverage/ves/Optimizer.cpp.func-sort-c.html new file mode 100644 index 0000000000..1a8a7a3032 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-05-27 13:05:14Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD2Ev79
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer6updateEv22879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func.html b/coverage/ves/Optimizer.cpp.func.html new file mode 100644 index 0000000000..d3d520f625 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func.html @@ -0,0 +1,200 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-05-27 13:05: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_8KeywordsE84
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer6updateEv22879
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9OptimizerD2Ev79
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.gcov.html b/coverage/ves/Optimizer.cpp.gcov.html new file mode 100644 index 0000000000..b99f8624da --- /dev/null +++ b/coverage/ves/Optimizer.cpp.gcov.html @@ -0,0 +1,1337 @@ + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-05-27 13:05: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             :       coeffs_fnames.clear();
+     385             :     }
+     386          79 :     setupOFiles(coeffs_fnames,coeffsOFiles_,mw_single_files);
+     387         158 :     parse("COEFFS_FMT",coeffs_output_fmt_);
+     388          79 :     if(coeffs_output_fmt_.size()>0) {
+     389         162 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     390          84 :         coeffs_pntrs_[i]->setOutputFmt(coeffs_output_fmt_);
+     391             :       }
+     392             :     }
+     393          79 :     if(!getRestart()) {
+     394         136 :       for(unsigned int i=0; i<coeffsOFiles_.size(); i++) {
+     395          70 :         coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     396             :       }
+     397             :     }
+     398          79 :     if(coeffs_fnames.size()>0) {
+     399          79 :       if(ncoeffssets_==1) {
+     400         152 :         log.printf("  Coefficients will be written out to file %s every %u iterations\n",coeffsOFiles_[0]->getPath().c_str(),coeffs_wstride_);
+     401             :       }
+     402             :       else {
+     403           3 :         log.printf("  Coefficients will be written out to the following files every %u iterations:\n",coeffs_wstride_);
+     404          12 :         for(unsigned int i=0; i<coeffs_fnames.size(); i++) {
+     405          18 :           log.printf("   coefficient set %u: %s\n",i,coeffsOFiles_[i]->getPath().c_str());
+     406             :         }
+     407             :       }
+     408             :     }
+     409             :     else {
+     410           0 :       log.printf("  Output of coefficients to file has been disabled\n");
+     411             :     }
+     412             :   }
+     413             : 
+     414             :   std::vector<std::string> gradient_fnames;
+     415         158 :   if(keywords.exists("GRADIENT_FILE")) {
+     416          79 :     parseFilenames("GRADIENT_FILE",gradient_fnames);
+     417         158 :     parse("GRADIENT_OUTPUT",gradient_wstride_);
+     418             : 
+     419          79 :     if(coeffs_fnames.size()>0) {
+     420         151 :       for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     421          72 :         plumed_massert(gradient_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and GRADIENT_FILE cannot be the same");
+     422             :       }
+     423             :     }
+     424          79 :     setupOFiles(gradient_fnames,gradientOFiles_,mw_single_files);
+     425         158 :     parse("GRADIENT_FMT",gradient_output_fmt_);
+     426          79 :     if(gradient_output_fmt_.size()>0) {
+     427         138 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     428          72 :         gradient_pntrs_[i]->setOutputFmt(gradient_output_fmt_);
+     429             :       }
+     430             :     }
+     431             : 
+     432          79 :     if(gradient_fnames.size()>0) {
+     433          66 :       if(ncoeffssets_==1) {
+     434         126 :         log.printf("  Gradient will be written out to file %s every %u iterations\n",gradientOFiles_[0]->getPath().c_str(),gradient_wstride_);
+     435             :       }
+     436             :       else {
+     437           3 :         log.printf("  Gradient will be written out to the following files every %u iterations:\n",gradient_wstride_);
+     438          12 :         for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     439          18 :           log.printf("   coefficient set %u: %s\n",i,gradientOFiles_[i]->getPath().c_str());
+     440             :         }
+     441             :       }
+     442             :     }
+     443             :   }
+     444             : 
+     445             :   std::vector<std::string> hessian_fnames;
+     446         158 :   if(keywords.exists("HESSIAN_FILE")) {
+     447          76 :     parseFilenames("HESSIAN_FILE",hessian_fnames);
+     448         152 :     parse("HESSIAN_OUTPUT",hessian_wstride_);
+     449             : 
+     450          76 :     if(coeffs_fnames.size()>0) {
+     451         142 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     452          66 :         plumed_massert(hessian_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and HESSIAN_FILE cannot be the same");
+     453             :       }
+     454             :     }
+     455          76 :     if(gradient_fnames.size()>0) {
+     456         131 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     457          66 :         plumed_massert(hessian_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and HESSIAN_FILE cannot be the same");
+     458             :       }
+     459             :     }
+     460          76 :     setupOFiles(hessian_fnames,hessianOFiles_,mw_single_files);
+     461         152 :     parse("HESSIAN_FMT",hessian_output_fmt_);
+     462             : 
+     463          76 :     if(hessian_fnames.size()>0) {
+     464          62 :       if(ncoeffssets_==1) {
+     465         120 :         log.printf("  Hessian will be written out to file %s every %u iterations\n",hessianOFiles_[0]->getPath().c_str(),hessian_wstride_);
+     466             :       }
+     467             :       else {
+     468           2 :         log.printf("  Hessian will be written out to the following files every %u iterations:\n",hessian_wstride_);
+     469           8 :         for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     470          12 :           log.printf("   coefficient set %u: %s\n",i,hessianOFiles_[i]->getPath().c_str());
+     471             :         }
+     472             :       }
+     473             :     }
+     474             :   }
+     475             : 
+     476             : 
+     477             :   //
+     478         158 :   if(keywords.exists("MASK_FILE")) {
+     479             :     std::vector<std::string> mask_fnames_in;
+     480         156 :     parseVector("MASK_FILE",mask_fnames_in);
+     481          78 :     if(mask_fnames_in.size()==1 && ncoeffssets_>1) {
+     482           0 :       if(identical_coeffs_shape_) {mask_fnames_in.resize(ncoeffssets_,mask_fnames_in[0]);}
+     483           0 :       else {plumed_merror("the coefficients indices shape differs between biases so you need to give a separate file for each coefficient set\n");}
+     484             :     }
+     485          78 :     if(mask_fnames_in.size()>0 && mask_fnames_in.size()!=ncoeffssets_) {
+     486           0 :       plumed_merror("Error in MASK_FILE keyword: either give one value for all biases or a separate value for each coefficient set");
+     487             :     }
+     488             : 
+     489          78 :     coeffs_mask_pntrs_.resize(ncoeffssets_);
+     490         162 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     491         168 :       coeffs_mask_pntrs_[i] = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_[i]);
+     492         168 :       coeffs_mask_pntrs_[i]->setLabels("mask");
+     493          84 :       coeffs_mask_pntrs_[i]->setValues(1.0);
+     494         168 :       coeffs_mask_pntrs_[i]->setOutputFmt("%f");
+     495             :     }
+     496             : 
+     497          78 :     if(mask_fnames_in.size()>0) {
+     498           1 :       if(ncoeffssets_==1) {
+     499           1 :         size_t nread = coeffs_mask_pntrs_[0]->readFromFile(mask_fnames_in[0],true,true);
+     500           1 :         log.printf("  read %zu values from mask file %s\n",nread,mask_fnames_in[0].c_str());
+     501           1 :         size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     502           1 :         log.printf("  deactived optimization of %zu coefficients\n",ndeactived);
+     503             :       }
+     504             :       else {
+     505           0 :         for(unsigned int i=0; i<ncoeffssets_; i++) {
+     506           0 :           size_t nread = coeffs_mask_pntrs_[i]->readFromFile(mask_fnames_in[i],true,true);
+     507           0 :           log.printf("  mask for coefficient set %u:\n",i);
+     508           0 :           log.printf("   read %zu values from file %s\n",nread,mask_fnames_in[i].c_str());
+     509           0 :           size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     510           0 :           log.printf("   deactived optimization of %zu coefficients\n",ndeactived);
+     511             :         }
+     512             :       }
+     513             :     }
+     514             : 
+     515             :     std::vector<std::string> mask_fnames_out;
+     516          78 :     parseFilenames("OUTPUT_MASK_FILE",mask_fnames_out);
+     517             : 
+     518          79 :     for(unsigned int i=0; i<mask_fnames_out.size(); i++) {
+     519           1 :       if(mask_fnames_in.size()>0) {
+     520           1 :         plumed_massert(mask_fnames_out[i]!=mask_fnames_in[i],"MASK_FILE and OUTPUT_MASK_FILE cannot be the same");
+     521             :       }
+     522           1 :       OFile maskOFile;
+     523           1 :       maskOFile.link(*this);
+     524           1 :       maskOFile.enforceBackup();
+     525           1 :       if(use_mwalkers_mpi_ && mwalkers_mpi_single_files_) {
+     526           0 :         unsigned int r=0;
+     527           0 :         if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     528           0 :         comm.Bcast(r,0);
+     529           0 :         if(r>0) {mask_fnames_out[i]="/dev/null";}
+     530           0 :         maskOFile.enforceSuffix("");
+     531             :       }
+     532           1 :       maskOFile.open(mask_fnames_out[i]);
+     533           1 :       coeffs_mask_pntrs_[i]->writeToFile(maskOFile,true);
+     534           1 :       maskOFile.close();
+     535           1 :     }
+     536          78 :   }
+     537             : 
+     538          79 :   if(getRestart() && ustride_targetdist_>0) {
+     539          16 :     for(unsigned int i=0; i<nbiases_; i++) {
+     540           8 :       if(dynamic_targetdists_[i]) {
+     541           8 :         bias_pntrs_[i]->restartTargetDistributions();
+     542             :       }
+     543             :     }
+     544             :   }
+     545             : 
+     546             : 
+     547             :   std::vector<std::string> targetdist_averages_fnames;
+     548         158 :   if(keywords.exists("TARGETDIST_AVERAGES_FILE")) {
+     549         158 :     parseFilenames("TARGETDIST_AVERAGES_FILE",targetdist_averages_fnames,"targetdist-averages.data");
+     550         158 :     parse("TARGETDIST_AVERAGES_OUTPUT",targetdist_averages_wstride_);
+     551             : 
+     552          79 :     if(coeffs_fnames.size()>0) {
+     553         164 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     554          85 :         plumed_massert(targetdist_averages_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     555             :       }
+     556             :     }
+     557          79 :     if(gradient_fnames.size()>0) {
+     558         138 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     559          72 :         plumed_massert(targetdist_averages_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     560             :       }
+     561             :     }
+     562          79 :     if(hessian_fnames.size()>0) {
+     563         128 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     564          66 :         plumed_massert(targetdist_averages_fnames[i]!=hessian_fnames[i],"HESSIAN_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     565             :       }
+     566             :     }
+     567          79 :     setupOFiles(targetdist_averages_fnames,targetdist_averagesOFiles_,mw_single_files);
+     568         158 :     parse("TARGETDIST_AVERAGES_FMT",targetdist_averages_output_fmt_);
+     569          79 :     if(targetdist_averages_output_fmt_.size()>0) {
+     570         156 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     571          81 :         targetdist_averages_pntrs_[i]->setOutputFmt(targetdist_averages_output_fmt_);
+     572             :       }
+     573             :     }
+     574             : 
+     575         164 :     for(unsigned int i=0; i<targetdist_averagesOFiles_.size(); i++) {
+     576          85 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     577             :     }
+     578             : 
+     579          79 :     if(targetdist_averages_wstride_==0) {
+     580             :       targetdist_averagesOFiles_.clear();
+     581             :     }
+     582             : 
+     583          79 :     if(targetdist_averages_fnames.size()>0 && targetdist_averages_wstride_ > 0) {
+     584          34 :       if(ncoeffssets_==1) {
+     585          68 :         log.printf("  Target distribution averages will be written out to file %s every %u iterations\n",targetdist_averagesOFiles_[0]->getPath().c_str(),targetdist_averages_wstride_);
+     586             :       }
+     587             :       else {
+     588           0 :         log.printf("  Target distribution averages will be written out to the following files every %u iterations:\n",targetdist_averages_wstride_);
+     589           0 :         for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     590           0 :           log.printf("   coefficient set %u: %s\n",i,targetdist_averagesOFiles_[i]->getPath().c_str());
+     591             :         }
+     592             :       }
+     593             :     }
+     594             :   }
+     595             : 
+     596             : 
+     597         158 :   if(keywords.exists("BIAS_OUTPUT")) {
+     598          79 :     parse("BIAS_OUTPUT",bias_output_stride_);
+     599          79 :     if(bias_output_stride_>0) {
+     600          74 :       bias_output_active_=true;
+     601         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     602          80 :         bias_pntrs_[i]->enableBiasFileOutput();
+     603          80 :         bias_pntrs_[i]->setupBiasFileOutput();
+     604          80 :         bias_pntrs_[i]->writeBiasToFile();
+     605             :       }
+     606             :     }
+     607             :     else {
+     608           5 :       bias_output_active_=false;
+     609           5 :       bias_output_stride_=1000;
+     610             :     }
+     611             :   }
+     612             : 
+     613         158 :   if(keywords.exists("FES_OUTPUT")) {
+     614          79 :     parse("FES_OUTPUT",fes_output_stride_);
+     615          79 :     if(fes_output_stride_>0) {
+     616          74 :       fes_output_active_=true;
+     617         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     618          80 :         bias_pntrs_[i]->enableFesFileOutput();
+     619          80 :         bias_pntrs_[i]->setupFesFileOutput();
+     620          80 :         bias_pntrs_[i]->writeFesToFile();
+     621             :       }
+     622             :     }
+     623             :     else {
+     624           5 :       fes_output_active_=false;
+     625           5 :       fes_output_stride_=1000;
+     626             :     }
+     627             :   }
+     628             : 
+     629         158 :   if(keywords.exists("FES_PROJ_OUTPUT")) {
+     630          79 :     parse("FES_PROJ_OUTPUT",fesproj_output_stride_);
+     631          79 :     if(fesproj_output_stride_>0) {
+     632          16 :       fesproj_output_active_=true;
+     633          32 :       for(unsigned int i=0; i<nbiases_; i++) {
+     634          16 :         bias_pntrs_[i]->enableFesProjFileOutput();
+     635          16 :         bias_pntrs_[i]->setupFesProjFileOutput();
+     636          16 :         bias_pntrs_[i]->writeFesProjToFile();
+     637             :       }
+     638             :     }
+     639             :     else {
+     640          63 :       fesproj_output_active_=false;
+     641          63 :       fesproj_output_stride_=1000;
+     642             :     }
+     643             :   }
+     644             : 
+     645         164 :   for(unsigned int i=0; i<nbiases_; i++) {
+     646          85 :     if(!dynamic_targetdists_[i] && bias_pntrs_[i]->isStaticTargetDistFileOutputActive()) {
+     647           4 :       bias_pntrs_[i]->setupTargetDistFileOutput();
+     648           4 :       bias_pntrs_[i]->writeTargetDistToFile();
+     649           4 :       bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     650           4 :       bias_pntrs_[i]->writeTargetDistProjToFile();
+     651             :     }
+     652             :   }
+     653             : 
+     654         158 :   if(keywords.exists("TARGETDIST_OUTPUT")) {
+     655          78 :     parse("TARGETDIST_OUTPUT",targetdist_output_stride_);
+     656          78 :     if(targetdist_output_stride_>0) {
+     657          37 :       if(ustride_targetdist_==0) {
+     658           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     659             :       }
+     660          37 :       if(targetdist_output_stride_%ustride_targetdist_!=0) {
+     661           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     662             :       }
+     663          37 :       if(targetdist_output_stride_%coeffs_wstride_!=0) {
+     664           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of COEFFS_OUTPUT");
+     665             :       }
+     666             : 
+     667          37 :       targetdist_output_active_=true;
+     668          74 :       for(unsigned int i=0; i<nbiases_; i++) {
+     669          37 :         if(dynamic_targetdists_[i]) {
+     670          37 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     671          37 :           bias_pntrs_[i]->setupTargetDistFileOutput();
+     672          37 :           bias_pntrs_[i]->writeTargetDistToFile();
+     673             :         }
+     674             :       }
+     675             :     }
+     676             :     else {
+     677          41 :       targetdist_output_active_=false;
+     678          41 :       targetdist_output_stride_=1000;
+     679             :     }
+     680             :   }
+     681             : 
+     682         158 :   if(keywords.exists("TARGETDIST_PROJ_OUTPUT")) {
+     683          78 :     parse("TARGETDIST_PROJ_OUTPUT",targetdist_proj_output_stride_);
+     684          78 :     if(targetdist_proj_output_stride_>0) {
+     685           3 :       if(ustride_targetdist_==0) {
+     686           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_PROJ_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     687             :       }
+     688           3 :       if(targetdist_proj_output_stride_%ustride_targetdist_!=0) {
+     689           0 :         plumed_merror("the value given in TARGETDIST_PROJ_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     690             :       }
+     691             : 
+     692           3 :       targetdist_proj_output_active_=true;
+     693           6 :       for(unsigned int i=0; i<nbiases_; i++) {
+     694           3 :         if(dynamic_targetdists_[i]) {
+     695           3 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     696           3 :           bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     697           3 :           bias_pntrs_[i]->writeTargetDistProjToFile();
+     698             :         }
+     699             :       }
+     700             :     }
+     701             :     else {
+     702          75 :       targetdist_proj_output_active_=false;
+     703          75 :       targetdist_proj_output_stride_=1000;
+     704             :     }
+     705             :   }
+     706             : 
+     707          79 :   if(ncoeffssets_==1) {
+     708          76 :     log.printf("  Output Components:\n");
+     709          76 :     log.printf(" ");
+     710          76 :     if(monitor_instantaneous_gradient_) {
+     711           6 :       addComponent("gradrms"); componentIsNotPeriodic("gradrms");
+     712           3 :       log.printf(" ");
+     713           9 :       addComponent("gradmax"); componentIsNotPeriodic("gradmax");
+     714             :     }
+     715          76 :     if(aver_gradient_pntrs_.size()>0) {
+     716           2 :       log.printf(" ");
+     717           4 :       addComponent("avergradrms"); componentIsNotPeriodic("avergradrms");
+     718           2 :       log.printf(" ");
+     719           6 :       addComponent("avergradmax"); componentIsNotPeriodic("avergradmax");
+     720             :     }
+     721          76 :     if(!fixed_stepsize_) {
+     722           1 :       log.printf(" ");
+     723           2 :       addComponent("stepsize"); componentIsNotPeriodic("stepsize");
+     724           2 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+     725             :     }
+     726             :   }
+     727             :   else {
+     728          12 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     729           9 :       log.printf("  Output Components for coefficient set %u:\n",i);
+     730          18 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+     731           9 :       log.printf(" ");
+     732           9 :       if(monitor_instantaneous_gradient_) {
+     733           6 :         addComponent("gradrms"+is); componentIsNotPeriodic("gradrms"+is);
+     734           3 :         log.printf(" ");
+     735           9 :         addComponent("gradmax"+is); componentIsNotPeriodic("gradmax"+is);
+     736             :       }
+     737           9 :       if(aver_gradient_pntrs_.size()>0) {
+     738           0 :         log.printf(" ");
+     739           0 :         addComponent("avergradrms"+is); componentIsNotPeriodic("avergradrms"+is);
+     740           0 :         log.printf(" ");
+     741           0 :         addComponent("avergradmax"+is); componentIsNotPeriodic("avergradmax"+is);
+     742             :       }
+     743           9 :       if(!fixed_stepsize_) {
+     744           0 :         log.printf(" ");
+     745           0 :         addComponent("stepsize"+is); componentIsNotPeriodic("stepsize"+is);
+     746           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+     747             :       }
+     748             :     }
+     749             :   }
+     750             : 
+     751         158 : }
+     752             : 
+     753             : 
+     754          79 : Optimizer::~Optimizer() {
+     755             :   //
+     756         164 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+     757          85 :     if(coeffsOFiles_.size()>0 && getIterationCounter()%coeffs_wstride_!=0) {
+     758           2 :       coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     759             :     }
+     760          85 :     if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_!=0) {
+     761           1 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     762             :     }
+     763             :   }
+     764             :   //
+     765          79 :   if(!isTargetDistOutputActive()) {
+     766          90 :     for(unsigned int i=0; i<nbiases_; i++) {
+     767          48 :       if(dynamic_targetdists_[i]) {
+     768           1 :         bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     769           1 :         bias_pntrs_[i]->setupTargetDistFileOutput();
+     770           1 :         bias_pntrs_[i]->writeTargetDistToFile();
+     771             :       }
+     772             :     }
+     773             :   }
+     774             :   //
+     775          79 :   if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()!=0) {
+     776           1 :     writeBiasOutputFiles();
+     777             :   }
+     778          79 :   if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()!=0) {
+     779           1 :     writeFesOutputFiles();
+     780             :   }
+     781          79 :   if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()!=0) {
+     782           1 :     writeFesProjOutputFiles();
+     783             :   }
+     784          79 :   if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()!=0) {
+     785           2 :     writeTargetDistOutputFiles();
+     786             :   }
+     787          79 :   if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()!=0) {
+     788           1 :     writeTargetDistProjOutputFiles();
+     789             :   }
+     790         395 : }
+     791             : 
+     792             : 
+     793          87 : void Optimizer::registerKeywords( Keywords& keys ) {
+     794          87 :   Action::registerKeywords(keys);
+     795          87 :   ActionPilot::registerKeywords(keys);
+     796          87 :   ActionWithValue::registerKeywords(keys);
+     797             :   //
+     798          87 :   keys.remove("NUMERICAL_DERIVATIVES");
+     799             :   // Default always active keywords
+     800         174 :   keys.add("compulsory","BIAS","the label of the VES bias to be optimized");
+     801         174 :   keys.add("compulsory","STRIDE","the frequency of updating the coefficients given in the number of MD steps.");
+     802         174 :   keys.add("compulsory","COEFFS_FILE","coeffs.data","the name of output file for the coefficients");
+     803         174 :   keys.add("compulsory","COEFFS_OUTPUT","100","how often the coefficients should be written to file. This parameter is given as the number of iterations.");
+     804         174 :   keys.add("optional","COEFFS_FMT","specify format for coefficient file(s) (useful for decrease the number of digits in regtests)");
+     805         174 :   keys.add("optional","COEFFS_SET_ID_PREFIX","suffix to add to the filename given in FILE to identify the bias, should only be given if a single filename is given in FILE when optimizing multiple biases.");
+     806             :   //
+     807         174 :   keys.add("optional","INITIAL_COEFFS","the name(s) of file(s) with the initial coefficients");
+     808             :   // Hidden keywords to output the gradient to a file.
+     809         174 :   keys.add("hidden","GRADIENT_FILE","the name of output file for the gradient");
+     810         174 :   keys.add("hidden","GRADIENT_OUTPUT","how often the gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if GRADIENT_FILE is specficed");
+     811         174 :   keys.add("hidden","GRADIENT_FMT","specify format for gradient file(s) (useful for decrease the number of digits in regtests)");
+     812             :   // Either use a fixed stepsize (useFixedStepSizeKeywords) or changing stepsize (useDynamicsStepSizeKeywords)
+     813         174 :   keys.reserve("compulsory","STEPSIZE","the step size used for the optimization");
+     814         174 :   keys.reserve("compulsory","INITIAL_STEPSIZE","the initial step size used for the optimization");
+     815             :   // Keywords related to the Hessian, actived with the useHessianKeywords function
+     816         174 :   keys.reserveFlag("FULL_HESSIAN",false,"if the full Hessian matrix should be used for the optimization, otherwise only the diagonal part of the Hessian is used");
+     817         174 :   keys.reserve("hidden","HESSIAN_FILE","the name of output file for the Hessian");
+     818         174 :   keys.reserve("hidden","HESSIAN_OUTPUT","how often the Hessian should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if HESSIAN_FILE is specficed");
+     819         174 :   keys.reserve("hidden","HESSIAN_FMT","specify format for hessian file(s) (useful for decrease the number of digits in regtests)");
+     820             :   // Keywords related to the multiple walkers, actived with the useMultipleWalkersKeywords function
+     821         174 :   keys.reserveFlag("MULTIPLE_WALKERS",false,"if optimization is to be performed using multiple walkers connected via MPI");
+     822             :   // Keywords related to the mask file, actived with the useMaskKeywords function
+     823         174 :   keys.reserve("optional","MASK_FILE","read in a mask file which allows one to employ different step sizes for different coefficients and/or deactivate the optimization of certain coefficients (by putting values of 0.0). One can write out the resulting mask by using the OUTPUT_MASK_FILE keyword.");
+     824         174 :   keys.reserve("optional","OUTPUT_MASK_FILE","Name of the file to write out the mask resulting from using the MASK_FILE keyword. Can also be used to generate a template mask file.");
+     825             :   //
+     826         174 :   keys.reserveFlag("START_OPTIMIZATION_AFRESH",false,"if the iterations should be started afresh when a restart has been triggered by the RESTART keyword or the MD code.");
+     827             :   //
+     828         174 :   keys.addFlag("MONITOR_INSTANTANEOUS_GRADIENT",false,"if quantities related to the instantaneous gradient should be outputted.");
+     829             :   //
+     830         174 :   keys.reserveFlag("MONITOR_AVERAGE_GRADIENT",false,"if the averaged gradient should be monitored and quantities related to it should be outputted.");
+     831         174 :   keys.reserve("optional","MONITOR_AVERAGES_GRADIENT_EXP_DECAY","use an exponentially decaying averaging with a given time constant when monitoring the averaged gradient");
+     832             :   //
+     833         174 :   keys.reserve("optional","TARGETDIST_STRIDE","stride for updating a target distribution that is iteratively updated during the optimization. Note that the value is given in terms of coefficient iterations.");
+     834         174 :   keys.reserve("optional","TARGETDIST_OUTPUT","how often the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     835         174 :   keys.reserve("optional","TARGETDIST_PROJ_OUTPUT","how often the projections of the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     836             :   //
+     837         174 :   keys.add("optional","TARGETDIST_AVERAGES_FILE","the name of output file for the target distribution averages. By default it is targetdist-averages.data.");
+     838         174 :   keys.add("optional","TARGETDIST_AVERAGES_OUTPUT","how often the target distribution averages should be written out to file. Note that the value is given in terms of coefficient iterations. If no value is given are the averages only written at the beginning of the optimization");
+     839         174 :   keys.add("hidden","TARGETDIST_AVERAGES_FMT","specify format for target distribution averages file(s) (useful for decrease the number of digits in regtests)");
+     840             :   //
+     841         174 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     842         174 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     843         174 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     844             :   //
+     845         174 :   keys.reserve("optional","REWEIGHT_FACTOR_STRIDE","stride for updating the reweighting factor c(t). Note that the value is given in terms of coefficient iterations.");
+     846             :   //
+     847          87 :   keys.use("RESTART");
+     848             :   //
+     849          87 :   keys.use("UPDATE_FROM");
+     850          87 :   keys.use("UPDATE_UNTIL");
+     851             :   // Components that are always active
+     852         174 :   keys.addOutputComponent("gradrms","MONITOR_INSTANTANEOUS_GRADIENT","the root mean square value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     853         174 :   keys.addOutputComponent("gradmax","MONITOR_INSTANTANEOUS_GRADIENT","the largest absolute value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     854             :   // keys.addOutputComponent("gradmaxidx","default","the index of the maximum absolute value of the gradient");
+     855             : 
+     856          87 : }
+     857             : 
+     858             : 
+     859          80 : void Optimizer::useHessianKeywords(Keywords& keys) {
+     860             :   // keys.use("FULL_HESSIAN");
+     861          80 :   keys.use("HESSIAN_FILE");
+     862          80 :   keys.use("HESSIAN_OUTPUT");
+     863          80 :   keys.use("HESSIAN_FMT");
+     864          80 : }
+     865             : 
+     866             : 
+     867          87 : void Optimizer::useMultipleWalkersKeywords(Keywords& keys) {
+     868          87 :   keys.use("MULTIPLE_WALKERS");
+     869          87 : }
+     870             : 
+     871             : 
+     872          81 : void Optimizer::useFixedStepSizeKeywords(Keywords& keys) {
+     873          81 :   keys.use("STEPSIZE");
+     874          81 : }
+     875             : 
+     876             : 
+     877           3 : void Optimizer::useDynamicStepSizeKeywords(Keywords& keys) {
+     878           3 :   keys.use("INITIAL_STEPSIZE");
+     879           6 :   keys.addOutputComponent("stepsize","default","the current value of step size used to update the coefficients. For multiple biases this component is labeled using the number of the bias as stepsize-#.");
+     880           3 : }
+     881             : 
+     882             : 
+     883          84 : void Optimizer::useMaskKeywords(Keywords& keys) {
+     884          84 :   keys.use("MASK_FILE");
+     885          84 :   keys.use("OUTPUT_MASK_FILE");
+     886          84 : }
+     887             : 
+     888             : 
+     889          80 : void Optimizer::useRestartKeywords(Keywords& keys) {
+     890          80 :   keys.use("START_OPTIMIZATION_AFRESH");
+     891          80 : }
+     892             : 
+     893             : 
+     894          80 : void Optimizer::useMonitorAverageGradientKeywords(Keywords& keys) {
+     895          80 :   keys.use("MONITOR_AVERAGE_GRADIENT");
+     896          80 :   keys.use("MONITOR_AVERAGES_GRADIENT_EXP_DECAY");
+     897         160 :   keys.addOutputComponent("avergradrms","MONITOR_AVERAGE_GRADIENT","the root mean square value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     898         160 :   keys.addOutputComponent("avergradmax","MONITOR_AVERAGE_GRADIENT","the largest absolute value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     899          80 : }
+     900             : 
+     901             : 
+     902          84 : void Optimizer::useDynamicTargetDistributionKeywords(Keywords& keys) {
+     903          84 :   keys.use("TARGETDIST_STRIDE");
+     904          84 :   keys.use("TARGETDIST_OUTPUT");
+     905          84 :   keys.use("TARGETDIST_PROJ_OUTPUT");
+     906          84 : }
+     907             : 
+     908             : 
+     909           0 : void Optimizer::useReweightFactorKeywords(Keywords& keys) {
+     910           0 :   keys.use("REWEIGHT_FACTOR_STRIDE");
+     911           0 : }
+     912             : 
+     913             : 
+     914          76 : void Optimizer::turnOnHessian() {
+     915          76 :   plumed_massert(hessian_pntrs_.size()==0,"turnOnHessian() should only be run during initialization");
+     916          76 :   use_hessian_=true;
+     917          76 :   hessian_pntrs_.clear();
+     918         158 :   for(unsigned int i=0; i<nbiases_; i++) {
+     919          82 :     std::vector<CoeffsMatrix*> pntrs_hessian = enableHessian(bias_pntrs_[i],diagonal_hessian_);
+     920         164 :     for(unsigned int k=0; k<pntrs_hessian.size(); k++) {
+     921          82 :       pntrs_hessian[k]->turnOnIterationCounter();
+     922          82 :       pntrs_hessian[k]->setIterationCounterAndTime(getIterationCounter(),getTime());
+     923          82 :       hessian_pntrs_.push_back(pntrs_hessian[k]);
+     924             :     }
+     925             :   }
+     926          76 :   plumed_massert(hessian_pntrs_.size()==ncoeffssets_,"problems in linking Hessians");
+     927          76 :   if(diagonal_hessian_) {
+     928          76 :     log.printf("  Optimization performed using diagonal Hessian matrix\n");
+     929             :   }
+     930             :   else {
+     931           0 :     log.printf("  Optimization performed using full Hessian matrix\n");
+     932             :   }
+     933             :   //
+     934          76 :   if(hessian_output_fmt_.size()>0) {
+     935         128 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     936          66 :       hessian_pntrs_[i]->setOutputFmt(hessian_output_fmt_);
+     937             :     }
+     938             :   }
+     939             : 
+     940          76 : }
+     941             : 
+     942             : 
+     943           0 : void Optimizer::turnOffHessian() {
+     944           0 :   use_hessian_=false;
+     945           0 :   for(unsigned int i=0; i<nbiases_; i++) {
+     946           0 :     bias_pntrs_[i]->disableHessian();
+     947             :   }
+     948             :   hessian_pntrs_.clear();
+     949           0 :   hessianOFiles_.clear();
+     950           0 : }
+     951             : 
+     952             : 
+     953          82 : std::vector<CoeffsMatrix*> Optimizer::enableHessian(VesBias* bias_pntr_in, const bool diagonal_hessian) {
+     954          82 :   plumed_massert(use_hessian_,"the Hessian should not be used");
+     955          82 :   bias_pntr_in->enableHessian(diagonal_hessian);
+     956             :   std::vector<CoeffsMatrix*> hessian_pntrs_out = bias_pntr_in->getHessianPntrs();
+     957         164 :   for(unsigned int k=0; k<hessian_pntrs_out.size(); k++) {
+     958          82 :     plumed_massert(hessian_pntrs_out[k] != NULL,"Hessian is needed but not linked correctly");
+     959             :   }
+     960          82 :   return hessian_pntrs_out;
+     961             : }
+     962             : 
+     963             : 
+     964             : // CoeffsMatrix* Optimizer::switchToDiagonalHessian(VesBias* bias_pntr_in) {
+     965             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     966             : //   diagonal_hessian_=true;
+     967             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     968             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     969             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     970             : //   //
+     971             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     972             : //   return hessian_pntr_out;
+     973             : // }
+     974             : 
+     975             : 
+     976             : // CoeffsMatrix* Optimizer::switchToFullHessian(VesBias* bias_pntr_in) {
+     977             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     978             : //   diagonal_hessian_=false;
+     979             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     980             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     981             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     982             : //   //
+     983             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     984             : //   return hessian_pntr_out;
+     985             : // }
+     986             : 
+     987             : 
+     988       22879 : void Optimizer::update() {
+     989       22879 :   if(onStep() && !isFirstStep) {
+     990       45560 :     for(unsigned int i=0; i<nbiases_; i++) {
+     991       22810 :       bias_pntrs_[i]->updateGradientAndHessian(use_mwalkers_mpi_);
+     992             :     }
+     993       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     994       22810 :       if(gradient_pntrs_[i]->isActive()) {coeffsUpdate(i);}
+     995             :       else {
+     996         190 :         std::string msg = "iteration " + getIterationCounterStr(+1) +
+     997         285 :                           " for " + bias_pntrs_[i]->getLabel() +
+     998          95 :                           " - the coefficients are not updated as CV values are outside the bias intervals";
+     999          95 :         warning(msg);
+    1000             :       }
+    1001             : 
+    1002             :       // +1 as this is done before increaseIterationCounter() is used
+    1003       22810 :       unsigned int curr_iter = getIterationCounter()+1;
+    1004       22810 :       double curr_time = getTime();
+    1005       22810 :       coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1006             :       aux_coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1007       22810 :       gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1008       22810 :       targetdist_averages_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1009       22810 :       if(use_hessian_) {
+    1010       22780 :         hessian_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1011             :       }
+    1012       22810 :       if(aver_gradient_pntrs_.size()>0) {
+    1013             :         aver_gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1014          20 :         aver_gradient_pntrs_[i]->addToAverage(*gradient_pntrs_[i]);
+    1015             :       }
+    1016             :     }
+    1017             :     increaseIterationCounter();
+    1018             : 
+    1019       22750 :     if(ustride_targetdist_>0 && getIterationCounter()%ustride_targetdist_==0) {
+    1020         708 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1021         354 :         if(dynamic_targetdists_[i]) {
+    1022         354 :           bias_pntrs_[i]->updateTargetDistributions();
+    1023             :         }
+    1024             :       }
+    1025             :     }
+    1026       22750 :     if(ustride_reweightfactor_>0 && getIterationCounter()%ustride_reweightfactor_==0) {
+    1027           0 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1028           0 :         bias_pntrs_[i]->updateReweightFactor();
+    1029             :       }
+    1030             :     }
+    1031             : 
+    1032       22750 :     updateOutputComponents();
+    1033       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1034       22810 :       writeOutputFiles(i);
+    1035             :     }
+    1036             :     //
+    1037       22750 :     if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()==0) {
+    1038          74 :       writeBiasOutputFiles();
+    1039             :     }
+    1040       22750 :     if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()==0) {
+    1041          74 :       writeFesOutputFiles();
+    1042             :     }
+    1043       22750 :     if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()==0) {
+    1044          16 :       writeFesProjOutputFiles();
+    1045             :     }
+    1046       22750 :     if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()==0) {
+    1047          36 :       writeTargetDistOutputFiles();
+    1048             :     }
+    1049       22750 :     if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()==0) {
+    1050           3 :       writeTargetDistProjOutputFiles();
+    1051             :     }
+    1052             :   }
+    1053             :   else {
+    1054         129 :     isFirstStep=false;
+    1055             :   }
+    1056       22879 : }
+    1057             : 
+    1058             : 
+    1059       22750 : void Optimizer::updateOutputComponents() {
+    1060       22750 :   if(ncoeffssets_==1) {
+    1061       22720 :     if(!fixed_stepsize_) {
+    1062          20 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+    1063             :     }
+    1064       22720 :     if(monitor_instantaneous_gradient_) {
+    1065          30 :       getPntrToComponent("gradrms")->set( gradient_pntrs_[0]->getRMS() );
+    1066          30 :       size_t gradient_maxabs_idx=0;
+    1067          60 :       getPntrToComponent("gradmax")->set( gradient_pntrs_[0]->getMaxAbsValue(gradient_maxabs_idx) );
+    1068             :     }
+    1069       22720 :     if(aver_gradient_pntrs_.size()>0) {
+    1070          20 :       getPntrToComponent("avergradrms")->set( aver_gradient_pntrs_[0]->getRMS() );
+    1071          20 :       size_t avergradient_maxabs_idx=0;
+    1072          40 :       getPntrToComponent("avergradmax")->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1073             :     }
+    1074             :   }
+    1075             :   else {
+    1076         120 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1077         180 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+    1078          90 :       if(!fixed_stepsize_) {
+    1079           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+    1080             :       }
+    1081          90 :       if(monitor_instantaneous_gradient_) {
+    1082          30 :         getPntrToComponent("gradrms"+is)->set( gradient_pntrs_[i]->getRMS() );
+    1083          30 :         size_t gradient_maxabs_idx=0;
+    1084          60 :         getPntrToComponent("gradmax"+is)->set( gradient_pntrs_[i]->getMaxAbsValue(gradient_maxabs_idx) );
+    1085             :       }
+    1086          90 :       if(aver_gradient_pntrs_.size()>0) {
+    1087           0 :         getPntrToComponent("avergradrms"+is)->set( aver_gradient_pntrs_[0]->getRMS() );
+    1088           0 :         size_t avergradient_maxabs_idx=0;
+    1089           0 :         getPntrToComponent("avergradmax"+is)->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1090             :       }
+    1091             :     }
+    1092             :   }
+    1093       22750 : }
+    1094             : 
+    1095             : 
+    1096           1 : void Optimizer::turnOffCoeffsOutputFiles() {
+    1097           1 :   coeffsOFiles_.clear();
+    1098           1 : }
+    1099             : 
+    1100             : 
+    1101       22810 : void Optimizer::writeOutputFiles(const unsigned int coeffs_id) {
+    1102       22810 :   if(coeffsOFiles_.size()>0 && iter_counter%coeffs_wstride_==0) {
+    1103         789 :     coeffs_pntrs_[coeffs_id]->writeToFile(*coeffsOFiles_[coeffs_id],aux_coeffs_pntrs_[coeffs_id].get(),false);
+    1104             :   }
+    1105       22810 :   if(gradientOFiles_.size()>0 && iter_counter%gradient_wstride_==0) {
+    1106         720 :     if(aver_gradient_pntrs_.size()==0) {
+    1107         700 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],false);
+    1108             :     }
+    1109             :     else {
+    1110          20 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],aver_gradient_pntrs_[coeffs_id].get(),false);
+    1111             :     }
+    1112             :   }
+    1113       22810 :   if(hessianOFiles_.size()>0 && iter_counter%hessian_wstride_==0) {
+    1114         660 :     hessian_pntrs_[coeffs_id]->writeToFile(*hessianOFiles_[coeffs_id]);
+    1115             :   }
+    1116       22810 :   if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_==0) {
+    1117         333 :     targetdist_averages_pntrs_[coeffs_id]->writeToFile(*targetdist_averagesOFiles_[coeffs_id]);
+    1118             :   }
+    1119       22810 : }
+    1120             : 
+    1121             : 
+    1122         388 : void Optimizer::setupOFiles(std::vector<std::string>& fnames, std::vector<std::unique_ptr<OFile>>& OFiles, const bool multi_sim_single_files) {
+    1123         388 :   plumed_assert(ncoeffssets_>0);
+    1124         388 :   OFiles.resize(fnames.size());
+    1125         702 :   for(unsigned int i=0; i<fnames.size(); i++) {
+    1126         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.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func-sort-c.html b/coverage/ves/Optimizer.h.func-sort-c.html new file mode 100644 index 0000000000..c40a560535 --- /dev/null +++ b/coverage/ves/Optimizer.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func.html b/coverage/ves/Optimizer.h.func.html new file mode 100644 index 0000000000..e9c814292a --- /dev/null +++ b/coverage/ves/Optimizer.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.gcov.html b/coverage/ves/Optimizer.h.gcov.html new file mode 100644 index 0000000000..0d691389cb --- /dev/null +++ b/coverage/ves/Optimizer.h.gcov.html @@ -0,0 +1,430 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html new file mode 100644 index 0000000000..28d692936a --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe966createERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func.html b/coverage/ves/OutputBasisFunctions.cpp.func.html new file mode 100644 index 0000000000..859d4588fc --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe966createERKNS_13ActionOptionsE71
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_132OutputBasisFunctionsRegisterMe96D2Ev4168
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.gcov.html b/coverage/ves/OutputBasisFunctions.cpp.gcov.html new file mode 100644 index 0000000000..e21c8023a3 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + 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-05-27 13:05: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       12575 : PLUMED_REGISTER_ACTION(OutputBasisFunctions,"VES_OUTPUT_BASISFUNCTIONS")
+      97             : 
+      98          73 : void OutputBasisFunctions::registerKeywords(Keywords& keys) {
+      99          73 :   Action::registerKeywords(keys);
+     100         146 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the basis functions that you want to use");
+     101         146 :   keys.add("optional","GRID_BINS","the number of bins used for the grid for writing the basis function values and derivatives. The default value is 1000.");
+     102         146 :   keys.add("optional","GRID_MIN","the minimum of the grid for writing the basis function values and derivatives. By default it is the minimum of the interval on which the basis functions are defined.");
+     103         146 :   keys.add("optional","GRID_MAX","the maximum of the grid for writing the basis function values and derivatives. By default it is the maximum of the interval on which the basis functions are defined.");
+     104         146 :   keys.add("optional","FILE_VALUES","filename of the file on which the basis function values are written. By default it is BF_LABEL.values.data.");
+     105         146 :   keys.add("optional","FILE_DERIVS","filename of the file on which the basis function derivatives are written. By default it is BF_LABEL.derivs.data.");
+     106         146 :   keys.add("optional","FORMAT_VALUES_DERIVS","the numerical format of the basis function values and derivatives written to file. By default it is %15.8f.\n. You can also use FORMAT_VALUES and FORMAT_DERIVS to give the numerical formats separately.");
+     107         146 :   keys.add("optional","FORMAT_VALUES","the numerical format of the basis function derivatives written to file. By default it is %15.8f.\n");
+     108         146 :   keys.add("optional","FORMAT_DERIVS","the numerical format of the basis function values written to file. By default it is %15.8f.\n");
+     109         146 :   keys.add("optional","FILE_TARGETDIST_AVERAGES","filename of the file on which the averages over the target distributions are written. By default it is BF_LABEL.targetdist-averages.data.");
+     110         146 :   keys.add("optional","FORMAT_TARGETDIST_AVERAGES","the numerical format of the target distribution averages written to file. By default it is %15.8f.\n");
+     111         146 :   keys.add("optional","FILE_TARGETDIST","filename of the files on which the target distributions are written. By default it is BF_LABEL.targetdist-#.data.");
+     112         146 :   keys.add("numbered","TARGET_DISTRIBUTION","the target distribution to be used.");
+     113         146 :   keys.addFlag("IGNORE_PERIODICITY",false,"if the periodicity of the basis functions should be ignored.");
+     114         146 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"if the derivatives of the basis functions should be calculated numerically.");
+     115          73 : }
+     116             : 
+     117          71 : OutputBasisFunctions::OutputBasisFunctions(const ActionOptions&ao):
+     118             :   Action(ao),
+     119          71 :   bf_pntrs(0)
+     120             : {
+     121          71 :   std::vector<std::string> basisset_labels(0);
+     122         142 :   parseVector("BASIS_FUNCTIONS",basisset_labels);
+     123          71 :   if(basisset_labels.size()>1) {plumed_merror("Only one basis set label allowed in keyword BASIS_FUNCTIONS of "+getName());}
+     124             : 
+     125          71 :   std::string error_msg = "";
+     126         142 :   bf_pntrs = VesTools::getPointersFromLabels<BasisFunctions*>(basisset_labels,plumed.getActionSet(),error_msg);
+     127          71 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     128             : 
+     129          71 :   unsigned int nbins = 1000;
+     130         142 :   parse("GRID_BINS",nbins);
+     131             : 
+     132          71 :   std::string min_str = bf_pntrs[0]->intervalMinStr();
+     133          71 :   std::string max_str = bf_pntrs[0]->intervalMaxStr();
+     134          71 :   parse("GRID_MIN",min_str);
+     135         142 :   parse("GRID_MAX",max_str);
+     136             : 
+     137          71 :   std::string fname_values = bf_pntrs[0]->getLabel()+".values.data";
+     138         142 :   parse("FILE_VALUES",fname_values);
+     139          71 :   std::string fname_derives = bf_pntrs[0]->getLabel()+".derivs.data";
+     140         142 :   parse("FILE_DERIVS",fname_derives);
+     141          71 :   std::string fname_targetdist_aver = bf_pntrs[0]->getLabel()+".targetdist-averages.data";
+     142         142 :   parse("FILE_TARGETDIST_AVERAGES",fname_targetdist_aver);
+     143          71 :   std::string fname_targetdist = bf_pntrs[0]->getLabel()+".targetdist-.data";
+     144          71 :   parse("FILE_TARGETDIST",fname_targetdist);
+     145             : 
+     146          71 :   std::string fmt_values_derivs = "%15.8f";
+     147          71 :   parse("FORMAT_VALUES_DERIVS",fmt_values_derivs);
+     148          71 :   std::string fmt_values = fmt_values_derivs;
+     149          71 :   std::string fmt_derivs = fmt_values_derivs;
+     150          71 :   parse("FORMAT_VALUES",fmt_values);
+     151          71 :   parse("FORMAT_DERIVS",fmt_derivs);
+     152             : 
+     153          71 :   std::string fmt_targetdist_aver = "%15.8f";
+     154          71 :   parse("FORMAT_TARGETDIST_AVERAGES",fmt_targetdist_aver);
+     155             : 
+     156          71 :   bool ignore_periodicity = false;
+     157          71 :   parseFlag("IGNORE_PERIODICITY",ignore_periodicity);
+     158             : 
+     159          71 :   bool numerical_deriv = false;
+     160         142 :   parseFlag("NUMERICAL_DERIVATIVES",numerical_deriv);
+     161             : 
+     162             :   std::vector<TargetDistribution*> targetdist_pntrs;
+     163          71 :   targetdist_pntrs.push_back(NULL);
+     164          71 :   std::string targetdist_label="";
+     165         176 :   for(int i=1;; i++) {
+     166         494 :     if(!parseNumbered("TARGET_DISTRIBUTION",i,targetdist_label)) {break;}
+     167         176 :     std::string error_msg = "";
+     168         176 :     TargetDistribution* pntr_tmp = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     169         176 :     if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     170         176 :     targetdist_pntrs.push_back(pntr_tmp);
+     171         176 :   }
+     172          71 :   checkRead();
+     173             :   //
+     174          71 :   OFile ofile_values;
+     175          71 :   ofile_values.link(*this);
+     176          71 :   ofile_values.enforceBackup();
+     177          71 :   ofile_values.open(fname_values);
+     178          71 :   OFile ofile_derivs;
+     179          71 :   ofile_derivs.link(*this);
+     180          71 :   ofile_derivs.enforceBackup();
+     181          71 :   ofile_derivs.open(fname_derives);
+     182          71 :   bf_pntrs[0]->writeBasisFunctionsToFile(ofile_values,ofile_derivs,min_str,max_str,nbins,ignore_periodicity,fmt_values,fmt_derivs,numerical_deriv);
+     183          71 :   ofile_values.close();
+     184          71 :   ofile_derivs.close();
+     185             :   //
+     186          71 :   std::vector<std::string> grid_min(1); grid_min[0]=bf_pntrs[0]->intervalMinStr();
+     187          71 :   std::vector<std::string> grid_max(1); grid_max[0]=bf_pntrs[0]->intervalMaxStr();
+     188          71 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins;
+     189          71 :   std::vector<std::unique_ptr<Value>> arguments(1);
+     190         142 :   arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     191          71 :   if(bf_pntrs[0]->arePeriodic() && !ignore_periodicity) {
+     192          46 :     arguments[0]->setDomain(bf_pntrs[0]->intervalMinStr(),bf_pntrs[0]->intervalMaxStr());
+     193             :   }
+     194             :   else {
+     195          48 :     arguments[0]->setNotPeriodic();
+     196             :   }
+     197             : 
+     198          71 :   OFile ofile_targetdist_aver;
+     199          71 :   ofile_targetdist_aver.link(*this);
+     200          71 :   ofile_targetdist_aver.enforceBackup();
+     201          71 :   ofile_targetdist_aver.open(fname_targetdist_aver);
+     202             : 
+     203         318 :   for(unsigned int i=0; i<targetdist_pntrs.size(); i++) {
+     204         247 :     std::string is; Tools::convert(i,is);
+     205             :     //
+     206         247 :     if(targetdist_pntrs[i]!=NULL) {
+     207         352 :       targetdist_pntrs[i]->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     208         176 :       plumed_massert(targetdist_pntrs[i]->getDimension()==1,"the target distribution must be one dimensional");
+     209         176 :       targetdist_pntrs[i]->updateTargetDist();
+     210             :     }
+     211             :     //
+     212         247 :     std::vector<double> bf_integrals = bf_pntrs[0]->getTargetDistributionIntegrals(targetdist_pntrs[i]);
+     213         494 :     CoeffsVector targetdist_averages = CoeffsVector("aver.targetdist-"+is,Tools::unique2raw(arguments),bf_pntrs,comm,false);
+     214         247 :     targetdist_averages.setValues(bf_integrals);
+     215         247 :     if(fmt_targetdist_aver.size()>0) {targetdist_averages.setOutputFmt(fmt_targetdist_aver);}
+     216         247 :     targetdist_averages.writeToFile(ofile_targetdist_aver,true);
+     217         247 :     if(targetdist_pntrs[i]!=NULL) {
+     218             :       Grid* targetdist_grid_pntr = targetdist_pntrs[i]->getTargetDistGridPntr();
+     219         176 :       std::string fname = FileBase::appendSuffix(fname_targetdist,is);
+     220         176 :       OFile ofile;
+     221         176 :       ofile.link(*this);
+     222         176 :       ofile.enforceBackup();
+     223         176 :       ofile.open(fname);
+     224         176 :       targetdist_grid_pntr->writeToFile(ofile);
+     225         176 :       ofile.close();
+     226         176 :     }
+     227         247 :   }
+     228          71 :   ofile_targetdist_aver.close();
+     229             : 
+     230             : 
+     231         213 : }
+     232             : 
+     233             : 
+     234             : 
+     235             : }
+     236             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func-sort-c.html b/coverage/ves/OutputFesBias.cpp.func-sort-c.html new file mode 100644 index 0000000000..2a91ae168d --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE5
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func.html b/coverage/ves/OutputFesBias.cpp.func.html new file mode 100644 index 0000000000..4bf593d2e5 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe1106createERKNS_13ActionOptionsE3
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_126OutputFesBiasRegisterMe110D2Ev4168
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.gcov.html b/coverage/ves/OutputFesBias.cpp.gcov.html new file mode 100644 index 0000000000..6d8390dd2c --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_ACTION(OutputFesBias,"VES_OUTPUT_FES")
+     111             : 
+     112             : 
+     113           5 : void OutputFesBias::registerKeywords(Keywords& keys) {
+     114          10 :   keys.add("compulsory","BIAS","the label of the VES bias for to output the free energy surfaces and the bias files");
+     115          10 :   keys.add("compulsory","COEFFS_INPUT","the name of input coefficient file");
+     116          10 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     117          10 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     118          10 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     119             :   //
+     120           5 : }
+     121             : 
+     122             : 
+     123           3 : OutputFesBias::OutputFesBias(const ActionOptions&ao):
+     124           3 :   Action(ao)
+     125             : {
+     126             : 
+     127             :   std::vector<std::string> bias_labels;
+     128           6 :   parseVector("BIAS",bias_labels);
+     129           3 :   if(bias_labels.size()>1) {
+     130           0 :     plumed_merror(getName()+" only support one VES bias");
+     131             :   }
+     132             : 
+     133           3 :   std::string error_msg = "";
+     134           3 :   std::vector<VesBias*> bias_pntrs = VesTools::getPointersFromLabels<VesBias*>(bias_labels,plumed.getActionSet(),error_msg);
+     135           3 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BIAS of "+getName()+": "+error_msg);}
+     136             : 
+     137           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     138           3 :     if(bias_pntrs[i]->numberOfCoeffsSets()>1) {
+     139           0 :       plumed_merror(getName()+" at the moment supports only VES biases with a single coefficient set");
+     140             :     }
+     141             :   }
+     142             : 
+     143             :   std::vector<std::string> coeffs_fnames;
+     144           6 :   parseVector("COEFFS_INPUT",coeffs_fnames);
+     145           3 :   if(coeffs_fnames.size()!=bias_pntrs.size()) {
+     146           0 :     plumed_merror(getName()+": there have to be as many coefficient file given in COEFFS_INPUT as VES biases given in BIAS");
+     147             :   }
+     148             : 
+     149           3 :   unsigned int bias_output_stride = 0;
+     150           3 :   parse("BIAS_OUTPUT",bias_output_stride);
+     151             : 
+     152           3 :   unsigned int fes_output_stride = 0;
+     153           3 :   parse("FES_OUTPUT",fes_output_stride);
+     154             : 
+     155           3 :   unsigned int fesproj_output_stride = 0;
+     156           3 :   parse("FES_PROJ_OUTPUT",fesproj_output_stride);
+     157             : 
+     158           3 :   if(bias_output_stride == 0 && fes_output_stride == 0 && fesproj_output_stride == 0) {
+     159           0 :     plumed_merror(getName()+": you are not telling the action to do anything, you need to use one of the keywords BIAS_OUTPUT, FES_OUTPUT, or FES_PROJ_OUTPUT");
+     160             :   }
+     161             : 
+     162           3 :   checkRead();
+     163             : 
+     164           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     165             : 
+     166           3 :     if(bias_pntrs[i]->dynamicTargetDistribution()) {
+     167           0 :       plumed_merror(getName()+" does not support dynamic target distributions at the moment");
+     168             :     }
+     169             : 
+     170           3 :     if(bias_pntrs[i]->isStaticTargetDistFileOutputActive()) {
+     171           2 :       bias_pntrs[i]->setupTargetDistFileOutput();
+     172           2 :       bias_pntrs[i]->writeTargetDistToFile();
+     173           2 :       bias_pntrs[i]->setupTargetDistProjFileOutput();
+     174           2 :       bias_pntrs[i]->writeTargetDistProjToFile();
+     175             :     }
+     176             : 
+     177             : 
+     178           3 :     if(bias_output_stride>0) {
+     179           3 :       bias_pntrs[i]->enableBiasFileOutput();
+     180           3 :       bias_pntrs[i]->setupBiasFileOutput();
+     181             :     }
+     182             : 
+     183           3 :     if(fes_output_stride>0) {
+     184           3 :       bias_pntrs[i]->enableFesFileOutput();
+     185           3 :       bias_pntrs[i]->setupFesFileOutput();
+     186             :     }
+     187             : 
+     188           3 :     if(fesproj_output_stride>0) {
+     189           1 :       bias_pntrs[i]->enableFesProjFileOutput();
+     190           1 :       bias_pntrs[i]->setupFesProjFileOutput();
+     191             :     }
+     192             : 
+     193           3 :     bias_pntrs[i]->enableIterationNumberInFilenames();
+     194             : 
+     195           3 :     IFile ifile;
+     196           3 :     ifile.open(coeffs_fnames[i]);
+     197             : 
+     198          39 :     while(ifile) {
+     199             : 
+     200          36 :       bias_pntrs[i]->resetBiasFileOutput();
+     201          36 :       bias_pntrs[i]->resetFesFileOutput();
+     202             : 
+     203          72 :       if(bias_pntrs[i]->getCoeffsPntrs()[0]->readOneSetFromFile(ifile)>0) {
+     204          33 :         unsigned int iteration = bias_pntrs[i]->getCoeffsPntrs()[0]->getIterationCounter();
+     205             : 
+     206          33 :         if(bias_output_stride>0 && iteration%bias_output_stride==0) {
+     207           8 :           bias_pntrs[i]->writeBiasToFile();
+     208             :         }
+     209             : 
+     210          33 :         if(fes_output_stride>0 && iteration%fes_output_stride==0) {
+     211           8 :           bias_pntrs[i]->writeFesToFile();
+     212             :         }
+     213             : 
+     214          33 :         if(fesproj_output_stride>0 && iteration%fesproj_output_stride==0) {
+     215           3 :           bias_pntrs[i]->writeFesProjToFile();
+     216             :         }
+     217             : 
+     218             :       }
+     219             : 
+     220             :     }
+     221             : 
+     222           3 :   }
+     223             : 
+     224           3 :   log.printf("Stopping");
+     225           3 :   plumed.stop();
+     226           6 : }
+     227             : 
+     228             : 
+     229             : }
+     230             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html new file mode 100644 index 0000000000..54e8c82c71 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe926createERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func.html b/coverage/ves/OutputTargetDistribution.cpp.func.html new file mode 100644 index 0000000000..776672c014 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe926createERKNS_13ActionOptionsE120
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_136OutputTargetDistributionRegisterMe92D2Ev4168
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.gcov.html b/coverage/ves/OutputTargetDistribution.cpp.gcov.html new file mode 100644 index 0000000000..921c0d0b82 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + 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-05-27 13:05: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       12624 : PLUMED_REGISTER_ACTION(OutputTargetDistribution,"VES_OUTPUT_TARGET_DISTRIBUTION")
+      93             : 
+      94         122 : void OutputTargetDistribution::registerKeywords(Keywords& keys) {
+      95         122 :   Action::registerKeywords(keys);
+      96         244 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+      97         244 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+      98         244 :   keys.add("compulsory","GRID_BINS","the number of bins used for the grid.");
+      99         244 :   keys.add("optional","GRID_PERIODICITY","specify if the individual arguments should be made periodic (YES) or not (NO). By default all arguments are taken as not periodic.");
+     100         244 :   keys.add("compulsory","TARGETDIST_FILE","filename of the file for writing the target distribution");
+     101         244 :   keys.add("optional","LOG_TARGETDIST_FILE","filename of the file for writing the log of the target distribution");
+     102         244 :   keys.add("compulsory","TARGET_DISTRIBUTION","the target distribution to be used.");
+     103         244 :   keys.add("optional","FMT_GRIDS","the numerical format of the target distribution grids written to file. By default it is %14.9f");
+     104         244 :   keys.addFlag("DO_1D_PROJECTIONS",false,"Also output the one-dimensional marginal distributions for multi-dimensional target distribution.");
+     105         122 : }
+     106             : 
+     107         120 : OutputTargetDistribution::OutputTargetDistribution(const ActionOptions&ao):
+     108         120 :   Action(ao)
+     109             : {
+     110             : 
+     111             :   std::string targetdist_fname;
+     112         240 :   parse("TARGETDIST_FILE",targetdist_fname);
+     113             :   std::string log_targetdist_fname;
+     114         120 :   parse("LOG_TARGETDIST_FILE",log_targetdist_fname);
+     115         120 :   if(targetdist_fname==log_targetdist_fname) {
+     116           0 :     plumed_merror("error in " + getName() + ":TARGETDIST_FILE and LOG_TARGETDIST_FILE cannot be the same");
+     117             :   }
+     118             : 
+     119             :   std::vector<unsigned int> grid_bins;
+     120         240 :   parseVector("GRID_BINS",grid_bins);
+     121         120 :   unsigned int nargs = grid_bins.size();
+     122             : 
+     123         120 :   std::vector<std::string> grid_min(nargs);
+     124         120 :   parseVector("GRID_MIN",grid_min);
+     125         120 :   std::vector<std::string> grid_max(nargs);
+     126         120 :   parseVector("GRID_MAX",grid_max);
+     127             : 
+     128         120 :   std::vector<std::string> grid_periodicity(nargs);
+     129         240 :   parseVector("GRID_PERIODICITY",grid_periodicity);
+     130         232 :   if(grid_periodicity.size()==0) {grid_periodicity.assign(nargs,"NO");}
+     131             : 
+     132         120 :   std::string fmt_grids="%14.9f";
+     133         120 :   parse("FMT_GRIDS",fmt_grids);
+     134             : 
+     135         120 :   bool do_1d_proj = false;
+     136         120 :   parseFlag("DO_1D_PROJECTIONS",do_1d_proj);
+     137         120 :   if(do_1d_proj && nargs==1) {
+     138           0 :     plumed_merror("doesn't make sense to use the DO_1D_PROJECTIONS keyword for a one-dimensional distribution");
+     139             :   }
+     140             : 
+     141         120 :   plumed_massert(grid_min.size()==nargs,"mismatch between number of values given for grid parameters");
+     142         120 :   plumed_massert(grid_max.size()==nargs,"mismatch between number of values given for grid parameters");
+     143         120 :   plumed_massert(grid_periodicity.size()==nargs,"mismatch between number of values given for grid parameters");
+     144             : 
+     145             :   std::string targetdist_label;
+     146         120 :   parse("TARGET_DISTRIBUTION",targetdist_label);
+     147         120 :   checkRead();
+     148             :   //
+     149         120 :   std::vector<std::unique_ptr<Value>> arguments(nargs);
+     150         287 :   for(unsigned int i=0; i < nargs; i++) {
+     151         167 :     std::string is; Tools::convert(i+1,is);
+     152         167 :     if(nargs==1) {is="";}
+     153         167 :     arguments[i]= Tools::make_unique<Value>(nullptr,"arg"+is,false);
+     154         167 :     if(grid_periodicity[i]=="YES") {
+     155          11 :       arguments[i]->setDomain(grid_min[i],grid_max[i]);
+     156             :     }
+     157         156 :     else if(grid_periodicity[i]=="NO") {
+     158         156 :       arguments[i]->setNotPeriodic();
+     159             :     }
+     160             :     else {
+     161           0 :       plumed_merror("wrong value given in GRID_PERIODICITY, either specify YES or NO");
+     162             :     }
+     163             :   }
+     164             : 
+     165         120 :   std::string error_msg = "";
+     166         120 :   TargetDistribution* targetdist_pntr = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     167         120 :   if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     168             :   //
+     169         120 :   if(targetdist_pntr->isDynamic()) {
+     170           0 :     plumed_merror(getName() + " only works for static target distributions");
+     171             :   }
+     172         120 :   targetdist_pntr->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     173         120 :   targetdist_pntr->updateTargetDist();
+     174             :   Grid* targetdist_grid_pntr = targetdist_pntr->getTargetDistGridPntr();
+     175             :   Grid* log_targetdist_grid_pntr = targetdist_pntr->getLogTargetDistGridPntr();
+     176             : 
+     177             : 
+     178         120 :   double sum_grid = TargetDistribution::integrateGrid(targetdist_grid_pntr);
+     179         120 :   log.printf("  target distribution integrated over the grid: %16.12f\n",sum_grid);
+     180         120 :   log.printf("                                                (%30.16e)\n",sum_grid);
+     181             :   //
+     182         120 :   OFile ofile;
+     183         120 :   ofile.link(*this);
+     184         120 :   ofile.enforceBackup();
+     185         120 :   ofile.open(targetdist_fname);
+     186             :   targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     187         120 :   targetdist_grid_pntr->writeToFile(ofile);
+     188         120 :   ofile.close();
+     189         120 :   if(log_targetdist_fname.size()>0) {
+     190          23 :     OFile ofile2;
+     191          23 :     ofile2.link(*this);
+     192          23 :     ofile2.enforceBackup();
+     193          23 :     ofile2.open(log_targetdist_fname);
+     194             :     log_targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     195          23 :     log_targetdist_grid_pntr->writeToFile(ofile2);
+     196          23 :     ofile2.close();
+     197          23 :   }
+     198             : 
+     199         120 :   if(do_1d_proj) {
+     200          12 :     for(unsigned int i=0; i<nargs; i++) {
+     201           8 :       std::vector<std::string> arg1d(1);
+     202           8 :       arg1d[0] = arguments[i]->getName();
+     203           8 :       Grid marginal_grid = targetdist_pntr->getMarginal(arg1d);
+     204             :       //
+     205             :       std::string suffix;
+     206           8 :       Tools::convert(i+1,suffix);
+     207           8 :       suffix = "proj-" + suffix;
+     208           8 :       std::string marginal_fname = FileBase::appendSuffix(targetdist_fname,"."+suffix);
+     209             :       //
+     210           8 :       OFile ofile3;
+     211           8 :       ofile3.link(*this);
+     212           8 :       ofile3.enforceBackup();
+     213           8 :       ofile3.open(marginal_fname);
+     214             :       marginal_grid.setOutputFmt(fmt_grids);
+     215           8 :       marginal_grid.writeToFile(ofile3);
+     216          16 :     }
+     217             :   }
+     218             : 
+     219         480 : }
+     220             : 
+     221             : 
+     222             : 
+     223             : 
+     224             : 
+     225             : }
+     226             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func-sort-c.html b/coverage/ves/TD_Chi.cpp.func-sort-c.html new file mode 100644 index 0000000000..5704372b8b --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func.html b/coverage/ves/TD_Chi.cpp.func.html new file mode 100644 index 0000000000..dec5ec2f81 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_118TD_ChiRegisterMe91D2Ev4168
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.gcov.html b/coverage/ves/TD_Chi.cpp.gcov.html new file mode 100644 index 0000000000..c774defc1e --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + 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-05-27 13:05: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       12513 : PLUMED_REGISTER_ACTION(TD_Chi,"TD_CHI")
+      92             : 
+      93             : 
+      94          11 : void TD_Chi::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi distribution given as positive integer larger than 1.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_Chi::TD_Chi(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118             : 
+     119           9 :   std::vector<unsigned int> kappa_int(0);
+     120          18 :   parseVector("KAPPA",kappa_int);
+     121           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 1");}
+     122           9 :   kappa_.resize(kappa_int.size());
+     123          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     124           9 :     if(kappa_int[k] < 1) {plumed_merror(getName()+": KAPPA should be an integer 1 or higher");}
+     125           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     126             :   }
+     127             : 
+     128           9 :   setDimension(minima_.size());
+     129           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     130           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     131           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     132             : 
+     133           9 :   normalization_.resize(getDimension());
+     134          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     135           9 :     normalization_[k] = pow(2.0,(1.0-0.5*kappa_[k]))/(tgamma(0.5*kappa_[k])*sigma_[k]);
+     136             :   }
+     137           9 :   checkRead();
+     138           9 : }
+     139             : 
+     140             : 
+     141        1509 : double TD_Chi::getValue(const std::vector<double>& argument) const {
+     142             :   double value = 1.0;
+     143        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     144        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     145        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi distribution is not defined for values less that ones given in MINIMUM");}
+     146        1509 :     value *= normalization_[k] * pow(arg,kappa_[k]-1.0) * exp(-0.5*arg*arg);
+     147             :   }
+     148        1509 :   return value;
+     149             : }
+     150             : 
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html new file mode 100644 index 0000000000..598946d944 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func.html b/coverage/ves/TD_ChiSquared.cpp.func.html new file mode 100644 index 0000000000..631b158926 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe916createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_125TD_ChiSquaredRegisterMe91D2Ev4168
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.gcov.html b/coverage/ves/TD_ChiSquared.cpp.gcov.html new file mode 100644 index 0000000000..f5c1bb0ebf --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + 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-05-27 13:05: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       12513 : PLUMED_REGISTER_ACTION(TD_ChiSquared,"TD_CHISQUARED")
+      92             : 
+      93             : 
+      94          11 : void TD_ChiSquared::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi-squared distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi-squared distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi-squared distribution given as positive integer larger than 2.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_ChiSquared::TD_ChiSquared(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118           9 :   std::vector<unsigned int> kappa_int(0);
+     119          18 :   parseVector("KAPPA",kappa_int);
+     120           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 2");}
+     121           9 :   kappa_.resize(kappa_int.size());
+     122          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     123           9 :     if(kappa_int[k] < 2) {plumed_merror(getName()+": KAPPA should be an integer 2 or higher");}
+     124           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     125             :   }
+     126             : 
+     127           9 :   setDimension(minima_.size());
+     128           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     129           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     130           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     131             : 
+     132           9 :   normalization_.resize(getDimension());
+     133          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     134           9 :     normalization_[k] = 1.0/(pow(2.0,0.5*kappa_[k])*tgamma(0.5*kappa_[k])*sigma_[k]);
+     135             :   }
+     136           9 :   checkRead();
+     137           9 : }
+     138             : 
+     139             : 
+     140        1509 : double TD_ChiSquared::getValue(const std::vector<double>& argument) const {
+     141             :   double value = 1.0;
+     142        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     143        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     144        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi-squared istribution is not defined for values less that ones given in MINIMUM");}
+     145        1509 :     value *= normalization_[k] * pow(arg,0.5*kappa_[k]-1.0) * exp(-0.5*arg);
+     146             :   }
+     147        1509 :   return value;
+     148             : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func-sort-c.html b/coverage/ves/TD_Custom.cpp.func-sort-c.html new file mode 100644 index 0000000000..041821c254 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE18
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func.html b/coverage/ves/TD_Custom.cpp.func.html new file mode 100644 index 0000000000..f161d42f8f --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05:14Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe1466createERKNS_13ActionOptionsE16
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122TD_CustomRegisterMe146D2Ev4168
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.gcov.html b/coverage/ves/TD_Custom.cpp.gcov.html new file mode 100644 index 0000000000..6900337198 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + 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-05-27 13:05: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          48 :   ~TD_Custom() {};
+     144             : };
+     145             : 
+     146       12520 : PLUMED_REGISTER_ACTION(TD_Custom,"TD_CUSTOM")
+     147             : 
+     148             : 
+     149          18 : void TD_Custom::registerKeywords(Keywords& keys) {
+     150          18 :   TargetDistribution::registerKeywords(keys);
+     151          36 :   keys.add("compulsory","FUNCTION","The function you wish to use for the target distribution where you should use the variables _s1_,_s2_,... for the arguments. You can also use the current estimate of the FES by using the variable _FE_ and the temperature by using the \\f$k_B T\\f$ and _beta_ variables.");
+     152          18 :   keys.use("WELLTEMPERED_FACTOR");
+     153          18 :   keys.use("SHIFT_TO_ZERO");
+     154          18 : }
+     155             : 
+     156             : 
+     157          16 : TD_Custom::TD_Custom(const ActionOptions& ao):
+     158             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     159             : //
+     160          16 :   cv_var_lepton_refs_(0,nullptr),
+     161          16 :   kbt_var_lepton_ref_(nullptr),
+     162          16 :   beta_var_lepton_ref_(nullptr),
+     163          16 :   fes_var_lepton_ref_(nullptr),
+     164             : //
+     165          16 :   cv_var_idx_(0),
+     166          16 :   cv_var_str_(0),
+     167             : //
+     168          16 :   cv_var_prefix_str_("s"),
+     169          16 :   fes_var_str_("FE"),
+     170          16 :   kbt_var_str_("kBT"),
+     171          16 :   beta_var_str_("beta"),
+     172             : //
+     173          16 :   use_fes_(false),
+     174          16 :   use_kbt_(false),
+     175          32 :   use_beta_(false)
+     176             : {
+     177             :   std::string func_str;
+     178          16 :   parse("FUNCTION",func_str);
+     179          16 :   checkRead();
+     180             :   //
+     181             :   try {
+     182          16 :     lepton::ParsedExpression pe=lepton::Parser::parse(func_str).optimize(lepton::Constants());
+     183          16 :     log<<"  function as parsed by lepton: "<<pe<<"\n";
+     184          16 :     expression=pe.createCompiledExpression();
+     185             :   }
+     186           0 :   catch(PLMD::lepton::Exception& exc) {
+     187           0 :     plumed_merror("There was some problem in parsing the function "+func_str+" given in FUNCTION with lepton");
+     188           0 :   }
+     189             : 
+     190          39 :   for(auto &p: expression.getVariables()) {
+     191          23 :     std::string curr_var = p;
+     192             :     unsigned int cv_idx;
+     193          39 :     if(curr_var.substr(0,cv_var_prefix_str_.size())==cv_var_prefix_str_ && Tools::convertNoexcept(curr_var.substr(cv_var_prefix_str_.size()),cv_idx) && cv_idx>0) {
+     194          16 :       cv_var_idx_.push_back(cv_idx-1);
+     195             :     }
+     196           7 :     else if(curr_var==fes_var_str_) {
+     197           3 :       use_fes_=true;
+     198             :       setDynamic();
+     199             :       setFesGridNeeded();
+     200             :     }
+     201           4 :     else if(curr_var==kbt_var_str_) {
+     202           2 :       use_kbt_=true;
+     203             :     }
+     204           2 :     else if(curr_var==beta_var_str_) {
+     205           2 :       use_beta_=true;
+     206             :     }
+     207             :     else {
+     208           0 :       plumed_merror(getName()+": problem with parsing formula with lepton, cannot recognise the variable "+curr_var);
+     209             :     }
+     210             :   }
+     211             :   //
+     212          16 :   std::sort(cv_var_idx_.begin(),cv_var_idx_.end());
+     213          16 :   cv_var_str_.resize(cv_var_idx_.size());
+     214          16 :   cv_var_lepton_refs_.resize(cv_var_str_.size());
+     215          32 :   for(unsigned int j=0; j<cv_var_idx_.size(); j++) {
+     216          16 :     std::string str1; Tools::convert(cv_var_idx_[j]+1,str1);
+     217          32 :     cv_var_str_[j] = cv_var_prefix_str_+str1;
+     218             :     try {
+     219          16 :       cv_var_lepton_refs_[j] = &expression.getVariableReference(cv_var_str_[j]);
+     220           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     221             :   }
+     222             : 
+     223          16 :   if(use_kbt_) {
+     224             :     try {
+     225           2 :       kbt_var_lepton_ref_ = &expression.getVariableReference(kbt_var_str_);
+     226           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     227             :   }
+     228          16 :   if(use_beta_) {
+     229             :     try {
+     230           2 :       beta_var_lepton_ref_ = &expression.getVariableReference(beta_var_str_);
+     231           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     232             :   }
+     233          16 :   if(use_fes_) {
+     234             :     try {
+     235           3 :       fes_var_lepton_ref_ = &expression.getVariableReference(fes_var_str_);
+     236           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     237             :   }
+     238             : 
+     239          16 : }
+     240             : 
+     241             : 
+     242          16 : void TD_Custom::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     243          16 :   if(cv_var_idx_.size()>0 && cv_var_idx_[cv_var_idx_.size()-1]>getDimension()) {
+     244           0 :     plumed_merror(getName()+": mismatch between CVs given in FUNC and the dimension of the target distribution");
+     245             :   }
+     246          16 : }
+     247             : 
+     248             : 
+     249           0 : double TD_Custom::getValue(const std::vector<double>& argument) const {
+     250           0 :   plumed_merror("getValue not implemented for TD_Custom");
+     251             :   return 0.0;
+     252             : }
+     253             : 
+     254             : 
+     255          46 : void TD_Custom::updateGrid() {
+     256          46 :   if(use_fes_) {
+     257          33 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to the free energy in the target distribution");
+     258             :   }
+     259          46 :   if(use_kbt_) {
+     260          22 :     if(kbt_var_lepton_ref_) {*kbt_var_lepton_ref_= 1.0/getBeta();}
+     261             :   }
+     262          46 :   if(use_beta_) {
+     263          22 :     if(beta_var_lepton_ref_) {*beta_var_lepton_ref_= getBeta();}
+     264             :   }
+     265             :   //
+     266          92 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     267             :   double norm = 0.0;
+     268             :   //
+     269       40909 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     270       40863 :     std::vector<double> point = targetDistGrid().getPoint(l);
+     271       99928 :     for(unsigned int k=0; k<cv_var_str_.size() ; k++) {
+     272       59065 :       if(cv_var_lepton_refs_[k]) {*cv_var_lepton_refs_[k] = point[cv_var_idx_[k]];}
+     273             :     }
+     274       40863 :     if(use_fes_) {
+     275        3300 :       if(fes_var_lepton_ref_) {*fes_var_lepton_ref_ = getFesGridPntr()->getValue(l);}
+     276             :     }
+     277       40863 :     double value = expression.evaluate();
+     278             : 
+     279       40863 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     280       40863 :     targetDistGrid().setValue(l,value);
+     281       40863 :     norm += integration_weights[l]*value;
+     282       40863 :     logTargetDistGrid().setValue(l,-std::log(value));
+     283             :   }
+     284          46 :   if(norm>0.0) {
+     285          45 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     286             :   }
+     287           1 :   else if(!isTargetDistGridShiftedToZero()) {
+     288           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     289             :   }
+     290          46 :   logTargetDistGrid().setMinToZero();
+     291          46 : }
+     292             : 
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func-sort-c.html b/coverage/ves/TD_Exponential.cpp.func-sort-c.html new file mode 100644 index 0000000000..02b5a64113 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func.html b/coverage/ves/TD_Exponential.cpp.func.html new file mode 100644 index 0000000000..27f6eeb442 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe846createERKNS_13ActionOptionsE8
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_126TD_ExponentialRegisterMe84D2Ev4168
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.gcov.html b/coverage/ves/TD_Exponential.cpp.gcov.html new file mode 100644 index 0000000000..07d1b00b41 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.gcov.html @@ -0,0 +1,205 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(TD_Exponential,"TD_EXPONENTIAL")
+      85             : 
+      86             : 
+      87          10 : void TD_Exponential::registerKeywords(Keywords& keys) {
+      88          10 :   TargetDistribution::registerKeywords(keys);
+      89          20 :   keys.add("compulsory","MINIMUM","The minimum of the exponential distribution.");
+      90          20 :   keys.add("compulsory","LAMBDA","The lambda parameter of the exponential distribution given as positive number.");
+      91          10 :   keys.use("WELLTEMPERED_FACTOR");
+      92          10 :   keys.use("SHIFT_TO_ZERO");
+      93          10 :   keys.use("NORMALIZE");
+      94          10 : }
+      95             : 
+      96             : 
+      97           8 : TD_Exponential::TD_Exponential(const ActionOptions& ao):
+      98             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+      99          16 :   minima_(0),
+     100           8 :   lambda_(0)
+     101             : {
+     102           8 :   parseVector("MINIMUM",minima_);
+     103           8 :   parseVector("LAMBDA",lambda_);
+     104          16 :   for(unsigned int k=0; k<lambda_.size(); k++) {
+     105           8 :     if(lambda_[k] < 0.0) {plumed_merror(getName()+": the value given in LAMBDA should be positive.");}
+     106             :   }
+     107             : 
+     108             : 
+     109           8 :   setDimension(minima_.size());
+     110           8 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     111           8 :   if(lambda_.size()!=getDimension()) {plumed_merror(getName()+": the LAMBDA keyword does not match the given dimension in MINIMUM");}
+     112           8 :   checkRead();
+     113           8 : }
+     114             : 
+     115             : 
+     116        1308 : double TD_Exponential::getValue(const std::vector<double>& argument) const {
+     117             :   double value = 1.0;
+     118        2616 :   for(unsigned int k=0; k<argument.size(); k++) {
+     119        1308 :     double arg = (argument[k]-minima_[k])*lambda_[k];
+     120        1308 :     if(arg<0.0) {plumed_merror(getName()+": the exponential distribution is not defined for values less that ones given in MINIMUM");}
+     121        1308 :     value *= lambda_[k]*exp(-arg);
+     122             :   }
+     123        1308 :   return value;
+     124             : }
+     125             : 
+     126             : 
+     127             : 
+     128             : }
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html new file mode 100644 index 0000000000..05ad11368e --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE8
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119D2Ev4168
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html new file mode 100644 index 0000000000..37dba0e3bc --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe1196createERKNS_13ActionOptionsE6
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_145TD_ExponentiallyModifiedGaussianRegisterMe119D2Ev4168
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html new file mode 100644 index 0000000000..941255f72f --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html @@ -0,0 +1,300 @@ + + + + + + + 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-05-27 13:05: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       12510 : PLUMED_REGISTER_ACTION(TD_ExponentiallyModifiedGaussian,"TD_EXPONENTIALLY_MODIFIED_GAUSSIAN")
+     120             : 
+     121             : 
+     122           8 : void TD_ExponentiallyModifiedGaussian::registerKeywords(Keywords& keys) {
+     123           8 :   TargetDistribution::registerKeywords(keys);
+     124          16 :   keys.add("numbered","CENTER","The center of each exponentially modified Gaussian distributions.");
+     125          16 :   keys.add("numbered","SIGMA","The sigma parameters for each exponentially modified Gaussian distributions.");
+     126          16 :   keys.add("numbered","LAMBDA","The lambda parameters for each exponentially modified Gaussian distributions");
+     127          16 :   keys.add("optional","WEIGHTS","The weights of the distributions. By default all are weighted equally.");
+     128           8 :   keys.use("WELLTEMPERED_FACTOR");
+     129           8 :   keys.use("SHIFT_TO_ZERO");
+     130           8 :   keys.use("NORMALIZE");
+     131           8 : }
+     132             : 
+     133             : 
+     134           6 : TD_ExponentiallyModifiedGaussian::TD_ExponentiallyModifiedGaussian(const ActionOptions& ao):
+     135             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     136          12 :   centers_(0),
+     137           6 :   sigmas_(0),
+     138           6 :   lambdas_(0),
+     139           6 :   weights_(0),
+     140          12 :   ncenters_(0)
+     141             : {
+     142           9 :   for(unsigned int i=1;; i++) {
+     143             :     std::vector<double> tmp_center;
+     144          30 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     145           9 :     centers_.push_back(tmp_center);
+     146           9 :   }
+     147           9 :   for(unsigned int i=1;; i++) {
+     148             :     std::vector<double> tmp_sigma;
+     149          30 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     150          20 :     for(unsigned int k=0; k<tmp_sigma.size(); k++) {
+     151          11 :       if(tmp_sigma[k]<=0.0) {plumed_merror(getName()+": the values given in SIGMA should be positive");}
+     152             :     }
+     153           9 :     sigmas_.push_back(tmp_sigma);
+     154           9 :   }
+     155           9 :   for(unsigned int i=1;; i++) {
+     156             :     std::vector<double> tmp_lambda;
+     157          30 :     if(!parseNumberedVector("LAMBDA",i,tmp_lambda) ) {break;}
+     158          20 :     for(unsigned int k=0; k<tmp_lambda.size(); k++) {
+     159          11 :       if(tmp_lambda[k]<=0.0) {plumed_merror(getName()+": the values given in LAMBDA should be positive");}
+     160             :     }
+     161           9 :     lambdas_.push_back(tmp_lambda);
+     162           9 :   }
+     163             :   //
+     164           6 :   if(centers_.size()==0) {
+     165           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     166             :   }
+     167             :   //
+     168           6 :   if(centers_.size()!=sigmas_.size() || centers_.size()!=lambdas_.size() ) {
+     169           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, SIGMA, and LAMBDA keywords");
+     170             :   }
+     171             :   //
+     172           6 :   setDimension(centers_[0].size());
+     173           6 :   ncenters_ = centers_.size();
+     174             :   //
+     175             :   // check centers and sigmas
+     176          15 :   for(unsigned int i=0; i<ncenters_; i++) {
+     177           9 :     if(centers_[i].size()!=getDimension()) {
+     178           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     179             :     }
+     180           9 :     if(sigmas_[i].size()!=getDimension()) {
+     181           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     182             :     }
+     183           9 :     if(lambdas_[i].size()!=getDimension()) {
+     184           0 :       plumed_merror(getName()+": one of the LAMBDA keyword does not match the given dimension");
+     185             :     }
+     186             :   }
+     187             :   //
+     188          12 :   parseVector("WEIGHTS",weights_);
+     189           6 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     190           6 :   if(centers_.size()!=weights_.size()) {
+     191           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     192             :   }
+     193             :   //
+     194             :   double sum_weights=0.0;
+     195          15 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     196          15 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     197             :   //
+     198           6 :   checkRead();
+     199           6 : }
+     200             : 
+     201             : 
+     202       11206 : double TD_ExponentiallyModifiedGaussian::getValue(const std::vector<double>& argument) const {
+     203             :   double value=0.0;
+     204       33015 :   for(unsigned int i=0; i<ncenters_; i++) {
+     205       21809 :     value+=weights_[i]*ExponentiallyModifiedGaussianDiagonal(argument,centers_[i],sigmas_[i],lambdas_[i]);
+     206             :   }
+     207       11206 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211       21809 : double TD_ExponentiallyModifiedGaussian::ExponentiallyModifiedGaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& lambda) const {
+     212             :   double value = 1.0;
+     213       64020 :   for(unsigned int k=0; k<argument.size(); k++) {
+     214       42211 :     double arg1 = 0.5*lambda[k]*(2.0*center[k]+lambda[k]*sigma[k]*sigma[k]-2.0*argument[k]);
+     215       42211 :     double arg2 = (center[k]+lambda[k]*sigma[k]*sigma[k]-argument[k])/(sqrt(2.0)*sigma[k]);
+     216       42211 :     value *= 0.5*lambda[k]*exp(arg1)*erfc(arg2);
+     217             :   }
+     218       21809 :   return value;
+     219             : }
+     220             : 
+     221             : 
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func-sort-c.html b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html new file mode 100644 index 0000000000..c86eb08b3b --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE193
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176D2Ev4168
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func.html b/coverage/ves/TD_Gaussian.cpp.func.html new file mode 100644 index 0000000000..8d0c979041 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE193
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe1766createERKNS_13ActionOptionsE191
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124TD_GaussianRegisterMe176D2Ev4168
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.gcov.html b/coverage/ves/TD_Gaussian.cpp.gcov.html new file mode 100644 index 0000000000..1cbe092205 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.gcov.html @@ -0,0 +1,391 @@ + + + + + + + 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-05-27 13:05: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       12695 : PLUMED_REGISTER_ACTION(TD_Gaussian,"TD_GAUSSIAN")
+     177             : 
+     178             : 
+     179         193 : void TD_Gaussian::registerKeywords(Keywords& keys) {
+     180         193 :   TargetDistribution::registerKeywords(keys);
+     181         386 :   keys.add("numbered","CENTER","The centers of the Gaussian distributions.");
+     182         386 :   keys.add("numbered","SIGMA","The standard deviations of the Gaussian distributions.");
+     183         386 :   keys.add("numbered","CORRELATION","The correlation for two-dimensional bivariate Gaussian distributions. Only works for two arguments. The value should be between -1 and 1. If no value is given the Gaussian kernels is considered as un-correlated (i.e. value of 0.0).");
+     184         386 :   keys.add("optional","WEIGHTS","The weights of the Gaussian distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     185         193 :   keys.use("WELLTEMPERED_FACTOR");
+     186         193 :   keys.use("SHIFT_TO_ZERO");
+     187         193 :   keys.use("NORMALIZE");
+     188         193 : }
+     189             : 
+     190             : 
+     191         191 : TD_Gaussian::TD_Gaussian(const ActionOptions& ao):
+     192             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     193         382 :   centers_(0),
+     194         191 :   sigmas_(0),
+     195         191 :   correlation_(0),
+     196         191 :   weights_(0),
+     197         191 :   diagonal_(true),
+     198         382 :   ncenters_(0)
+     199             : {
+     200         211 :   for(unsigned int i=1;; i++) {
+     201             :     std::vector<double> tmp_center;
+     202         804 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     203         211 :     centers_.push_back(tmp_center);
+     204         211 :   }
+     205         211 :   for(unsigned int i=1;; i++) {
+     206             :     std::vector<double> tmp_sigma;
+     207         804 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     208         211 :     sigmas_.push_back(tmp_sigma);
+     209         211 :   }
+     210             : 
+     211         191 :   if(centers_.size()==0) {
+     212           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     213             :   }
+     214             :   //
+     215         191 :   if(centers_.size()!=sigmas_.size()) {
+     216           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER and SIGMA keywords");
+     217             :   }
+     218             :   //
+     219         191 :   setDimension(centers_[0].size());
+     220         191 :   ncenters_ = centers_.size();
+     221             :   // check centers and sigmas
+     222         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     223         211 :     if(centers_[i].size()!=getDimension()) {
+     224           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     225             :     }
+     226         211 :     if(sigmas_[i].size()!=getDimension()) {
+     227           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     228             :     }
+     229             :   }
+     230             :   //
+     231         191 :   correlation_.resize(ncenters_);
+     232             : 
+     233         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     234             :     std::vector<double> corr;
+     235         422 :     parseNumberedVector("CORRELATION",(i+1),corr);
+     236         211 :     if(corr.size()>0) {
+     237           3 :       diagonal_ = false;
+     238             :     }
+     239             :     else {
+     240         208 :       corr.assign(1,0.0);
+     241             :     }
+     242         211 :     correlation_[i] = corr;
+     243             :   }
+     244             : 
+     245         191 :   if(!diagonal_ && getDimension()!=2) {
+     246           0 :     plumed_merror(getName()+": CORRELATION is only defined for two-dimensional Gaussians for now.");
+     247             :   }
+     248         402 :   for(unsigned int i=0; i<correlation_.size(); i++) {
+     249         211 :     if(correlation_[i].size()!=1) {
+     250           0 :       plumed_merror(getName()+": only one value should be given in CORRELATION");
+     251             :     }
+     252         422 :     for(unsigned int k=0; k<correlation_[i].size(); k++) {
+     253         211 :       if(correlation_[i][k] <= -1.0 ||  correlation_[i][k] >= 1.0) {
+     254           0 :         plumed_merror(getName()+": values given in CORRELATION should be between -1.0 and 1.0" );
+     255             :       }
+     256             :     }
+     257             :   }
+     258             :   //
+     259         382 :   parseVector("WEIGHTS",weights_);
+     260         191 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     261         191 :   if(centers_.size()!=weights_.size()) {
+     262           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     263             :   }
+     264             :   //
+     265             :   double sum_weights=0.0;
+     266         402 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     267         402 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     268             :   //
+     269         191 :   checkRead();
+     270         191 : }
+     271             : 
+     272             : 
+     273      229739 : double TD_Gaussian::getValue(const std::vector<double>& argument) const {
+     274             :   double value=0.0;
+     275      229739 :   if(diagonal_) {
+     276      501589 :     for(unsigned int i=0; i<ncenters_; i++) {
+     277      292252 :       value+=weights_[i]*GaussianDiagonal(argument, centers_[i], sigmas_[i]);
+     278             :     }
+     279             :   }
+     280       20402 :   else if(!diagonal_ && getDimension()==2) {
+     281       61206 :     for(unsigned int i=0; i<ncenters_; i++) {
+     282       40804 :       value+=weights_[i]*Gaussian2D(argument, centers_[i], sigmas_[i],correlation_[i]);
+     283             :     }
+     284             :   }
+     285      229739 :   return value;
+     286             : }
+     287             : 
+     288             : 
+     289      292252 : double TD_Gaussian::GaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, bool normalize) const {
+     290             :   double value = 1.0;
+     291      828323 :   for(unsigned int k=0; k<argument.size(); k++) {
+     292      536071 :     double arg=(argument[k]-center[k])/sigma[k];
+     293      536071 :     double tmp_exp = exp(-0.5*arg*arg);
+     294      536071 :     if(normalize) {tmp_exp/=(sigma[k]*sqrt(2.0*pi));}
+     295      536071 :     value*=tmp_exp;
+     296             :   }
+     297      292252 :   return value;
+     298             : }
+     299             : 
+     300             : 
+     301       40804 : double TD_Gaussian::Gaussian2D(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& correlation, bool normalize) const {
+     302       40804 :   double arg1 = (argument[0]-center[0])/sigma[0];
+     303       40804 :   double arg2 = (argument[1]-center[1])/sigma[1];
+     304       40804 :   double corr = correlation[0];
+     305       40804 :   double value = (arg1*arg1 + arg2*arg2 - 2.0*corr*arg1*arg2);
+     306       40804 :   value *= -1.0 / ( 2.0*(1.0-corr*corr) );
+     307       40804 :   value = exp(value);
+     308       40804 :   if(normalize) {
+     309       40804 :     value /=  2*pi*sigma[0]*sigma[1]*sqrt(1.0-corr*corr);
+     310             :   }
+     311       40804 :   return value;
+     312             : }
+     313             : 
+     314             : }
+     315             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html new file mode 100644 index 0000000000..6f1f51de4f --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE7
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html new file mode 100644 index 0000000000..143cda41a3 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe1126createERKNS_13ActionOptionsE5
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_139TD_GeneralizedExtremeValueRegisterMe112D2Ev4168
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html new file mode 100644 index 0000000000..68170e45e1 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + 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-05-27 13:05: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       12509 : PLUMED_REGISTER_ACTION(TD_GeneralizedExtremeValue,"TD_GENERALIZED_EXTREME_VALUE")
+     113             : 
+     114             : 
+     115           7 : void TD_GeneralizedExtremeValue::registerKeywords(Keywords& keys) {
+     116           7 :   TargetDistribution::registerKeywords(keys);
+     117          14 :   keys.add("compulsory","LOCATION","The mu parameter of the generalized extreme value distribution.");
+     118          14 :   keys.add("compulsory","SCALE","The sigma parameter for the generalized extreme value distribution given as a positive number.");
+     119          14 :   keys.add("compulsory","SHAPE","The xi parameter for the generalized extreme value distribution.");
+     120           7 :   keys.use("WELLTEMPERED_FACTOR");
+     121           7 :   keys.use("SHIFT_TO_ZERO");
+     122           7 :   keys.use("NORMALIZE");
+     123           7 : }
+     124             : 
+     125             : 
+     126           5 : TD_GeneralizedExtremeValue::TD_GeneralizedExtremeValue(const ActionOptions& ao):
+     127             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     128          10 :   center_(0),
+     129           5 :   scale_(0),
+     130           5 :   shape_(0),
+     131          10 :   normalization_(0)
+     132             : {
+     133           5 :   parseVector("LOCATION",center_);
+     134           5 :   parseVector("SCALE",scale_);
+     135          10 :   parseVector("SHAPE",shape_);
+     136             : 
+     137           5 :   setDimension(center_.size());
+     138           5 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     139           5 :   if(scale_.size()!=getDimension()) {plumed_merror(getName()+": the SCALE keyword does not match the given dimension in MINIMA");}
+     140           5 :   if(shape_.size()!=getDimension()) {plumed_merror(getName()+": the SHAPE keyword does not match the given dimension in MINIMA");}
+     141             : 
+     142           5 :   normalization_.resize(getDimension());
+     143          10 :   for(unsigned int k=0; k<getDimension(); k++) {
+     144           5 :     if(scale_[k]<0.0) {plumed_merror(getName()+": the value given for the scale parameter in SCALE should be larger than 0.0");}
+     145           5 :     normalization_[k] = 1.0/scale_[k];
+     146             :   }
+     147           5 :   checkRead();
+     148           5 : }
+     149             : 
+     150             : 
+     151        1605 : double TD_GeneralizedExtremeValue::getValue(const std::vector<double>& argument) const {
+     152        1605 :   return GEVdiagonal(argument,center_,scale_,shape_,normalization_);
+     153             : }
+     154             : 
+     155             : 
+     156        1605 : double TD_GeneralizedExtremeValue::GEVdiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& scale, const std::vector<double>& shape, const std::vector<double>& normalization) const {
+     157             :   double value = 1.0;
+     158        2940 :   for(unsigned int k=0; k<argument.size(); k++) {
+     159        1605 :     double arg=(argument[k]-center[k])/scale[k];
+     160             :     double tx;
+     161        1605 :     if(shape_[k]!=0.0) {
+     162        1404 :       if( shape_[k]>0 && argument[k] <= (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     163        1214 :       if( shape_[k]<0 && argument[k] > (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     164        1134 :       tx = pow( (1.0+arg*shape[k]), -1.0/shape[k] );
+     165             :     }
+     166             :     else {
+     167         201 :       tx = exp(-arg);
+     168             :     }
+     169        1335 :     value *= normalization[k] * pow(tx,shape[k]+1.0) * exp(-tx);
+     170             :   }
+     171             :   return value;
+     172             : }
+     173             : 
+     174             : 
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html new file mode 100644 index 0000000000..1bce6b634b --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE10
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114D2Ev4168
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func.html b/coverage/ves/TD_GeneralizedNormal.cpp.func.html new file mode 100644 index 0000000000..b49176c1ea --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe1146createERKNS_13ActionOptionsE8
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_133TD_GeneralizedNormalRegisterMe114D2Ev4168
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html new file mode 100644 index 0000000000..0d32fa8524 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html @@ -0,0 +1,303 @@ + + + + + + + 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-05-27 13:05: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       12512 : PLUMED_REGISTER_ACTION(TD_GeneralizedNormal,"TD_GENERALIZED_NORMAL")
+     115             : 
+     116             : 
+     117          10 : void TD_GeneralizedNormal::registerKeywords(Keywords& keys) {
+     118          10 :   TargetDistribution::registerKeywords(keys);
+     119          20 :   keys.add("numbered","CENTER","The center of each generalized normal distribution.");
+     120          20 :   keys.add("numbered","ALPHA","The alpha parameters for each generalized normal distribution.");
+     121          20 :   keys.add("numbered","BETA","The beta parameters for each generalized normal distribution.");
+     122          20 :   keys.add("optional","WEIGHTS","The weights of the generalized normal distribution. By default all are weighted equally.");
+     123          10 :   keys.use("WELLTEMPERED_FACTOR");
+     124          10 :   keys.use("SHIFT_TO_ZERO");
+     125          10 :   keys.use("NORMALIZE");
+     126          10 : }
+     127             : 
+     128             : 
+     129           8 : TD_GeneralizedNormal::TD_GeneralizedNormal(const ActionOptions& ao):
+     130             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     131          16 :   centers_(0),
+     132           8 :   alphas_(0),
+     133           8 :   betas_(0),
+     134           8 :   normalization_(0),
+     135           8 :   weights_(0),
+     136          16 :   ncenters_(0)
+     137             : {
+     138          15 :   for(unsigned int i=1;; i++) {
+     139             :     std::vector<double> tmp_center;
+     140          46 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     141          15 :     centers_.push_back(tmp_center);
+     142          15 :   }
+     143          15 :   for(unsigned int i=1;; i++) {
+     144             :     std::vector<double> tmp_alpha;
+     145          46 :     if(!parseNumberedVector("ALPHA",i,tmp_alpha) ) {break;}
+     146          35 :     for(unsigned int k=0; k<tmp_alpha.size(); k++) {
+     147          20 :       if(tmp_alpha[k]<=0.0) {plumed_merror(getName()+": the values given in ALPHA should be positive");}
+     148             :     }
+     149          15 :     alphas_.push_back(tmp_alpha);
+     150          15 :   }
+     151          15 :   for(unsigned int i=1;; i++) {
+     152             :     std::vector<double> tmp_beta;
+     153          46 :     if(!parseNumberedVector("BETA",i,tmp_beta) ) {break;}
+     154          35 :     for(unsigned int k=0; k<tmp_beta.size(); k++) {
+     155          20 :       if(tmp_beta[k]<=0.0) {plumed_merror(getName()+": the values given in BETA should be positive");}
+     156             :     }
+     157          15 :     betas_.push_back(tmp_beta);
+     158          15 :   }
+     159             :   //
+     160           8 :   if(centers_.size()==0) {
+     161           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     162             :   }
+     163             :   //
+     164           8 :   if(centers_.size()!=alphas_.size() || centers_.size()!=betas_.size() ) {
+     165           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, ALPHA, and BETA keywords");
+     166             :   }
+     167             :   //
+     168           8 :   setDimension(centers_[0].size());
+     169           8 :   ncenters_ = centers_.size();
+     170             :   //
+     171             :   // check centers and sigmas
+     172          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     173          15 :     if(centers_[i].size()!=getDimension()) {
+     174           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     175             :     }
+     176          15 :     if(alphas_[i].size()!=getDimension()) {
+     177           0 :       plumed_merror(getName()+": one of the ALPHA keyword does not match the given dimension");
+     178             :     }
+     179          15 :     if(betas_[i].size()!=getDimension()) {
+     180           0 :       plumed_merror(getName()+": one of the BETA keyword does not match the given dimension");
+     181             :     }
+     182             :   }
+     183             :   //
+     184          16 :   parseVector("WEIGHTS",weights_);
+     185           8 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     186           8 :   if(centers_.size()!=weights_.size()) {
+     187           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     188             :   }
+     189             :   //
+     190             :   double sum_weights=0.0;
+     191          23 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     192          23 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     193             :   //
+     194           8 :   normalization_.resize(ncenters_);
+     195          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     196          15 :     normalization_[i].resize(getDimension());
+     197          35 :     for(unsigned int k=0; k<getDimension(); k++) {
+     198          20 :       normalization_[i][k] = 0.5*betas_[i][k]/(alphas_[i][k]*tgamma(1.0/betas_[i][k]));
+     199             :     }
+     200             :   }
+     201           8 :   checkRead();
+     202           8 : }
+     203             : 
+     204             : 
+     205       21608 : double TD_GeneralizedNormal::getValue(const std::vector<double>& argument) const {
+     206             :   double value=0.0;
+     207       74623 :   for(unsigned int i=0; i<ncenters_; i++) {
+     208       53015 :     value+=weights_[i]*ExponentialPowerDiagonal(argument,centers_[i],alphas_[i],betas_[i],normalization_[i]);
+     209             :   }
+     210       21608 :   return value;
+     211             : }
+     212             : 
+     213             : 
+     214       53015 : double TD_GeneralizedNormal::ExponentialPowerDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& alpha, const std::vector<double>& beta, const std::vector<double>& normalization) const {
+     215             :   double value = 1.0;
+     216      157035 :   for(unsigned int k=0; k<argument.size(); k++) {
+     217      104020 :     double arg=(std::abs(argument[k]-center[k]))/alpha[k];
+     218      104020 :     arg = pow(arg,beta[k]);
+     219      104020 :     value*=normalization[k]*exp(-arg);
+     220             :   }
+     221       53015 :   return value;
+     222             : }
+     223             : 
+     224             : 
+     225             : 
+     226             : }
+     227             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func-sort-c.html b/coverage/ves/TD_Grid.cpp.func-sort-c.html new file mode 100644 index 0000000000..5b8ecc665b --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117D2Ev4168
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func.html b/coverage/ves/TD_Grid.cpp.func.html new file mode 100644 index 0000000000..b388f10e5d --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe1176createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_120TD_GridRegisterMe117D2Ev4168
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.gcov.html b/coverage/ves/TD_Grid.cpp.gcov.html new file mode 100644 index 0000000000..db92599174 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + 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-05-27 13:05: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       12513 : PLUMED_REGISTER_ACTION(TD_Grid,"TD_GRID")
+     118             : 
+     119             : 
+     120          11 : void TD_Grid::registerKeywords(Keywords& keys) {
+     121          11 :   TargetDistribution::registerKeywords(keys);
+     122          22 :   keys.add("compulsory","FILE","The name of the external grid file to be used as a target distribution.");
+     123          22 :   keys.add("optional","SHIFT","Shift the grid read in by some constant value. Due to normalization the final shift in the target distribution will generally not be the same as the value given here");
+     124          22 :   keys.addFlag("ZERO_OUTSIDE",false,"By default the target distribution is continuous such that values outside the boundary of the external grid file are the same as at the boundary. This can be changed by using this flag which will make values outside to be taken as zero.");
+     125          22 :   keys.addFlag("DO_NOT_NORMALIZE",false,"By default the target distribution from the external grid is always normalized inside the code. You can use this flag to disable this normalization. However, be warned that this will generally lead to the wrong behavior if the distribution from the external grid is not properly normalized to 1.");
+     126          11 :   keys.use("WELLTEMPERED_FACTOR");
+     127          11 :   keys.use("SHIFT_TO_ZERO");
+     128          11 : }
+     129             : 
+     130           9 : TD_Grid::TD_Grid(const ActionOptions& ao):
+     131             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     132           9 :   minima_(0),
+     133           9 :   maxima_(0),
+     134           9 :   zero_outside_(false),
+     135          18 :   shift_(0.0)
+     136             : {
+     137             :   std::string filename;
+     138           9 :   parse("FILE",filename);
+     139           9 :   parse("SHIFT",shift_);
+     140           9 :   if(shift_!=0.0) {
+     141           1 :     if(isTargetDistGridShiftedToZero()) {plumed_merror(getName() + ": using both SHIFT and SHIFT_TO_ZERO is not allowed.");}
+     142             :   }
+     143           9 :   parseFlag("ZERO_OUTSIDE",zero_outside_);
+     144             : 
+     145           9 :   bool do_not_normalize=false;
+     146           9 :   parseFlag("DO_NOT_NORMALIZE",do_not_normalize);
+     147           9 :   if(do_not_normalize && shift_!=0.0) {plumed_merror(getName() + ": using both SHIFT and DO_NOT_NORMALIZE is not allowed.");}
+     148           9 :   if(!do_not_normalize) {setForcedNormalization();}
+     149             : 
+     150           9 :   checkRead();
+     151             : 
+     152             :   std::string gridlabel;
+     153             :   std::vector<std::string> arglabels;
+     154             :   std::vector<std::string> argmin;
+     155             :   std::vector<std::string> argmax;
+     156             :   std::vector<bool> argperiodic;
+     157             :   std::vector<unsigned int> argnbins;
+     158           9 :   bool has_deriv = false;
+     159           9 :   unsigned int nargs = VesTools::getGridFileInfo(filename,gridlabel,arglabels,argmin,argmax,argperiodic,argnbins,has_deriv);
+     160           9 :   if(nargs==0) {
+     161           0 :     plumed_merror(getName() + ": problem in parsing information from grid file");
+     162             :   }
+     163             : 
+     164           9 :   setDimension(arglabels.size());
+     165           9 :   std::vector<std::unique_ptr<Value>> arguments(arglabels.size());
+     166          22 :   for(unsigned int i=0; i < arglabels.size(); i++) {
+     167          26 :     arguments[i]= Tools::make_unique<Value>(nullptr,arglabels[i],false);
+     168          13 :     if(argperiodic[i]) {
+     169           0 :       arguments[i]->setDomain(argmin[i],argmax[i]);
+     170             :     }
+     171             :     else {
+     172          13 :       arguments[i]->setNotPeriodic();
+     173             :     }
+     174             :   }
+     175             : 
+     176           9 :   IFile gridfile; gridfile.open(filename);
+     177           9 :   if(has_deriv) {
+     178           0 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,true,true);
+     179             :   }
+     180             :   else {
+     181          18 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,false,false);
+     182             :   }
+     183           9 :   gridfile.close();
+     184             : 
+     185             : 
+     186           9 :   minima_.resize(getDimension());
+     187           9 :   maxima_.resize(getDimension());
+     188           9 :   periodic_.resize(getDimension());
+     189          22 :   for (unsigned int i=0; i < getDimension(); i++) {
+     190          13 :     Tools::convert(distGrid_->getMin()[i],minima_[i]);
+     191          13 :     Tools::convert(distGrid_->getMax()[i],maxima_[i]);
+     192          13 :     periodic_[i] = argperiodic[i];
+     193          13 :     if(periodic_[i]) {maxima_[i]-=distGrid_->getDx()[i];}
+     194             :   }
+     195             : 
+     196          27 : }
+     197             : 
+     198             : 
+     199       49369 : double TD_Grid::getValue(const std::vector<double>& argument) const {
+     200             :   double outside = 0.0;
+     201       49369 :   std::vector<double> arg = argument;
+     202      145566 :   for(unsigned int k=0; k<getDimension(); k++) {
+     203       96533 :     if(zero_outside_ && (argument[k] < minima_[k] || argument[k] > maxima_[k])) {
+     204             :       return outside;
+     205             :     }
+     206       96197 :     else if(argument[k] < minima_[k]) {
+     207         168 :       arg[k] = minima_[k];
+     208             :     }
+     209       96029 :     else if(argument[k] > maxima_[k]) {
+     210         168 :       arg[k] =maxima_[k];
+     211             :     }
+     212             :   }
+     213       49033 :   return GridLinearInterpolation::getGridValueWithLinearInterpolation(distGrid_.get(),arg)+shift_;
+     214             : }
+     215             : 
+     216             : 
+     217             : }
+     218             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html new file mode 100644 index 0000000000..2f414cc835 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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:597875.6 %
Date:2024-05-27 13:05: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_LinearCombinationRegisterMe1516createERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe151C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe151D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func.html b/coverage/ves/TD_LinearCombination.cpp.func.html new file mode 100644 index 0000000000..5cb37bdeb6 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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:597875.6 %
Date:2024-05-27 13:05:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe1516createERKNS_13ActionOptionsE12
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe151C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_133TD_LinearCombinationRegisterMe151D2Ev4168
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.gcov.html b/coverage/ves/TD_LinearCombination.cpp.gcov.html new file mode 100644 index 0000000000..80425a0b7d --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.gcov.html @@ -0,0 +1,353 @@ + + + + + + + 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:597875.6 %
Date:2024-05-27 13:05: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             : #include <limits>
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : // class Grid;
+      37             : class Action;
+      38             : 
+      39             : namespace ves {
+      40             : 
+      41             : //+PLUMEDOC VES_TARGETDIST TD_LINEAR_COMBINATION
+      42             : /*
+      43             : Target distribution given by linear combination of distributions (static or dynamic).
+      44             : 
+      45             : Employ a target distribution that is a linear combination of the other
+      46             : distributions, defined as
+      47             : \f[
+      48             : p(\mathbf{s}) = \sum_{i} w_{i} \, p_{i}(\mathbf{s})
+      49             : \f]
+      50             : where the weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      51             : 
+      52             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      53             : linear combination are given in the DISTRIBUTIONS keyword.
+      54             : 
+      55             : The weights \f$w_{i}\f$ can be given using
+      56             : the WEIGHTS keyword. The distributions are weighted equally if no weights are given.
+      57             : 
+      58             : It is assumed that all the distributions \f$p_{i}(\mathbf{s})\f$ are normalized.
+      59             : If that is not the case for some reason should you
+      60             : normalize each distribution separately by using the NORMALIZE
+      61             : keyword when defining them in the input file (i.e. before the
+      62             : TD_LINEAR_COMBINATION action).
+      63             : Note that normalizing the overall
+      64             : linear combination will generally lead to different results than normalizing
+      65             : each distribution separately.
+      66             : 
+      67             : The linear combination will be a dynamic target distribution if one or more
+      68             : of the distributions used is a dynamic distribution, otherwise it will be a
+      69             : static distribution.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : Here we employ a linear combination of a uniform and a Gaussian distribution.
+      74             : No weights are given so the two distributions will be weighted equally.
+      75             : \plumedfile
+      76             : td_uni: TD_UNIFORM
+      77             : 
+      78             : td_gauss: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      79             : 
+      80             : td_comb: TD_LINEAR_COMBINATION DISTRIBUTIONS=td_uni,td_gauss
+      81             : \endplumedfile
+      82             : 
+      83             : Here we employ a linear combination of a uniform and two Gaussian distribution.
+      84             : The weights are automatically normalized to 1 such that giving
+      85             : WEIGHTS=1.0,1.0,2.0 as we do here is equal to giving WEIGHTS=0.25,0.25,0.50.
+      86             : \plumedfile
+      87             : td_uni: TD_UNIFORM
+      88             : 
+      89             : td_gauss1: TD_GAUSSIAN CENTER1=-2.0,-2.0 SIGMA1=0.5,0.3
+      90             : 
+      91             : td_gauss2: TD_GAUSSIAN CENTER1=+2.0,+2.0 SIGMA1=0.3,0.5
+      92             : 
+      93             : TD_LINEAR_COMBINATION ...
+      94             :  DISTRIBUTIONS=td_uni,td_gauss1,td_gauss2
+      95             :  WEIGHTS=1.0,1.0,2.0
+      96             :  LABEL=td_comb
+      97             : ... TD_LINEAR_COMBINATION
+      98             : \endplumedfile
+      99             : 
+     100             : In the above example the two Gaussian kernels are given using two separate
+     101             : DISTRIBUTION keywords. As the \ref TD_GAUSSIAN target distribution allows multiple
+     102             : centers is it also possible to use just one DISTRIBUTION keyword for the two
+     103             : Gaussian kernels. This is shown in the following example which will give the
+     104             : exact same result as the one above as the weights have been appropriately
+     105             : adjusted
+     106             : \plumedfile
+     107             : td_uni: TD_UNIFORM
+     108             : 
+     109             : TD_GAUSSIAN ...
+     110             :  CENTER1=-2.0,-2.0  SIGMA1=0.5,0.3
+     111             :  CENTER2=+2.0,+2.0  SIGMA2=0.3,0.5
+     112             :  WEIGHTS=1.0,2.0
+     113             :  LABEL=td_gauss
+     114             : ... TD_GAUSSIAN
+     115             : 
+     116             : TD_LINEAR_COMBINATION ...
+     117             :  DISTRIBUTIONS=td_uni,td_gauss
+     118             :  WEIGHTS=0.25,0.75
+     119             :  LABEL=td_comb
+     120             : ... TD_LINEAR_COMBINATION
+     121             : \endplumedfile
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : class VesBias;
+     127             : 
+     128             : class TD_LinearCombination: public TargetDistribution {
+     129             : private:
+     130             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     131             :   std::vector<Grid*> grid_pntrs_;
+     132             :   std::vector<double> weights_;
+     133             :   unsigned int ndist_;
+     134             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     135             : public:
+     136             :   static void registerKeywords(Keywords&);
+     137             :   explicit TD_LinearCombination(const ActionOptions& ao);
+     138             :   void updateGrid() override;
+     139             :   double getValue(const std::vector<double>&) const override;
+     140             :   //
+     141             :   void linkVesBias(VesBias*) override;
+     142             :   void linkAction(Action*) override;
+     143             :   //
+     144             :   void linkBiasGrid(Grid*) override;
+     145             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     146             :   void linkFesGrid(Grid*) override;
+     147             :   //
+     148             : };
+     149             : 
+     150             : 
+     151       12516 : PLUMED_REGISTER_ACTION(TD_LinearCombination,"TD_LINEAR_COMBINATION")
+     152             : 
+     153             : 
+     154          14 : void TD_LinearCombination::registerKeywords(Keywords& keys) {
+     155          14 :   TargetDistribution::registerKeywords(keys);
+     156          28 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the linear combination.");
+     157          28 :   keys.add("optional","WEIGHTS","The weights of target distributions. Have to be as many as the number of target distribution labels given in DISTRIBUTIONS. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     158          14 :   keys.use("WELLTEMPERED_FACTOR");
+     159             :   //keys.use("SHIFT_TO_ZERO");
+     160          14 :   keys.use("NORMALIZE");
+     161          14 : }
+     162             : 
+     163             : 
+     164          12 : TD_LinearCombination::TD_LinearCombination(const ActionOptions& ao):
+     165             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     166          24 :   distribution_pntrs_(0),
+     167          12 :   grid_pntrs_(0),
+     168          12 :   weights_(0),
+     169          24 :   ndist_(0)
+     170             : {
+     171             :   std::vector<std::string> targetdist_labels;
+     172          12 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     173             : 
+     174          12 :   std::string error_msg = "";
+     175          24 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     176          12 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     177             : 
+     178          40 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     179          28 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     180          28 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     181          28 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     182             :   }
+     183             : 
+     184          12 :   ndist_ = distribution_pntrs_.size();
+     185          12 :   grid_pntrs_.assign(ndist_,NULL);
+     186          12 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     187          12 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     188             :   //
+     189          24 :   parseVector("WEIGHTS",weights_);
+     190          12 :   if(weights_.size()==0) {weights_.assign(distribution_pntrs_.size(),1.0);}
+     191          12 :   if(distribution_pntrs_.size()!=weights_.size()) {
+     192           0 :     plumed_merror(getName()+ ": there has to be as many weights given in WEIGHTS as the number of target distribution labels given in DISTRIBUTIONS");
+     193             :   }
+     194             :   //
+     195             :   double sum_weights=0.0;
+     196          40 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     197          40 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     198          12 :   checkRead();
+     199          12 : }
+     200             : 
+     201             : 
+     202           0 : double TD_LinearCombination::getValue(const std::vector<double>& argument) const {
+     203           0 :   plumed_merror("getValue not implemented for TD_LinearCombination");
+     204             :   return 0.0;
+     205             : }
+     206             : 
+     207             : 
+     208          12 : void TD_LinearCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     209          40 :   for(unsigned int i=0; i<ndist_; i++) {
+     210          28 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     211          28 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     212           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     213             :     }
+     214          28 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     215             :   }
+     216          12 : }
+     217             : 
+     218             : 
+     219          22 : void TD_LinearCombination::updateGrid() {
+     220          70 :   for(unsigned int i=0; i<ndist_; i++) {
+     221          48 :     distribution_pntrs_[i]->updateTargetDist();
+     222             :   }
+     223      162033 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     224             :     double value = 0.0;
+     225      506837 :     for(unsigned int i=0; i<ndist_; i++) {
+     226      344826 :       value += weights_[i]*grid_pntrs_[i]->getValue(l);
+     227             :     }
+     228      162011 :     if(value==0.0) value=std::numeric_limits<double>::denorm_min();
+     229      162011 :     targetDistGrid().setValue(l,value);
+     230      162011 :     logTargetDistGrid().setValue(l,-std::log(value));
+     231             :   }
+     232          22 :   logTargetDistGrid().setMinToZero();
+     233          22 : }
+     234             : 
+     235             : 
+     236           1 : void TD_LinearCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     237           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     238           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     239           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     240             :   }
+     241           1 : }
+     242             : 
+     243             : 
+     244           0 : void TD_LinearCombination::linkAction(Action* action_pntr_in) {
+     245           0 :   TargetDistribution::linkAction(action_pntr_in);
+     246           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     247           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     248             :   }
+     249           0 : }
+     250             : 
+     251             : 
+     252           0 : void TD_LinearCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     253           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     254           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     255           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     256             :   }
+     257           0 : }
+     258             : 
+     259             : 
+     260           0 : void TD_LinearCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     261           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     262           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     263           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     264             :   }
+     265           0 : }
+     266             : 
+     267             : 
+     268           1 : void TD_LinearCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     269           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     270           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     271           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     272             :   }
+     273           1 : }
+     274             : 
+     275             : 
+     276             : }
+     277             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html new file mode 100644 index 0000000000..9391997fa9 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE4
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func.html b/coverage/ves/TD_Multicanonical.cpp.func.html new file mode 100644 index 0000000000..cacf931959 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe1606createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_130TD_MulticanonicalRegisterMe160D2Ev4168
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.gcov.html b/coverage/ves/TD_Multicanonical.cpp.gcov.html new file mode 100644 index 0000000000..336d4fd8b8 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.gcov.html @@ -0,0 +1,551 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19820596.6 %
Date:2024-05-27 13:05: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           4 :   ~TD_Multicanonical() {}
+     156             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     157             : };
+     158             : 
+     159             : 
+     160       12506 : PLUMED_REGISTER_ACTION(TD_Multicanonical,"TD_MULTICANONICAL")
+     161             : 
+     162             : 
+     163           4 : void TD_Multicanonical::registerKeywords(Keywords& keys) {
+     164           4 :   TargetDistribution::registerKeywords(keys);
+     165           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     166           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     167           8 :   keys.add("compulsory","MIN_TEMP","Minimum temperature.");
+     168           8 :   keys.add("compulsory","MAX_TEMP","Maximum temperature.");
+     169           8 :   keys.add("optional","STEPS_TEMP","Number of temperature steps. Only for the 2D version, i.e. energy and order parameter.");
+     170           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     171           4 : }
+     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          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     272          11 :         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          12 :         double argument = targetDistGrid().getPoint(l)[0];
+     286          12 :         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          13 :         double argument = targetDistGrid().getPoint(l)[0];
+     312          13 :         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          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     326          11 :         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      109242 :           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      109242 :           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        5202 :             double energy = targetDistGrid().getPoint(index)[0];
+     409        5202 :             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      519473 :                   double energy_prime = targetDistGrid().getPoint(index_prime)[0];
+     436      519473 :                   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.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html new file mode 100644 index 0000000000..1d88630cc7 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html new file mode 100644 index 0000000000..ba23a78a49 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe2326createERKNS_13ActionOptionsE2
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_138TD_MultithermalMultibaricRegisterMe232D2Ev4168
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html new file mode 100644 index 0000000000..1260769d3a --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html @@ -0,0 +1,534 @@ + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14815297.4 %
Date:2024-05-27 13:05: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           4 :   ~TD_MultithermalMultibaric() {}
+     228             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     229             : };
+     230             : 
+     231             : 
+     232       12506 : PLUMED_REGISTER_ACTION(TD_MultithermalMultibaric,"TD_MULTITHERMAL_MULTIBARIC")
+     233             : 
+     234             : 
+     235           4 : void TD_MultithermalMultibaric::registerKeywords(Keywords& keys) {
+     236           4 :   TargetDistribution::registerKeywords(keys);
+     237           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     238           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     239           8 :   keys.add("compulsory","MIN_TEMP","Minimum energy.");
+     240           8 :   keys.add("compulsory","MAX_TEMP","Maximum energy.");
+     241           8 :   keys.add("compulsory","MIN_PRESSURE","Minimum pressure.");
+     242           8 :   keys.add("compulsory","MAX_PRESSURE","Maximum pressure.");
+     243           8 :   keys.add("compulsory","PRESSURE","Target pressure of the barostat used in the MD engine.");
+     244           8 :   keys.add("compulsory","STEPS_TEMP","20","Number of temperature steps.");
+     245           8 :   keys.add("compulsory","STEPS_PRESSURE","20","Number of pressure steps.");
+     246           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     247           4 : }
+     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     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     347     5231142 :           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     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     357     5231142 :           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.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html new file mode 100644 index 0000000000..437878ef67 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func.html b/coverage/ves/TD_ProductCombination.cpp.func.html new file mode 100644 index 0000000000..0936b4ebc9 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe1406createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_134TD_ProductCombinationRegisterMe140D2Ev4168
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.gcov.html b/coverage/ves/TD_ProductCombination.cpp.gcov.html new file mode 100644 index 0000000000..6d05f88354 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + 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-05-27 13:05: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       12508 : PLUMED_REGISTER_ACTION(TD_ProductCombination,"TD_PRODUCT_COMBINATION")
+     141             : 
+     142             : 
+     143           6 : void TD_ProductCombination::registerKeywords(Keywords& keys) {
+     144           6 :   TargetDistribution::registerKeywords(keys);
+     145          12 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the product combination.");
+     146           6 :   keys.use("WELLTEMPERED_FACTOR");
+     147           6 :   keys.use("SHIFT_TO_ZERO");
+     148           6 : }
+     149             : 
+     150             : 
+     151           4 : TD_ProductCombination::TD_ProductCombination(const ActionOptions& ao):
+     152             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     153           8 :   distribution_pntrs_(0),
+     154           4 :   grid_pntrs_(0),
+     155           8 :   ndist_(0)
+     156             : {
+     157             :   std::vector<std::string> targetdist_labels;
+     158           4 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     159             : 
+     160           4 :   std::string error_msg = "";
+     161           8 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     162           4 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     163             : 
+     164          12 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     165           8 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     166           8 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     167           8 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     168             :   }
+     169             : 
+     170           4 :   ndist_ = distribution_pntrs_.size();
+     171           4 :   grid_pntrs_.assign(ndist_,NULL);
+     172           4 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     173           4 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     174             :   //
+     175           4 :   checkRead();
+     176           4 : }
+     177             : 
+     178             : 
+     179           0 : double TD_ProductCombination::getValue(const std::vector<double>& argument) const {
+     180           0 :   plumed_merror("getValue not implemented for TD_ProductCombination");
+     181             :   return 0.0;
+     182             : }
+     183             : 
+     184             : 
+     185           4 : void TD_ProductCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     186          12 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           8 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     188           8 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     189           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     190             :     }
+     191           8 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     192             :   }
+     193           4 : }
+     194             : 
+     195             : 
+     196          14 : void TD_ProductCombination::updateGrid() {
+     197          42 :   for(unsigned int i=0; i<ndist_; i++) {
+     198          28 :     distribution_pntrs_[i]->updateTargetDist();
+     199             :   }
+     200          28 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     201             :   double norm = 0.0;
+     202       11717 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     203             :     double value = 1.0;
+     204       35109 :     for(unsigned int i=0; i<ndist_; i++) {
+     205       23406 :       value *= grid_pntrs_[i]->getValue(l);
+     206             :     }
+     207       11703 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     208       11703 :     norm += integration_weights[l]*value;
+     209       11703 :     targetDistGrid().setValue(l,value);
+     210       11703 :     logTargetDistGrid().setValue(l,-std::log(value));
+     211             :   }
+     212             : 
+     213          14 :   if(norm>0.0) {
+     214          14 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     215             :   }
+     216           0 :   else if(!isTargetDistGridShiftedToZero()) {
+     217           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     218             :   }
+     219          14 :   logTargetDistGrid().setMinToZero();
+     220          14 : }
+     221             : 
+     222             : 
+     223           1 : void TD_ProductCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     224           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     225           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     226           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     227             :   }
+     228           1 : }
+     229             : 
+     230             : 
+     231           0 : void TD_ProductCombination::linkAction(Action* action_pntr_in) {
+     232           0 :   TargetDistribution::linkAction(action_pntr_in);
+     233           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     234           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     235             :   }
+     236           0 : }
+     237             : 
+     238             : 
+     239           0 : void TD_ProductCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     240           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     241           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     242           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     243             :   }
+     244           0 : }
+     245             : 
+     246             : 
+     247           0 : void TD_ProductCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     248           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     249           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     250           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     251             :   }
+     252           0 : }
+     253             : 
+     254             : 
+     255           1 : void TD_ProductCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     256           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     257           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     258           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     259             :   }
+     260           1 : }
+     261             : 
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html new file mode 100644 index 0000000000..dded6d9524 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE17
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func.html b/coverage/ves/TD_ProductDistribution.cpp.func.html new file mode 100644 index 0000000000..f37f989b7e --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05:14Functions:71353.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe1036createERKNS_13ActionOptionsE15
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_135TD_ProductDistributionRegisterMe103D2Ev4168
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.gcov.html b/coverage/ves/TD_ProductDistribution.cpp.gcov.html new file mode 100644 index 0000000000..4343f78bbe --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + 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-05-27 13:05: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       12519 : PLUMED_REGISTER_ACTION(TD_ProductDistribution,"TD_PRODUCT_DISTRIBUTION")
+     104             : 
+     105             : 
+     106          17 : void TD_ProductDistribution::registerKeywords(Keywords& keys) {
+     107          17 :   TargetDistribution::registerKeywords(keys);
+     108          34 :   keys.add("compulsory","DISTRIBUTIONS","Labels of the one-dimensional target distribution actions for each argument to be used in the product distribution. Note that order of the labels is important.");
+     109          17 :   keys.use("WELLTEMPERED_FACTOR");
+     110          17 :   keys.use("SHIFT_TO_ZERO");
+     111          17 :   keys.use("NORMALIZE");
+     112          17 : }
+     113             : 
+     114             : 
+     115          15 : TD_ProductDistribution::TD_ProductDistribution(const ActionOptions& ao):
+     116             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     117          30 :   distribution_pntrs_(0),
+     118          15 :   grid_pntrs_(0),
+     119          30 :   ndist_(0)
+     120             : {
+     121             :   std::vector<std::string> targetdist_labels;
+     122          15 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     123             : 
+     124          15 :   std::string error_msg = "";
+     125          30 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     126          15 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     127             : 
+     128          45 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     129          30 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     130          30 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     131          30 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     132             :   }
+     133             : 
+     134          15 :   ndist_ = distribution_pntrs_.size();
+     135          15 :   grid_pntrs_.assign(ndist_,NULL);
+     136          15 :   setDimension(ndist_);
+     137             : 
+     138          15 :   checkRead();
+     139          15 : }
+     140             : 
+     141             : 
+     142           0 : double TD_ProductDistribution::getValue(const std::vector<double>& argument) const {
+     143           0 :   plumed_merror("getValue not implemented for TD_ProductDistribution");
+     144             :   return 0.0;
+     145             : }
+     146             : 
+     147             : 
+     148          15 : void TD_ProductDistribution::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     149          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     150          30 :     std::vector<Value*> arg1d(1);
+     151          30 :     std::vector<std::string> min1d(1);
+     152          30 :     std::vector<std::string> max1d(1);
+     153          30 :     std::vector<unsigned int> nbins1d(1);
+     154          30 :     arg1d[0]=arguments[i];
+     155             :     min1d[0]=min[i];
+     156             :     max1d[0]=max[i];
+     157          30 :     nbins1d[0]=nbins[i];
+     158          30 :     distribution_pntrs_[i]->setupGrids(arg1d,min1d,max1d,nbins1d);
+     159          30 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     160          30 :     if(distribution_pntrs_[i]->getDimension()!=1 || grid_pntrs_[i]->getDimension()!=1) {
+     161           0 :       plumed_merror(getName() + ": all target distributions must be one dimensional");
+     162             :     }
+     163          30 :   }
+     164          15 : }
+     165             : 
+     166             : 
+     167          15 : void TD_ProductDistribution::updateGrid() {
+     168          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     169          30 :     distribution_pntrs_[i]->updateTargetDist();
+     170             :   }
+     171      153030 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     172      153015 :     std::vector<unsigned int> indices = targetDistGrid().getIndices(l);
+     173             :     double value = 1.0;
+     174      459045 :     for(unsigned int i=0; i<ndist_; i++) {
+     175      306030 :       value *= grid_pntrs_[i]->getValue(indices[i]);
+     176             :     }
+     177      153015 :     targetDistGrid().setValue(l,value);
+     178      153015 :     logTargetDistGrid().setValue(l,-std::log(value));
+     179             :   }
+     180          15 :   logTargetDistGrid().setMinToZero();
+     181          15 : }
+     182             : 
+     183             : 
+     184           0 : void TD_ProductDistribution::linkVesBias(VesBias* vesbias_pntr_in) {
+     185           0 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     186           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           0 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     188             :   }
+     189           0 : }
+     190             : 
+     191             : 
+     192           0 : void TD_ProductDistribution::linkAction(Action* action_pntr_in) {
+     193           0 :   TargetDistribution::linkAction(action_pntr_in);
+     194           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     195           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     196             :   }
+     197           0 : }
+     198             : 
+     199             : 
+     200           0 : void TD_ProductDistribution::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     201           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     202           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     203           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     204             :   }
+     205           0 : }
+     206             : 
+     207             : 
+     208           0 : void TD_ProductDistribution::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     209           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     210           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     211           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     212             :   }
+     213           0 : }
+     214             : 
+     215             : 
+     216           0 : void TD_ProductDistribution::linkFesGrid(Grid* fes_grid_pntr_in) {
+     217           0 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     218           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     219           0 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     220             :   }
+     221           0 : }
+     222             : 
+     223             : 
+     224             : }
+     225             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func-sort-c.html b/coverage/ves/TD_Uniform.cpp.func-sort-c.html new file mode 100644 index 0000000000..46304889a2 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE75
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194D2Ev4168
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func.html b/coverage/ves/TD_Uniform.cpp.func.html new file mode 100644 index 0000000000..d8468a5f90 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE75
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe1946createERKNS_13ActionOptionsE73
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_123TD_UniformRegisterMe194D2Ev4168
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.gcov.html b/coverage/ves/TD_Uniform.cpp.gcov.html new file mode 100644 index 0000000000..a46a78f095 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.gcov.html @@ -0,0 +1,381 @@ + + + + + + + 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-05-27 13:05: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       12577 : PLUMED_REGISTER_ACTION(TD_Uniform,"TD_UNIFORM")
+     195             : 
+     196             : 
+     197          75 : void TD_Uniform::registerKeywords(Keywords& keys) {
+     198          75 :   TargetDistribution::registerKeywords(keys);
+     199         150 :   keys.add("optional","MINIMA","The minimum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     200         150 :   keys.add("optional","MAXIMA","The maximum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     201         150 :   keys.add("optional","SIGMA_MINIMA","The standard deviation parameters of the Gaussian switching functions for the minima of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     202         150 :   keys.add("optional","SIGMA_MAXIMA","The standard deviation parameters of the Gaussian switching functions for the maximum of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     203          75 : }
+     204             : 
+     205             : 
+     206          73 : TD_Uniform::TD_Uniform(const ActionOptions& ao):
+     207             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     208         146 :   minima_(0),
+     209          73 :   maxima_(0),
+     210          73 :   sigma_min_(0),
+     211         146 :   sigma_max_(0)
+     212             : {
+     213          73 :   parseVector("MINIMA",minima_);
+     214          73 :   parseVector("MAXIMA",maxima_);
+     215             : 
+     216          73 :   parseVector("SIGMA_MINIMA",sigma_min_);
+     217         146 :   parseVector("SIGMA_MAXIMA",sigma_max_);
+     218          73 :   if(minima_.size()==0 && sigma_min_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MINIMA if MINIMA is not given");}
+     219          73 :   if(maxima_.size()==0 && sigma_max_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MAXIMA if MAXIMA is not given");}
+     220             : 
+     221          73 :   if(minima_.size()>0 && maxima_.size()>0) {
+     222             :     // both MINIMA and MAXIMA given, do all checks
+     223          58 :     if(minima_.size()!=maxima_.size()) {plumed_merror(getName()+": MINIMA and MAXIMA do not have the same number of values.");}
+     224          58 :     setDimension(minima_.size());
+     225         122 :     for(unsigned int k=0; k<getDimension(); k++) {
+     226          64 :       if(minima_[k]>maxima_[k]) {
+     227           0 :         plumed_merror(getName()+": error in MINIMA and MAXIMA keywords, one of the MINIMA values is larger than the corresponding MAXIMA values");
+     228             :       }
+     229             :     }
+     230             :   }
+     231          15 :   else if(minima_.size()>0 && maxima_.size()==0) {
+     232             :     // only MINIMA given, MAXIMA assigned later on.
+     233           1 :     setDimension(minima_.size());
+     234             :   }
+     235          14 :   else if(maxima_.size()>0 && minima_.size()==0) {
+     236             :     // only MAXIMA given, MINIMA assigned later on.
+     237           1 :     setDimension(maxima_.size());
+     238             :   }
+     239          13 :   else if(maxima_.size()==0 && minima_.size()==0) {
+     240             :     // neither MAXIMA nor MINIMA givenm, both assigned later on.
+     241          13 :     setDimension(0);
+     242             :   }
+     243             : 
+     244          73 :   if(sigma_min_.size()==0) {sigma_min_.assign(getDimension(),0.0);}
+     245          73 :   if(sigma_max_.size()==0) {sigma_max_.assign(getDimension(),0.0);}
+     246          73 :   if(sigma_min_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MINIMA has the wrong number of values");}
+     247          73 :   if(sigma_max_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MAXIMA has the wrong number of values");}
+     248             :   //
+     249             :   setForcedNormalization();
+     250          73 :   checkRead();
+     251          73 : }
+     252             : 
+     253             : 
+     254          73 : void TD_Uniform::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     255             : 
+     256          73 :   if(minima_.size()==0) {
+     257          14 :     minima_.assign(getDimension(),0.0);
+     258          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(min[k],minima_[k]);}
+     259             :   }
+     260             : 
+     261          73 :   if(maxima_.size()==0) {
+     262          14 :     maxima_.assign(getDimension(),0.0);
+     263          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(max[k],maxima_[k]);}
+     264             :   }
+     265             : 
+     266          73 : }
+     267             : 
+     268             : 
+     269      118654 : double TD_Uniform::getValue(const std::vector<double>& argument) const {
+     270             :   //
+     271             :   double value = 1.0;
+     272      338719 :   for(unsigned int k=0; k<getDimension(); k++) {
+     273             :     double tmp;
+     274      220065 :     if(argument[k] < minima_[k]) {
+     275       15379 :       tmp = GaussianSwitchingFunc(argument[k],minima_[k],sigma_min_[k]);
+     276             :     }
+     277      204686 :     else if(argument[k] > maxima_[k]) {
+     278       15566 :       tmp = GaussianSwitchingFunc(argument[k],maxima_[k],sigma_max_[k]);
+     279             :     }
+     280             :     else {
+     281             :       tmp = 1.0;
+     282             :     }
+     283      220065 :     value *= tmp;
+     284             :   }
+     285      118654 :   return value;
+     286             : }
+     287             : 
+     288             : inline
+     289             : double TD_Uniform::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     290       30945 :   if(sigma>0.0) {
+     291       23278 :     double arg=(argument-center)/sigma;
+     292       23278 :     return exp(-0.5*arg*arg);
+     293             :   }
+     294             :   else {
+     295             :     return 0.0;
+     296             :   }
+     297             : }
+     298             : 
+     299             : 
+     300             : 
+     301             : 
+     302             : 
+     303             : 
+     304             : }
+     305             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func-sort-c.html b/coverage/ves/TD_VonMises.cpp.func-sort-c.html new file mode 100644 index 0000000000..745f79019a --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE11
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112D2Ev4168
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func.html b/coverage/ves/TD_VonMises.cpp.func.html new file mode 100644 index 0000000000..82c3d05700 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe1126createERKNS_13ActionOptionsE9
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_124TD_VonMisesRegisterMe112D2Ev4168
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.gcov.html b/coverage/ves/TD_VonMises.cpp.gcov.html new file mode 100644 index 0000000000..3ea094f368 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + 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-05-27 13:05: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       12513 : PLUMED_REGISTER_ACTION(TD_VonMises,"TD_VONMISES")
+     113             : 
+     114             : 
+     115          11 : void TD_VonMises::registerKeywords(Keywords& keys) {
+     116          11 :   TargetDistribution::registerKeywords(keys);
+     117          22 :   keys.add("numbered","CENTER","The centers of the Von Mises distributions.");
+     118          22 :   keys.add("numbered","SIGMA","The standard deviations of the Von Mises distributions.");
+     119          22 :   keys.add("optional","WEIGHTS","The weights of the Von Mises distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     120          22 :   keys.add("hidden","PERIODS","The periods for each of the dimensions. By default they are 2*pi for each dimension.");
+     121          11 :   keys.use("WELLTEMPERED_FACTOR");
+     122          11 :   keys.use("SHIFT_TO_ZERO");
+     123             :   //keys.use("NORMALIZE");
+     124          11 : }
+     125             : 
+     126             : 
+     127           9 : TD_VonMises::TD_VonMises(const ActionOptions& ao):
+     128             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     129          18 :   sigmas_(0),
+     130           9 :   centers_(0),
+     131           9 :   normalization_(0),
+     132           9 :   weights_(0),
+     133           9 :   periods_(0),
+     134          18 :   ncenters_(0)
+     135             : {
+     136          13 :   for(unsigned int i=1;; i++) {
+     137             :     std::vector<double> tmp_center;
+     138          44 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     139          13 :     centers_.push_back(tmp_center);
+     140          13 :   }
+     141          13 :   for(unsigned int i=1;; i++) {
+     142             :     std::vector<double> tmp_sigma;
+     143          44 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     144          13 :     sigmas_.push_back(tmp_sigma);
+     145          13 :   }
+     146             :   //
+     147           9 :   plumed_massert(centers_.size()==sigmas_.size(),"there has to be an equal amount of CENTER and SIGMA keywords");
+     148           9 :   if(centers_.size()==0) {
+     149           0 :     plumed_merror(getName()+": CENTER and SIGMA keywords seem to be missing. Note that numbered keywords start at CENTER1 and SIGMA1.");
+     150             :   }
+     151             :   //
+     152           9 :   setDimension(centers_[0].size());
+     153           9 :   ncenters_ = centers_.size();
+     154             :   //
+     155             :   // check centers and sigmas
+     156          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     157          13 :     if(centers_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");}
+     158          13 :     if(sigmas_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");}
+     159             :   }
+     160             :   //
+     161           9 :   kappas_.resize(sigmas_.size());
+     162          22 :   for(unsigned int i=0; i<sigmas_.size(); i++) {
+     163          13 :     kappas_[i].resize(sigmas_[i].size());
+     164          32 :     for(unsigned int k=0; k<kappas_[i].size(); k++) {
+     165          19 :       kappas_[i][k] = 1.0/(sigmas_[i][k]*sigmas_[i][k]);
+     166             :     }
+     167             :   }
+     168             :   //
+     169          18 :   parseVector("WEIGHTS",weights_);
+     170           9 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     171           9 :   if(centers_.size()!=weights_.size()) {plumed_merror(getName() + ": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");}
+     172             :   //
+     173           9 :   if(periods_.size()==0) {periods_.assign(getDimension(),2*pi);}
+     174          18 :   parseVector("PERIODS",periods_);
+     175           9 :   if(periods_.size()!=getDimension()) {plumed_merror(getName() + ": the number of values given in PERIODS does not match the dimension of the distribution");}
+     176             :   //
+     177             :   double sum_weights=0.0;
+     178          22 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     179          22 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     180             :   //
+     181           9 :   normalization_.resize(ncenters_);
+     182          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     183          13 :     normalization_[i].resize(getDimension());
+     184          32 :     for(unsigned int k=0; k<getDimension(); k++) {
+     185          19 :       normalization_[i][k] = getNormalization(kappas_[i][k],periods_[k]);
+     186             :     }
+     187             :   }
+     188           9 :   checkRead();
+     189           9 : }
+     190             : 
+     191             : 
+     192       31100 : double TD_VonMises::getValue(const std::vector<double>& argument) const {
+     193             :   double value=0.0;
+     194       92400 :   for(unsigned int i=0; i<ncenters_; i++) {
+     195       61300 :     value+=weights_[i]*VonMisesDiagonal(argument, centers_[i], kappas_[i],periods_,normalization_[i]);
+     196             :   }
+     197       31100 :   return value;
+     198             : }
+     199             : 
+     200             : 
+     201       80319 : double TD_VonMises::VonMisesDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& kappa, const std::vector<double>& periods, const std::vector<double>& normalization) const {
+     202             :   double value = 1.0;
+     203      220638 :   for(unsigned int k=0; k<argument.size(); k++) {
+     204      140319 :     double arg = kappa[k]*cos( ((2*pi)/periods[k])*(argument[k]-center[k]) );
+     205      140319 :     value*=normalization[k]*exp(arg);
+     206             :   }
+     207       80319 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211          19 : double TD_VonMises::getNormalization(const double kappa, const double period) const {
+     212             :   //
+     213          19 :   std::vector<double> centers(1);
+     214          19 :   centers[0] = 0.0;
+     215          19 :   std::vector<double> kappas(1);
+     216          19 :   kappas[0] = kappa;
+     217          19 :   std::vector<double> periods(1);
+     218          19 :   periods[0] = period;
+     219          19 :   std::vector<double> norm(1);
+     220          19 :   norm[0] = 1.0;
+     221             :   //
+     222             :   const unsigned int nbins = 1001;
+     223             :   std::vector<double> points;
+     224             :   std::vector<double> weights;
+     225             :   double min = 0.0;
+     226             :   double max = period;
+     227          19 :   GridIntegrationWeights::getOneDimensionalIntegrationPointsAndWeights(points,weights,nbins,min,max);
+     228             :   //
+     229             :   double sum = 0.0;
+     230       19038 :   for(unsigned int l=0; l<nbins; l++) {
+     231       19019 :     std::vector<double> arg(1); arg[0]= points[l];
+     232       19019 :     sum += weights[l] * VonMisesDiagonal(arg,centers,kappas,periods,norm);
+     233             :   }
+     234          38 :   return 1.0/sum;
+     235             : }
+     236             : 
+     237             : 
+     238             : }
+     239             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func-sort-c.html b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html new file mode 100644 index 0000000000..e827dd7729 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE31
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113D2Ev4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func.html b/coverage/ves/TD_WellTempered.cpp.func.html new file mode 100644 index 0000000000..e71a4ea9de --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe1136createERKNS_13ActionOptionsE29
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_128TD_WellTemperedRegisterMe113D2Ev4168
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.gcov.html b/coverage/ves/TD_WellTempered.cpp.gcov.html new file mode 100644 index 0000000000..ae82d47e9d --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.gcov.html @@ -0,0 +1,240 @@ + + + + + + + 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-05-27 13:05: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       12533 : PLUMED_REGISTER_ACTION(TD_WellTempered,"TD_WELLTEMPERED")
+     114             : 
+     115             : 
+     116          31 : void TD_WellTempered::registerKeywords(Keywords& keys) {
+     117          31 :   TargetDistribution::registerKeywords(keys);
+     118          62 :   keys.add("compulsory","BIASFACTOR","The bias factor used for the well-tempered distribution.");
+     119          31 : }
+     120             : 
+     121             : 
+     122          29 : TD_WellTempered::TD_WellTempered(const ActionOptions& ao):
+     123             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     124          29 :   bias_factor_(0.0)
+     125             : {
+     126          29 :   log.printf("  Well-tempered target distribution, see and cite ");
+     127          58 :   log << plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     128          58 :   log << plumed.cite("Barducci, Bussi, and Parrinello, Phys. Rev. Lett. 100, 020603 (2008)");
+     129          29 :   log.printf("\n");
+     130          29 :   parse("BIASFACTOR",bias_factor_);
+     131          29 :   if(bias_factor_<=1.0) {
+     132           0 :     plumed_merror("TD_WELLTEMPERED target distribution: the value of the bias factor doesn't make sense, it should be larger than 1.0");
+     133             :   }
+     134             :   setDynamic();
+     135             :   setFesGridNeeded();
+     136          29 :   checkRead();
+     137          29 : }
+     138             : 
+     139             : 
+     140           0 : double TD_WellTempered::getValue(const std::vector<double>& argument) const {
+     141           0 :   plumed_merror("getValue not implemented for TD_WellTempered");
+     142             :   return 0.0;
+     143             : }
+     144             : 
+     145             : 
+     146         319 : void TD_WellTempered::updateGrid() {
+     147         319 :   double beta_prime = getBeta()/bias_factor_;
+     148         319 :   plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_WellTempered!");
+     149         638 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     150             :   double norm = 0.0;
+     151     1127896 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     152     1127577 :     double value = beta_prime * getFesGridPntr()->getValue(l);
+     153     1127577 :     logTargetDistGrid().setValue(l,value);
+     154     1127577 :     value = exp(-value);
+     155     1127577 :     norm += integration_weights[l]*value;
+     156     1127577 :     targetDistGrid().setValue(l,value);
+     157             :   }
+     158         319 :   targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     159         319 :   logTargetDistGrid().setMinToZero();
+     160         319 : }
+     161             : 
+     162             : 
+     163             : }
+     164             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func-sort-c.html b/coverage/ves/TargetDistModifer.h.func-sort-c.html new file mode 100644 index 0000000000..cba9e4c88e --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func.html b/coverage/ves/TargetDistModifer.h.func.html new file mode 100644 index 0000000000..dc28eb16c9 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.gcov.html b/coverage/ves/TargetDistModifer.h.gcov.html new file mode 100644 index 0000000000..430127ef57 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func-sort-c.html b/coverage/ves/TargetDistribution.cpp.func-sort-c.html new file mode 100644 index 0000000000..d3a616e305 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func.html b/coverage/ves/TargetDistribution.cpp.func.html new file mode 100644 index 0000000000..ed8358d053 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func.html @@ -0,0 +1,176 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution22clearLogTargetDistGridEv1
_ZN4PLMD3ves18TargetDistribution23updateLogTargetDistGridEv29
_ZN4PLMD3ves18TargetDistribution25linkBiasWithoutCutoffGridEPNS_4GridE3
_ZN4PLMD3ves18TargetDistribution27getMarginalDistributionGridEPNS_4GridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE28
_ZN4PLMD3ves18TargetDistribution27readInRestartTargetDistGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves18TargetDistribution28applyTargetDistModiferToGridEPNS0_17TargetDistModiferE6
_ZN4PLMD3ves18TargetDistribution31calculateStaticDistributionGridEv368
_ZN4PLMD3ves18TargetDistribution32setMinimumOfTargetDistGridToZeroEv3
_ZN4PLMD3ves18TargetDistribution33updateBiasCutoffForTargetDistGridEv24
_ZN4PLMD3ves18TargetDistributionC2ERKNS_13ActionOptionsE407
_ZN4PLMD3ves18TargetDistributionD0Ev0
_ZN4PLMD3ves18TargetDistributionD2Ev407
_ZNK4PLMD3ves18TargetDistribution7getBetaEv377
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.gcov.html b/coverage/ves/TargetDistribution.cpp.gcov.html new file mode 100644 index 0000000000..4db90c7dd0 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.gcov.html @@ -0,0 +1,464 @@ + + + + + + + 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-05-27 13:05: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         441 : void TargetDistribution::registerKeywords( Keywords& keys ) {
+      41         441 :   Action::registerKeywords(keys);
+      42         882 :   keys.reserve("optional","WELLTEMPERED_FACTOR","Broaden the target distribution such that it is taken as [p(s)]^(1/gamma) where gamma is the well tempered factor given here. If this option is active the distribution will be automatically normalized.");
+      43         882 :   keys.reserveFlag("SHIFT_TO_ZERO",false,"Shift the minimum value of the target distribution to zero. This can for example be used to avoid negative values in the target distribution. If this option is active the distribution will be automatically normalized.");
+      44         882 :   keys.reserveFlag("NORMALIZE",false,"Renormalized the target distribution over the intervals on which it is defined to make sure that it is properly normalized to 1. In most cases this should not be needed as the target distributions should be normalized. The code will issue a warning (but still run) if this is needed for some reason.");
+      45         441 : }
+      46             : 
+      47             : 
+      48         407 : TargetDistribution::TargetDistribution(const ActionOptions&ao):
+      49             :   Action(ao),
+      50         407 :   type_(static_targetdist),
+      51         407 :   force_normalization_(false),
+      52         407 :   check_normalization_(true),
+      53         407 :   check_nonnegative_(true),
+      54         407 :   check_nan_inf_(false),
+      55         407 :   shift_targetdist_to_zero_(false),
+      56         407 :   dimension_(0),
+      57         814 :   grid_args_(0),
+      58         407 :   action_pntr_(NULL),
+      59         407 :   vesbias_pntr_(NULL),
+      60         407 :   needs_bias_grid_(false),
+      61         407 :   needs_bias_withoutcutoff_grid_(false),
+      62         407 :   needs_fes_grid_(false),
+      63         407 :   bias_grid_pntr_(NULL),
+      64         407 :   bias_withoutcutoff_grid_pntr_(NULL),
+      65         407 :   fes_grid_pntr_(NULL),
+      66         407 :   static_grid_calculated(false),
+      67         407 :   allow_bias_cutoff_(true),
+      68         407 :   bias_cutoff_active_(false)
+      69             : {
+      70             :   //
+      71         814 :   if(keywords.exists("WELLTEMPERED_FACTOR")) {
+      72         301 :     double welltempered_factor=0.0;
+      73         301 :     parse("WELLTEMPERED_FACTOR",welltempered_factor);
+      74             :     //
+      75         301 :     if(welltempered_factor>0.0) {
+      76           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          28 :     intVol/=grid_pntr->getDx()[args_index[l]];
+     233             :   }
+     234          28 :   proj_grid.scaleAllValuesAndDerivatives(intVol);
+     235             :   //
+     236          28 :   return proj_grid;
+     237          56 : }
+     238             : 
+     239             : 
+     240           8 : Grid TargetDistribution::getMarginal(const std::vector<std::string>& args) {
+     241           8 :   return TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_.get(),args);
+     242             : }
+     243             : 
+     244             : 
+     245         802 : void TargetDistribution::updateTargetDist() {
+     246             :   //
+     247         802 :   updateGrid();
+     248             :   //
+     249         808 :   for(unsigned int i=0; i<targetdist_modifer_pntrs_.size(); i++) {
+     250           6 :     applyTargetDistModiferToGrid(targetdist_modifer_pntrs_[i].get());
+     251             :   }
+     252             :   //
+     253         802 :   if(bias_cutoff_active_) {updateBiasCutoffForTargetDistGrid();}
+     254             :   //
+     255         802 :   if(shift_targetdist_to_zero_ && !(bias_cutoff_active_)) {setMinimumOfTargetDistGridToZero();}
+     256         802 :   if(force_normalization_ && !(bias_cutoff_active_) ) {normalizeTargetDistGrid();}
+     257             :   //
+     258             :   // if(check_normalization_ && !force_normalization_ && !shift_targetdist_to_zero_){
+     259         802 :   if(check_normalization_ && !(bias_cutoff_active_)) {
+     260         691 :     double normalization = integrateGrid(targetdist_grid_pntr_.get());
+     261             :     const double normalization_thrshold = 0.1;
+     262         691 :     if(normalization < 1.0-normalization_thrshold || normalization > 1.0+normalization_thrshold) {
+     263           9 :       std::string norm_str; Tools::convert(normalization,norm_str);
+     264           9 :       std::string msg = "the target distribution grid is not proberly normalized, integrating over the grid gives: " + norm_str + " - You can avoid this problem by using the NORMALIZE keyword";
+     265           9 :       warning(msg);
+     266             :     }
+     267             :   }
+     268             :   //
+     269         802 :   if(check_nonnegative_) {
+     270             :     const double nonnegative_thrshold = -0.02;
+     271         799 :     double grid_min_value = targetdist_grid_pntr_->getMinValue();
+     272         799 :     if(grid_min_value<nonnegative_thrshold) {
+     273           0 :       std::string grid_min_value_str; Tools::convert(grid_min_value,grid_min_value_str);
+     274           0 :       std::string msg = "the target distribution grid has negative values, the lowest value is: " + grid_min_value_str + " - You can avoid this problem by using the SHIFT_TO_ZERO keyword";
+     275           0 :       warning(msg);
+     276             :     }
+     277             :   }
+     278             :   //
+     279         802 :   if(check_nan_inf_) {checkNanAndInf();}
+     280             :   //
+     281         802 : }
+     282             : 
+     283             : 
+     284          24 : void TargetDistribution::updateBiasCutoffForTargetDistGrid() {
+     285          24 :   plumed_massert(vesbias_pntr_!=NULL,"The VesBias has to be linked to use updateBiasCutoffForTargetDistGrid()");
+     286          24 :   plumed_massert(vesbias_pntr_->biasCutoffActive(),"updateBiasCutoffForTargetDistGrid() should only be used if the bias cutoff is active");
+     287             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     288             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     289          24 :   plumed_massert(getBiasWithoutCutoffGridPntr()!=NULL,"the bias without cutoff grid has to be linked");
+     290             :   //
+     291          48 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     292             :   double norm = 0.0;
+     293        2624 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     294             :   {
+     295        2600 :     double value = targetdist_grid_pntr_->getValue(l);
+     296        2600 :     double bias = getBiasWithoutCutoffGridPntr()->getValue(l);
+     297        2600 :     double deriv_factor_swf = 0.0;
+     298        2600 :     double swf = vesbias_pntr_->getBiasCutoffSwitchingFunction(bias,deriv_factor_swf);
+     299             :     // this comes from the p(s)
+     300        2600 :     value *= swf;
+     301        2600 :     norm += integration_weights[l]*value;
+     302             :     // this comes from the derivative of V(s)
+     303        2600 :     value *= deriv_factor_swf;
+     304        2600 :     targetdist_grid_pntr_->setValue(l,value);
+     305             :     // double log_value = log_targetdist_grid_pntr_->getValue(l) - std::log(swf);
+     306             :     // log_targetdist_grid_pntr_->setValue(l,log_value);
+     307             :   }
+     308          24 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     309             :   // log_targetdist_grid_pntr_->setMinToZero();
+     310          24 : }
+     311             : 
+     312           6 : void TargetDistribution::applyTargetDistModiferToGrid(TargetDistModifer* modifer_pntr) {
+     313             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     314             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     315             :   //
+     316          12 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     317             :   double norm = 0.0;
+     318       21212 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     319             :   {
+     320       21206 :     double value = targetdist_grid_pntr_->getValue(l);
+     321       21206 :     std::vector<double> cv_values = targetdist_grid_pntr_->getPoint(l);
+     322       21206 :     value = modifer_pntr->getModifedTargetDistValue(value,cv_values);
+     323       21206 :     norm += integration_weights[l]*value;
+     324       21206 :     targetdist_grid_pntr_->setValue(l,value);
+     325       21206 :     log_targetdist_grid_pntr_->setValue(l,-std::log(value));
+     326             :   }
+     327           6 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     328           6 :   log_targetdist_grid_pntr_->setMinToZero();
+     329           6 : }
+     330             : 
+     331             : 
+     332          29 : void TargetDistribution::updateLogTargetDistGrid() {
+     333       44070 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     334             :   {
+     335       44041 :     log_targetdist_grid_pntr_->setValue(l,-std::log(targetdist_grid_pntr_->getValue(l)));
+     336             :   }
+     337          29 :   log_targetdist_grid_pntr_->setMinToZero();
+     338          29 : }
+     339             : 
+     340             : 
+     341           3 : void TargetDistribution::setMinimumOfTargetDistGridToZero() {
+     342           3 :   targetDistGrid().setMinToZero();
+     343           3 :   normalizeTargetDistGrid();
+     344           3 :   updateLogTargetDistGrid();
+     345           3 : }
+     346             : 
+     347             : 
+     348           8 : void TargetDistribution::readInRestartTargetDistGrid(const std::string& grid_fname) {
+     349           8 :   plumed_massert(isDynamic(),"this should only be used for dynamically updated target distributions!");
+     350           8 :   IFile gridfile;
+     351           8 :   if(!gridfile.FileExist(grid_fname)) {
+     352           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, cannot find file " + grid_fname);
+     353             :   }
+     354           8 :   gridfile.open(grid_fname);
+     355          16 :   std::unique_ptr<GridBase> restart_grid = GridBase::create("targetdist",grid_args_,gridfile,false,false,false);
+     356           8 :   if(restart_grid->getSize()!=targetdist_grid_pntr_->getSize()) {
+     357           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, the grid is not of the correct size!");
+     358             :   }
+     359           8 :   VesTools::copyGridValues(restart_grid.get(),targetdist_grid_pntr_.get());
+     360           8 :   updateLogTargetDistGrid();
+     361           8 : }
+     362             : 
+     363           1 : void TargetDistribution::clearLogTargetDistGrid() {
+     364           1 :   log_targetdist_grid_pntr_->clear();
+     365           1 : }
+     366             : 
+     367             : 
+     368           0 : void TargetDistribution::checkNanAndInf() {
+     369           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     370             :   {
+     371           0 :     double value = targetdist_grid_pntr_->getValue(l);
+     372           0 :     if(std::isnan(value) || std::isinf(value)) {
+     373           0 :       std::string vs; Tools::convert(value,vs);
+     374           0 :       std::vector<double> p = targetdist_grid_pntr_->getPoint(l);
+     375           0 :       std::string ps; Tools::convert(p[0],ps);
+     376           0 :       ps = "(" + ps;
+     377           0 :       for(unsigned int k=1; k<p.size(); k++) {
+     378           0 :         std::string t1; Tools::convert(p[k],t1);
+     379           0 :         ps = ps + "," + t1;
+     380             :       }
+     381           0 :       ps = ps + ")";
+     382           0 :       plumed_merror(getName()+": problem with target distribution, the value at " + ps + " is " + vs);
+     383             :     }
+     384             :   }
+     385           0 : }
+     386             : 
+     387             : }
+     388             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func-sort-c.html b/coverage/ves/TargetDistribution.h.func-sort-c.html new file mode 100644 index 0000000000..8f261e5158 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func.html b/coverage/ves/TargetDistribution.h.func.html new file mode 100644 index 0000000000..f8531487e8 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.gcov.html b/coverage/ves/TargetDistribution.h.gcov.html new file mode 100644 index 0000000000..1861bb1f28 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.gcov.html @@ -0,0 +1,285 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func-sort-c.html b/coverage/ves/VesBias.cpp.func-sort-c.html new file mode 100644 index 0000000000..c22bff026f --- /dev/null +++ b/coverage/ves/VesBias.cpp.func-sort-c.html @@ -0,0 +1,252 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func.html b/coverage/ves/VesBias.cpp.func.html new file mode 100644 index 0000000000..7358e37fa6 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func.html @@ -0,0 +1,252 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias37useMultipleTargetDistributionKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZN4PLMD3ves7VesBiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves7VesBiasC2ERKNS_13ActionOptionsE90
_ZN4PLMD3ves7VesBiasD0Ev0
_ZN4PLMD3ves7VesBiasD1Ev0
_ZN4PLMD3ves7VesBiasD2Ev90
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias23calculateReweightFactorEv0
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias26getCoeffsSetFilenameSuffixB5cxx11Ej0
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.gcov.html b/coverage/ves/VesBias.cpp.gcov.html new file mode 100644 index 0000000000..26a940d368 --- /dev/null +++ b/coverage/ves/VesBias.cpp.gcov.html @@ -0,0 +1,837 @@ + + + + + + + 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-05-27 13:05: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         270 :   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          92 : void VesBias::registerKeywords( Keywords& keys ) {
+     242          92 :   Bias::registerKeywords(keys);
+     243         184 :   keys.add("optional","TEMP","the system temperature - this is needed if the MD code does not pass the temperature to PLUMED.");
+     244             :   //
+     245         184 :   keys.reserve("optional","COEFFS","read in the coefficients from files.");
+     246             :   //
+     247         184 :   keys.reserve("optional","TARGET_DISTRIBUTION","the label of the target distribution to be used.");
+     248         184 :   keys.reserve("optional","TARGET_DISTRIBUTIONS","the label of the target distribution to be used. Here you are allows to use multiple labels.");
+     249             :   //
+     250         184 :   keys.reserve("optional","GRID_BINS","the number of bins used for the grid. The default value is 100 bins per dimension.");
+     251         184 :   keys.reserve("optional","GRID_MIN","the lower bounds used for the grid.");
+     252         184 :   keys.reserve("optional","GRID_MAX","the upper bounds used for the grid.");
+     253             :   //
+     254         184 :   keys.add("optional","BIAS_FILE","filename of the file on which the bias should be written out. By default it is bias.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     255         184 :   keys.add("optional","FES_FILE","filename of the file on which the FES should be written out. By default it is fes.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     256         184 :   keys.add("optional","TARGETDIST_FILE","filename of the file on which the target distribution should be written out. By default it is targetdist.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients and the target distribution is dynamic.");
+     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         184 :   keys.reserve("optional","BIAS_CUTOFF","cutoff the bias such that it only fills the free energy surface up to certain level F_cutoff, here you should give the value of the F_cutoff.");
+     264         184 :   keys.reserve("optional","BIAS_CUTOFF_FERMI_LAMBDA","the lambda value used in the Fermi switching function for the bias cutoff (BIAS_CUTOFF), the default value is 10.0.");
+     265             :   //
+     266         184 :   keys.reserve("numbered","PROJ_ARG","arguments for doing projections of the FES or the target distribution.");
+     267             :   //
+     268         184 :   keys.reserveFlag("CALC_REWEIGHT_FACTOR",false,"enable the calculation of the reweight factor c(t). You should also give a stride for updating the reweight factor in the optimizer by using the REWEIGHT_FACTOR_STRIDE keyword if the coefficients are updated.");
+     269         184 :   keys.add("optional","OPTIMIZATION_THRESHOLD","Threshold value to turn off optimization of localized basis functions.");
+     270             : 
+     271          92 : }
+     272             : 
+     273             : 
+     274          92 : void VesBias::useInitialCoeffsKeywords(Keywords& keys) {
+     275          92 :   keys.use("COEFFS");
+     276          92 : }
+     277             : 
+     278             : 
+     279          92 : void VesBias::useTargetDistributionKeywords(Keywords& keys) {
+     280         184 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTIONS"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     281          92 :   keys.use("TARGET_DISTRIBUTION");
+     282          92 : }
+     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          92 : void VesBias::useGridBinKeywords(Keywords& keys) {
+     292          92 :   keys.use("GRID_BINS");
+     293          92 : }
+     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          92 : void VesBias::useBiasCutoffKeywords(Keywords& keys) {
+     303          92 :   keys.use("BIAS_CUTOFF");
+     304          92 :   keys.use("BIAS_CUTOFF_FERMI_LAMBDA");
+     305          92 : }
+     306             : 
+     307             : 
+     308          92 : void VesBias::useProjectionArgKeywords(Keywords& keys) {
+     309          92 :   keys.use("PROJ_ARG");
+     310          92 : }
+     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         180 :   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         113 :     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.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func-sort-c.html b/coverage/ves/VesBias.h.func-sort-c.html new file mode 100644 index 0000000000..7dad9db32a --- /dev/null +++ b/coverage/ves/VesBias.h.func-sort-c.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func.html b/coverage/ves/VesBias.h.func.html new file mode 100644 index 0000000000..0973f47ce6 --- /dev/null +++ b/coverage/ves/VesBias.h.func.html @@ -0,0 +1,172 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesBias.h.gcov.html b/coverage/ves/VesBias.h.gcov.html new file mode 100644 index 0000000000..3ba1a17bcd --- /dev/null +++ b/coverage/ves/VesBias.h.gcov.html @@ -0,0 +1,491 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func-sort-c.html b/coverage/ves/VesDeltaF.cpp.func-sort-c.html new file mode 100644 index 0000000000..7e94b0b189 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe1806createERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe180C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe180D2Ev4168
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func.html b/coverage/ves/VesDeltaF.cpp.func.html new file mode 100644 index 0000000000..be951d3ffa --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe1806createERKNS_13ActionOptionsE4
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe180C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_122VesDeltaFRegisterMe180D2Ev4168
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.gcov.html b/coverage/ves/VesDeltaF.cpp.gcov.html new file mode 100644 index 0000000000..02a25c31b1 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.gcov.html @@ -0,0 +1,797 @@ + + + + + + + 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-05-27 13:05: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 Delta F method
+      38             : 
+      39             : Implementation of VES\f$\Delta F\f$ method \cite Invernizzi2019vesdeltaf (step two only).
+      40             : 
+      41             : \warning
+      42             :   Notice that this is a stand-alone bias Action, it does not need any of the other VES module components
+      43             : 
+      44             : First you should create some estimate of the local free energy basins of your system,
+      45             : using e.g. multiple \ref METAD short runs, and combining them with the \ref sum_hills utility.
+      46             : Once you have them, you can use this bias Action to perform the VES optimization part of the method.
+      47             : 
+      48             : These \f$N+1\f$ local basins are used to model the global free energy.
+      49             : In particular, given the conditional probabilities \f$P(\mathbf{s}|i)\propto e^{-\beta F_i(\mathbf{s})}\f$
+      50             : and the probabilities of being in a given basin \f$P_i\f$, we can write:
+      51             : \f[
+      52             :   e^{-\beta F(\mathbf{s})}\propto P(\mathbf{s})=\sum_{i=0}^N P(\mathbf{s}|i)P_i \, .
+      53             : \f]
+      54             : We use this free energy model and the chosen bias factor \f$\gamma\f$ to build the bias potential:
+      55             : \f$V(\mathbf{s})=-(1-1/\gamma)F(\mathbf{s})\f$.
+      56             : Or, more explicitly:
+      57             : \f[
+      58             :   V(\mathbf{s})=(1-1/\gamma)\frac{1}{\beta}\log\left[e^{-\beta F_0(\mathbf{s})}
+      59             :   +\sum_{i=1}^{N} e^{-\beta F_i(\mathbf{s})} e^{-\beta \alpha_i}\right] \, ,
+      60             : \f]
+      61             : where the parameters \f$\boldsymbol{\alpha}\f$ are the \f$N\f$ free energy differences (see below) from the \f$F_0\f$ basin.
+      62             : 
+      63             : 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$.
+      64             : In this case the optimization parameters \f$\alpha_i\f$ are the difference in height between the minima of the basins.
+      65             : Using the keyword `NORMALIZE`, you can also decide to normalize the local free energies so that
+      66             : \f$\int d\mathbf{s}\, e^{-\beta F_i(\mathbf{s})}=1\f$.
+      67             : In this case the parameters will represent not the difference in height (which depends on the chosen CVs),
+      68             : but the actual free energy difference, \f$\alpha_i=\Delta F_i\f$.
+      69             : 
+      70             : However, as discussed in Ref. \cite Invernizzi2019vesdeltaf, a better estimate of \f$\Delta F_i\f$ should be obtained through the reweighting procedure.
+      71             : 
+      72             : \par Examples
+      73             : 
+      74             : The following performs the optimization of the free energy difference between two metastable basins:
+      75             : 
+      76             : \plumedfile
+      77             : cv: DISTANCE ATOMS=1,2
+      78             : ves: VES_DELTA_F ...
+      79             :   ARG=cv
+      80             :   TEMP=300
+      81             :   FILE_F0=fesA.data
+      82             :   FILE_F1=fesB.data
+      83             :   BIASFACTOR=10.0
+      84             :   M_STEP=0.1
+      85             :   AV_STRIDE=500
+      86             :   PRINT_STRIDE=100
+      87             : ...
+      88             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=cv,ves.bias,ves.rct
+      89             : \endplumedfile
+      90             : 
+      91             : The local FES files can be obtained as described in Sec. 4.2 of Ref. \cite Invernizzi2019vesdeltaf, i.e. for example:
+      92             : - 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)
+      93             : - \verbatim cat HILLS* > all_HILLS \endverbatim
+      94             : - \verbatim plumed sum_hills --hills all_HILLS --outfile all_fesA.dat --mintozero --min 0 --max 1 --bin 100 \endverbatim
+      95             : - \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
+      96             : 
+      97             : The header of both FES files must be identical, and should be similar to the following:
+      98             : 
+      99             : \auxfile{fesA.data}
+     100             : #! FIELDS cv file.free der_cv
+     101             : #! SET min_cv 0
+     102             : #! SET max_cv 1
+     103             : #! SET nbins_cv  100
+     104             : #! SET periodic_cv false
+     105             : 0 0 0
+     106             : \endauxfile
+     107             : \auxfile{fesB.data}
+     108             : #! FIELDS cv file.free der_cv
+     109             : #! SET min_cv 0
+     110             : #! SET max_cv 1
+     111             : #! SET nbins_cv  100
+     112             : #! SET periodic_cv false
+     113             : 0 0 0
+     114             : \endauxfile
+     115             : 
+     116             : */
+     117             : //+ENDPLUMEDOC
+     118             : 
+     119             : class VesDeltaF : public bias::Bias {
+     120             : 
+     121             : private:
+     122             :   double beta_;
+     123             :   unsigned NumParallel_;
+     124             :   unsigned rank_;
+     125             :   unsigned NumWalkers_;
+     126             :   bool isFirstStep_;
+     127             :   bool afterCalculate_;
+     128             : 
+     129             : //prob
+     130             :   double tot_prob_;
+     131             :   std::vector<double> prob_;
+     132             :   std::vector< std::vector<double> > der_prob_;
+     133             : 
+     134             : //local basins
+     135             :   std::vector< std::unique_ptr<Grid> > grid_p_; //pointers because of GridBase::create
+     136             :   std::vector<double> norm_;
+     137             : 
+     138             : //optimizer-related stuff
+     139             :   long long unsigned mean_counter_;
+     140             :   unsigned mean_weight_tau_;
+     141             :   unsigned alpha_size_;
+     142             :   unsigned sym_alpha_size_;
+     143             :   std::vector<double> mean_alpha_;
+     144             :   std::vector<double> inst_alpha_;
+     145             :   std::vector<double> past_increment2_;
+     146             :   double minimization_step_;
+     147             :   bool damping_off_;
+     148             : //'tg' -> 'target distribution'
+     149             :   double inv_gamma_;
+     150             :   unsigned tg_counter_;
+     151             :   unsigned tg_stride_;
+     152             :   std::vector<double> tg_dV_dAlpha_;
+     153             :   std::vector<double> tg_d2V_dAlpha2_;
+     154             : //'av' -> 'ensemble average'
+     155             :   unsigned av_counter_;
+     156             :   unsigned av_stride_;
+     157             :   std::vector<double> av_dV_dAlpha_;
+     158             :   std::vector<double> av_dV_dAlpha_prod_;
+     159             :   std::vector<double> av_d2V_dAlpha2_;
+     160             : //printing
+     161             :   unsigned print_stride_;
+     162             :   OFile alphaOfile_;
+     163             : //other
+     164             :   std::vector<double> exp_alpha_;
+     165             :   std::vector<double> prev_exp_alpha_;
+     166             :   double work_;
+     167             : 
+     168             : //functions
+     169             :   void update_alpha();
+     170             :   void update_tg_and_rct();
+     171             :   inline unsigned get_index(const unsigned, const unsigned) const;
+     172             : 
+     173             : public:
+     174             :   explicit VesDeltaF(const ActionOptions&);
+     175             :   void calculate() override;
+     176             :   void update() override;
+     177             :   static void registerKeywords(Keywords& keys);
+     178             : };
+     179             : 
+     180       12512 : PLUMED_REGISTER_ACTION(VesDeltaF,"VES_DELTA_F")
+     181             : 
+     182           6 : void VesDeltaF::registerKeywords(Keywords& keys) {
+     183           6 :   Bias::registerKeywords(keys);
+     184           6 :   keys.use("ARG");
+     185          12 :   keys.add("optional","TEMP","temperature is compulsory, but it can be sometimes fetched from the MD engine");
+     186             : //local free energies
+     187          12 :   keys.add("numbered","FILE_F","names of files containing local free energies and derivatives. "
+     188             :            "The first one, FILE_F0, is used as reference for all the free energy differences.");
+     189          12 :   keys.reset_style("FILE_F","compulsory");
+     190          12 :   keys.addFlag("NORMALIZE",false,"normalize all local free energies so that alpha will be (approx) Delta F");
+     191          12 :   keys.addFlag("NO_MINTOZERO",false,"leave local free energies as provided, without shifting them to zero min");
+     192             : //target distribution
+     193          12 :   keys.add("compulsory","BIASFACTOR","0","the gamma bias factor used for well-tempered target p(s)."
+     194             :            " Set to 0 for non-tempered flat target");
+     195          12 :   keys.add("optional","TG_STRIDE","( default=1 ) number of AV_STRIDE between updates"
+     196             :            " of target p(s) and reweighing factor c(t)");
+     197             : //optimization
+     198          12 :   keys.add("compulsory","M_STEP","1.0","the mu step used for the Omega functional minimization");
+     199          12 :   keys.add("compulsory","AV_STRIDE","500","number of simulation steps between alpha updates");
+     200          12 :   keys.add("optional","TAU_MEAN","exponentially decaying average for alpha (rescaled using AV_STRIDE)."
+     201             :            " Should be used only in very specific cases");
+     202          12 :   keys.add("optional","INITIAL_ALPHA","( default=0 ) an initial guess for the bias potential parameter alpha");
+     203          12 :   keys.addFlag("DAMPING_OFF",false,"do not use an AdaGrad-like term to rescale M_STEP");
+     204             : //output parameters file
+     205          12 :   keys.add("compulsory","ALPHA_FILE","ALPHA","file name for output minimization parameters");
+     206          12 :   keys.add("optional","PRINT_STRIDE","( default=10 ) stride for printing to ALPHA_FILE");
+     207          12 :   keys.add("optional","FMT","specify format for ALPHA_FILE");
+     208             : //debug flags
+     209          12 :   keys.addFlag("SERIAL",false,"perform the calculation in serial even if multiple tasks are available");
+     210          12 :   keys.addFlag("MULTIPLE_WALKERS",false,"use multiple walkers connected via MPI for the optimization");
+     211           6 :   keys.use("RESTART");
+     212             : 
+     213             : //output components
+     214           6 :   componentsAreNotOptional(keys);
+     215          12 :   keys.addOutputComponent("rct","default","the reweighting factor c(t)");
+     216          12 :   keys.addOutputComponent("work","default","the work done by the bias in one AV_STRIDE");
+     217           6 : }
+     218             : 
+     219           4 : VesDeltaF::VesDeltaF(const ActionOptions&ao)
+     220             :   : PLUMED_BIAS_INIT(ao)
+     221           4 :   , isFirstStep_(true)
+     222           4 :   , afterCalculate_(false)
+     223           4 :   , mean_counter_(0)
+     224           4 :   , av_counter_(0)
+     225           4 :   , work_(0)
+     226             : {
+     227             : //set beta
+     228           4 :   const double Kb=plumed.getAtoms().getKBoltzmann();
+     229           4 :   double temp=0;
+     230           4 :   parse("TEMP",temp);
+     231           4 :   double KbT=Kb*temp;
+     232           4 :   if(KbT==0)
+     233             :   {
+     234           0 :     KbT=plumed.getAtoms().getKbT();
+     235           0 :     plumed_massert(KbT>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     236             :   }
+     237           4 :   beta_=1.0/KbT;
+     238             : 
+     239             : //initialize probability grids using local free energies
+     240             :   bool spline=true;
+     241             :   bool sparsegrid=false;
+     242           4 :   std::string funcl="file.free"; //typical name given by sum_hills
+     243             : 
+     244             :   std::vector<std::string> fes_names;
+     245           8 :   for(unsigned n=0;; n++)//NB: here we start from FILE_F0 not from FILE_F1
+     246             :   {
+     247             :     std::string filename;
+     248          24 :     if(!parseNumbered("FILE_F",n,filename))
+     249             :       break;
+     250           8 :     fes_names.push_back(filename);
+     251           8 :     IFile gridfile;
+     252           8 :     gridfile.open(filename);
+     253           8 :     auto g=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     254             : // we assume this cannot be sparse. in case we want it to be sparse, some of the methods
+     255             : // that are available only in Grid should be ported to GridBase
+     256           8 :     auto gg=dynamic_cast<Grid*>(g.get());
+     257             : // if this throws, g is deleted
+     258           8 :     plumed_assert(gg);
+     259             : // release ownership in order to transfer it to emplaced pointer
+     260             :     g.release();
+     261           8 :     grid_p_.emplace_back(gg);
+     262          16 :   }
+     263           4 :   plumed_massert(grid_p_.size()>1,"at least 2 basins must be defined, starting from FILE_F0");
+     264           4 :   alpha_size_=grid_p_.size()-1;
+     265           4 :   sym_alpha_size_=alpha_size_*(alpha_size_+1)/2; //useful for symmetric matrix [alpha_size_]x[alpha_size_]
+     266             :   //check for consistency with first local free energy
+     267           8 :   for(unsigned n=1; n<grid_p_.size(); n++)
+     268             :   {
+     269           8 :     std::string error_tag="FILE_F"+std::to_string(n)+" '"+fes_names[n]+"' not compatible with reference one, FILE_F0";
+     270           4 :     plumed_massert(grid_p_[n]->getSize()==grid_p_[0]->getSize(),error_tag);
+     271           4 :     plumed_massert(grid_p_[n]->getMin()==grid_p_[0]->getMin(),error_tag);
+     272           4 :     plumed_massert(grid_p_[n]->getMax()==grid_p_[0]->getMax(),error_tag);
+     273           4 :     plumed_massert(grid_p_[n]->getBinVolume()==grid_p_[0]->getBinVolume(),error_tag);
+     274             :   }
+     275             : 
+     276           4 :   bool no_mintozero=false;
+     277           4 :   parseFlag("NO_MINTOZERO",no_mintozero);
+     278           4 :   if(!no_mintozero)
+     279             :   {
+     280           6 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     281           4 :       grid_p_[n]->setMinToZero();
+     282             :   }
+     283           4 :   bool normalize=false;
+     284           4 :   parseFlag("NORMALIZE",normalize);
+     285           4 :   norm_.resize(grid_p_.size(),0);
+     286           4 :   std::vector<double> c_norm(grid_p_.size());
+     287             :   //convert the FESs to probability distributions
+     288             :   //NB: the spline interpolation will be done on the probability distributions, not on the given FESs
+     289             :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     290          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     291             :   {
+     292         808 :     for(Grid::index_t t=0; t<grid_p_[n]->getSize(); t++)
+     293             :     {
+     294         800 :       std::vector<double> der(ncv);
+     295         800 :       const double val=std::exp(-beta_*grid_p_[n]->getValueAndDerivatives(t,der));
+     296        1600 :       for(unsigned s=0; s<ncv; s++)
+     297         800 :         der[s]*=-beta_*val;
+     298         800 :       grid_p_[n]->setValueAndDerivatives(t,val,der);
+     299         800 :       norm_[n]+=val;
+     300             :     }
+     301           8 :     c_norm[n]=1./beta_*std::log(norm_[n]);
+     302           8 :     if(normalize)
+     303             :     {
+     304           4 :       grid_p_[n]->scaleAllValuesAndDerivatives(1./norm_[n]);
+     305           4 :       norm_[n]=1;
+     306             :     }
+     307             :   }
+     308             : 
+     309             : //get target
+     310           4 :   double biasfactor=0;
+     311           4 :   parse("BIASFACTOR",biasfactor);
+     312           4 :   plumed_massert(biasfactor==0 || biasfactor>1,"BIASFACTOR must be zero (for uniform target) or greater than one");
+     313           4 :   if(biasfactor==0)
+     314           2 :     inv_gamma_=0;
+     315             :   else
+     316           2 :     inv_gamma_=1./biasfactor;
+     317           4 :   tg_counter_=0;
+     318           4 :   tg_stride_=1;
+     319           4 :   parse("TG_STRIDE",tg_stride_);
+     320           4 :   tg_dV_dAlpha_.resize(alpha_size_,0);
+     321           4 :   tg_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     322             : 
+     323             : //setup optimization stuff
+     324           4 :   minimization_step_=1;
+     325           4 :   parse("M_STEP",minimization_step_);
+     326             : 
+     327           4 :   av_stride_=500;
+     328           4 :   parse("AV_STRIDE",av_stride_);
+     329           4 :   av_dV_dAlpha_.resize(alpha_size_,0);
+     330           4 :   av_dV_dAlpha_prod_.resize(sym_alpha_size_,0);
+     331           4 :   av_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     332             : 
+     333           4 :   mean_weight_tau_=0;
+     334           4 :   parse("TAU_MEAN",mean_weight_tau_);
+     335           4 :   if(mean_weight_tau_!=1) //set it to 1 for basic SGD
+     336             :   {
+     337           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");
+     338           4 :     mean_weight_tau_/=av_stride_; //this way you can look at the number of simulation steps to choose TAU_MEAN
+     339             :   }
+     340             : 
+     341           8 :   parseVector("INITIAL_ALPHA",mean_alpha_);
+     342           4 :   if(mean_alpha_.size()>0)
+     343             :   {
+     344           2 :     plumed_massert(mean_alpha_.size()==alpha_size_,"provide one INITIAL_ALPHA for each basin beyond the first one");
+     345             :   }
+     346             :   else
+     347           2 :     mean_alpha_.resize(alpha_size_,0);
+     348           4 :   inst_alpha_=mean_alpha_;
+     349           4 :   exp_alpha_.resize(alpha_size_);
+     350           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     351           4 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     352           4 :   prev_exp_alpha_=exp_alpha_;
+     353             : 
+     354           4 :   damping_off_=false;
+     355           4 :   parseFlag("DAMPING_OFF",damping_off_);
+     356           4 :   if(damping_off_)
+     357           2 :     past_increment2_.resize(alpha_size_,1);
+     358             :   else
+     359           2 :     past_increment2_.resize(alpha_size_,0);
+     360             : 
+     361             : //file printing options
+     362           4 :   std::string alphaFileName("ALPHA");
+     363           4 :   parse("ALPHA_FILE",alphaFileName);
+     364           4 :   print_stride_=10;
+     365           8 :   parse("PRINT_STRIDE",print_stride_);
+     366             :   std::string fmt;
+     367           4 :   parse("FMT",fmt);
+     368             : 
+     369             : //other flags, mainly for debugging
+     370           4 :   NumParallel_=comm.Get_size();
+     371           4 :   rank_=comm.Get_rank();
+     372           4 :   bool serial=false;
+     373           4 :   parseFlag("SERIAL",serial);
+     374           4 :   if(serial)
+     375             :   {
+     376           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     377           2 :     NumParallel_=1;
+     378           2 :     rank_=0;
+     379             :   }
+     380             : 
+     381           4 :   bool multiple_walkers=false;
+     382           4 :   parseFlag("MULTIPLE_WALKERS",multiple_walkers);
+     383           4 :   if(!multiple_walkers)
+     384           2 :     NumWalkers_=1;
+     385             :   else
+     386             :   {
+     387           2 :     if(comm.Get_rank()==0)//multi_sim_comm works well on first rank only
+     388           2 :       NumWalkers_=multi_sim_comm.Get_size();
+     389           2 :     if(comm.Get_size()>1) //if each walker has more than one processor update them all
+     390           0 :       comm.Bcast(NumWalkers_,0);
+     391             :   }
+     392             : 
+     393           4 :   checkRead();
+     394             : 
+     395             : //restart if needed
+     396           4 :   if(getRestart())
+     397             :   {
+     398           2 :     IFile ifile;
+     399           2 :     ifile.link(*this);
+     400           2 :     if(NumWalkers_>1)
+     401           4 :       ifile.enforceSuffix("");
+     402           2 :     if(ifile.FileExist(alphaFileName))
+     403             :     {
+     404           2 :       log.printf("  Restarting from: %s\n",alphaFileName.c_str());
+     405           2 :       log.printf("    all options (also PRINT_STRIDE) must be consistent!\n");
+     406           2 :       log.printf("    any INITIAL_ALPHA will be overwritten\n");
+     407           2 :       ifile.open(alphaFileName);
+     408             :       double time;
+     409           2 :       std::vector<double> damping(alpha_size_);
+     410          20 :       while(ifile.scanField("time",time)) //room for improvements: only last line is important
+     411             :       {
+     412          16 :         for(unsigned i=0; i<alpha_size_; i++)
+     413             :         {
+     414           8 :           const std::string index(std::to_string(i+1));
+     415           8 :           prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     416          16 :           ifile.scanField("alpha_"+index,mean_alpha_[i]);
+     417          16 :           ifile.scanField("auxiliary_"+index,inst_alpha_[i]);
+     418          16 :           ifile.scanField("damping_"+index,damping[i]);
+     419             :         }
+     420           8 :         ifile.scanField();
+     421           8 :         mean_counter_+=print_stride_;
+     422             :       }
+     423           4 :       for(unsigned i=0; i<alpha_size_; i++)
+     424             :       {
+     425           2 :         exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     426           2 :         past_increment2_[i]=damping[i]*damping[i];
+     427             :       }
+     428             :       //sync all walkers and treads. Not sure is mandatory but is no harm
+     429           2 :       comm.Barrier();
+     430           2 :       if(comm.Get_rank()==0)
+     431           2 :         multi_sim_comm.Barrier();
+     432             :     }
+     433             :     else
+     434           0 :       log.printf("  -- WARNING: restart requested, but no '%s' file found!\n",alphaFileName.c_str());
+     435           2 :   }
+     436             : 
+     437             : //setup output file with Alpha values
+     438           4 :   alphaOfile_.link(*this);
+     439           4 :   if(NumWalkers_>1)
+     440             :   {
+     441           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()>0)
+     442             :       alphaFileName="/dev/null"; //only first walker writes on file
+     443           4 :     alphaOfile_.enforceSuffix("");
+     444             :   }
+     445           4 :   alphaOfile_.open(alphaFileName);
+     446           4 :   if(fmt.length()>0)
+     447           8 :     alphaOfile_.fmtField(" "+fmt);
+     448             : 
+     449             : //add other output components
+     450           8 :   addComponent("rct"); componentIsNotPeriodic("rct");
+     451           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     452             : 
+     453             : //print some info
+     454           4 :   log.printf("  Temperature T: %g\n",1./(Kb*beta_));
+     455           4 :   log.printf("  Beta (1/Kb*T): %g\n",beta_);
+     456           4 :   log.printf("  Local free energy basins files and normalization constants:\n");
+     457          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     458           8 :     log.printf("    F_%d filename: %s  c_%d=%g\n",n,fes_names[n].c_str(),n,c_norm[n]);
+     459           4 :   if(no_mintozero)
+     460           2 :     log.printf(" -- NO_MINTOZERO: local free energies are not shifted to be zero at minimum\n");
+     461           4 :   if(normalize)
+     462           2 :     log.printf(" -- NORMALIZE: F_n+=c_n, alpha=DeltaF\n");
+     463           4 :   log.printf("  Using target distribution with 1/gamma = %g\n",inv_gamma_);
+     464           4 :   log.printf("    and updated with stride %d\n",tg_stride_);
+     465           4 :   log.printf("  Step for the minimization algorithm: %g\n",minimization_step_);
+     466           4 :   log.printf("  Stride for the ensemble average: %d\n",av_stride_);
+     467           4 :   if(mean_weight_tau_>1)
+     468           2 :     log.printf("  Exponentially decaying average with weight=tau/av_stride=%d\n",mean_weight_tau_);
+     469           4 :   if(mean_weight_tau_==1)
+     470           0 :     log.printf(" +++ WARNING +++ setting TAU_MEAN=1 is equivalent to use simple SGD, without mean alpha nor hessian contribution\n");
+     471           4 :   log.printf("  Initial guess for alpha:\n");
+     472           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     473           4 :     log.printf("    alpha_%d = %g\n",i+1,mean_alpha_[i]);
+     474           4 :   if(damping_off_)
+     475           2 :     log.printf(" -- DAMPING_OFF: the minimization step will NOT become smaller as the simulation goes on\n");
+     476           4 :   log.printf("  Printing on file %s with stride %d\n",alphaFileName.c_str(),print_stride_);
+     477           4 :   if(serial)
+     478           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     479           4 :   if(NumParallel_>1)
+     480           2 :     log.printf("  Using multiple threads per simulation: %d\n",NumParallel_);
+     481           4 :   if(multiple_walkers)
+     482             :   {
+     483           2 :     log.printf(" -- MULTIPLE_WALKERS: multiple simulations will combine statistics for the optimization\n");
+     484           2 :     if(NumWalkers_>1)
+     485             :     {
+     486           2 :       log.printf("    number of walkers: %d\n",NumWalkers_);
+     487           2 :       log.printf("    walker rank: %d\n",multi_sim_comm.Get_rank()); //only comm.Get_rank()=0 prints, so this is fine
+     488             :     }
+     489             :     else
+     490           0 :       log.printf(" +++ WARNING +++ only one replica found: are you sure you are running MPI-connected simulations?\n");
+     491             :   }
+     492           4 :   log.printf(" Bibliography ");
+     493           8 :   log<<plumed.cite("Invernizzi and Parrinello, J. Chem. Theory Comput. 15, 2187-2194 (2019)");
+     494           8 :   log<<plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+     495           4 :   if(inv_gamma_>0)
+     496           4 :     log<<plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     497             : 
+     498             : //last initializations
+     499           4 :   prob_.resize(grid_p_.size());
+     500           4 :   der_prob_.resize(grid_p_.size(),std::vector<double>(getNumberOfArguments()));
+     501           4 :   update_tg_and_rct();
+     502           8 : }
+     503             : 
+     504         804 : void VesDeltaF::calculate()
+     505             : {
+     506             : //get CVs
+     507         804 :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     508         804 :   std::vector<double> cv(ncv);
+     509        1608 :   for(unsigned s=0; s<ncv; s++)
+     510         804 :     cv[s]=getArgument(s);
+     511             : //get probabilities for each basin, and total one
+     512        2412 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     513        1608 :     prob_[n]=grid_p_[n]->getValueAndDerivatives(cv,der_prob_[n]);
+     514         804 :   tot_prob_=prob_[0];
+     515        1608 :   for(unsigned i=0; i<alpha_size_; i++)
+     516         804 :     tot_prob_+=prob_[i+1]*exp_alpha_[i];
+     517             : 
+     518             : //update bias and forces: V=-(1-inv_gamma_)*fes
+     519         804 :   setBias((1-inv_gamma_)/beta_*std::log(tot_prob_));
+     520        1608 :   for(unsigned s=0; s<ncv; s++)
+     521             :   {
+     522         804 :     double dProb_dCV_s=der_prob_[0][s];
+     523        1608 :     for(unsigned i=0; i<alpha_size_; i++)
+     524         804 :       dProb_dCV_s+=der_prob_[i+1][s]*exp_alpha_[i];
+     525         804 :     setOutputForce(s,-(1-inv_gamma_)/beta_/tot_prob_*dProb_dCV_s);
+     526             :   }
+     527         804 :   afterCalculate_=true;
+     528         804 : }
+     529             : 
+     530         804 : void VesDeltaF::update()
+     531             : {
+     532             : //skip first step to sync getTime() and av_counter_, as in METAD
+     533         804 :   if(isFirstStep_)
+     534             :   {
+     535           4 :     isFirstStep_=false;
+     536           4 :     return;
+     537             :   }
+     538         800 :   plumed_massert(afterCalculate_,"VesDeltaF::update() must be called after VesDeltaF::calculate() to work properly");
+     539         800 :   afterCalculate_=false;
+     540             : 
+     541             : //calculate derivatives for ensemble averages
+     542         800 :   std::vector<double> dV_dAlpha(alpha_size_);
+     543         800 :   std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     544        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     545         800 :     dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob_*prob_[i+1]*exp_alpha_[i];
+     546        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     547             :   {
+     548         800 :     d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     549        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     550         800 :       d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     551             :   }
+     552             : //update ensemble averages
+     553         800 :   av_counter_++;
+     554        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     555             :   {
+     556         800 :     av_dV_dAlpha_[i]+=(dV_dAlpha[i]-av_dV_dAlpha_[i])/av_counter_;
+     557        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     558             :     {
+     559         800 :       const unsigned ij=get_index(i,j);
+     560         800 :       av_dV_dAlpha_prod_[ij]+=(dV_dAlpha[i]*dV_dAlpha[j]-av_dV_dAlpha_prod_[ij])/av_counter_;
+     561         800 :       av_d2V_dAlpha2_[ij]+=(d2V_dAlpha2[ij]-av_d2V_dAlpha2_[ij])/av_counter_;
+     562             :     }
+     563             :   }
+     564             : //update work
+     565         800 :   double prev_tot_prob=prob_[0];
+     566        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     567         800 :     prev_tot_prob+=prob_[i+1]*prev_exp_alpha_[i];
+     568         800 :   work_+=(1-inv_gamma_)/beta_*std::log(tot_prob_/prev_tot_prob);
+     569             : 
+     570             : //update coefficients
+     571         800 :   if(av_counter_==av_stride_)
+     572             :   {
+     573          16 :     update_alpha();
+     574          16 :     tg_counter_++;
+     575          16 :     if(tg_counter_==tg_stride_)
+     576             :     {
+     577          12 :       update_tg_and_rct();
+     578          12 :       tg_counter_=0;
+     579             :     }
+     580             :     //reset the ensemble averages
+     581          16 :     av_counter_=0;
+     582             :     std::fill(av_dV_dAlpha_.begin(),av_dV_dAlpha_.end(),0);
+     583             :     std::fill(av_dV_dAlpha_prod_.begin(),av_dV_dAlpha_prod_.end(),0);
+     584             :     std::fill(av_d2V_dAlpha2_.begin(),av_d2V_dAlpha2_.end(),0);
+     585             :   }
+     586             : }
+     587             : 
+     588          16 : void VesDeltaF::update_tg_and_rct()
+     589             : {
+     590             : //calculate target averages
+     591          16 :   double Z_0=norm_[0];
+     592          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     593          16 :     Z_0+=norm_[i+1]*exp_alpha_[i];
+     594          16 :   double Z_tg=0;
+     595             :   std::fill(tg_dV_dAlpha_.begin(),tg_dV_dAlpha_.end(),0);
+     596             :   std::fill(tg_d2V_dAlpha2_.begin(),tg_d2V_dAlpha2_.end(),0);
+     597        1116 :   for(Grid::index_t t=rank_; t<grid_p_[0]->getSize(); t+=NumParallel_)
+     598             :   { //TODO can we recycle some code?
+     599        1100 :     std::vector<double> prob(grid_p_.size());
+     600        3300 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     601        2200 :       prob[n]=grid_p_[n]->getValue(t);
+     602        1100 :     double tot_prob=prob[0];
+     603        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     604        1100 :       tot_prob+=prob[i+1]*exp_alpha_[i];
+     605        1100 :     std::vector<double> dV_dAlpha(alpha_size_);
+     606        1100 :     std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     607        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     608        1100 :       dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob*prob[i+1]*exp_alpha_[i];
+     609        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     610             :     {
+     611        1100 :       d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     612        2200 :       for(unsigned j=i; j<alpha_size_; j++)
+     613        1100 :         d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     614             :     }
+     615        1100 :     const double unnorm_tg_p=std::pow(tot_prob,inv_gamma_);
+     616        1100 :     Z_tg+=unnorm_tg_p;
+     617        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     618        1100 :       tg_dV_dAlpha_[i]+=unnorm_tg_p*dV_dAlpha[i];
+     619        2200 :     for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     620        1100 :       tg_d2V_dAlpha2_[ij]+=unnorm_tg_p*d2V_dAlpha2[ij];
+     621             :   }
+     622          16 :   if(NumParallel_>1)
+     623             :   {
+     624          10 :     comm.Sum(Z_tg);
+     625          10 :     comm.Sum(tg_dV_dAlpha_);
+     626          10 :     comm.Sum(tg_d2V_dAlpha2_);
+     627             :   }
+     628          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     629          16 :     tg_dV_dAlpha_[i]/=Z_tg;
+     630          32 :   for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     631          16 :     tg_d2V_dAlpha2_[ij]/=Z_tg;
+     632          16 :   getPntrToComponent("rct")->set(-1./beta_*std::log(Z_tg/Z_0)); //Z_tg is the best available estimate of Z_V
+     633          16 : }
+     634             : 
+     635          16 : void VesDeltaF::update_alpha()
+     636             : {
+     637             : //combining the averages of multiple walkers
+     638          16 :   if(NumWalkers_>1)
+     639             :   {
+     640           8 :     if(comm.Get_rank()==0) //sum only once: in the first rank of each walker
+     641             :     {
+     642           8 :       multi_sim_comm.Sum(av_dV_dAlpha_);
+     643           8 :       multi_sim_comm.Sum(av_dV_dAlpha_prod_);
+     644           8 :       multi_sim_comm.Sum(av_d2V_dAlpha2_);
+     645          16 :       for(unsigned i=0; i<alpha_size_; i++)
+     646           8 :         av_dV_dAlpha_[i]/=NumWalkers_;
+     647          16 :       for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     648             :       {
+     649           8 :         av_dV_dAlpha_prod_[ij]/=NumWalkers_;
+     650           8 :         av_d2V_dAlpha2_[ij]/=NumWalkers_;
+     651             :       }
+     652             :     }
+     653           8 :     if(comm.Get_size()>1)//if there are more ranks for each walker, everybody has to know
+     654             :     {
+     655           0 :       comm.Bcast(av_dV_dAlpha_,0);
+     656           0 :       comm.Bcast(av_dV_dAlpha_prod_,0);
+     657           0 :       comm.Bcast(av_d2V_dAlpha2_,0);
+     658             :     }
+     659             :   }
+     660             :   //set work and reset it
+     661          16 :   getPntrToComponent("work")->set(work_);
+     662          16 :   work_=0;
+     663             : 
+     664             : //build the gradient and the Hessian of the functional
+     665          16 :   std::vector<double> grad_omega(alpha_size_);
+     666          16 :   std::vector<double> hess_omega(sym_alpha_size_);
+     667          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     668             :   {
+     669          16 :     grad_omega[i]=tg_dV_dAlpha_[i]-av_dV_dAlpha_[i];
+     670          32 :     for(unsigned j=i; j<alpha_size_; j++)
+     671             :     {
+     672          16 :       const unsigned ij=get_index(i,j);
+     673          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];
+     674             :     }
+     675             :   }
+     676             : //calculate the increment and update alpha
+     677          16 :   mean_counter_++;
+     678             :   long long unsigned mean_weight=mean_counter_;
+     679          16 :   if(mean_weight_tau_>0 && mean_weight_tau_<mean_counter_)
+     680             :     mean_weight=mean_weight_tau_;
+     681          16 :   std::vector<double> damping(alpha_size_);
+     682          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     683             :   {
+     684          16 :     double increment_i=grad_omega[i];
+     685          32 :     for(unsigned j=0; j<alpha_size_; j++)
+     686          16 :       increment_i+=hess_omega[get_index(i,j)]*(inst_alpha_[j]-mean_alpha_[j]);
+     687          16 :     if(!damping_off_)
+     688           8 :       past_increment2_[i]+=increment_i*increment_i;
+     689          16 :     damping[i]=std::sqrt(past_increment2_[i]);
+     690          16 :     prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     691          16 :     inst_alpha_[i]-=minimization_step_/damping[i]*increment_i;
+     692          16 :     mean_alpha_[i]+=(inst_alpha_[i]-mean_alpha_[i])/mean_weight;
+     693          16 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     694             :   }
+     695             : 
+     696             : //update the Alpha file
+     697          16 :   if(mean_counter_%print_stride_==0)
+     698             :   {
+     699          16 :     alphaOfile_.printField("time",getTime());
+     700          32 :     for(unsigned i=0; i<alpha_size_; i++)
+     701             :     {
+     702          16 :       const std::string index(std::to_string(i+1));
+     703          32 :       alphaOfile_.printField("alpha_"+index,mean_alpha_[i]);
+     704          32 :       alphaOfile_.printField("auxiliary_"+index,inst_alpha_[i]);
+     705          32 :       alphaOfile_.printField("damping_"+index,damping[i]);
+     706             :     }
+     707          16 :     alphaOfile_.printField();
+     708             :   }
+     709          16 : }
+     710             : 
+     711             : //mapping of a [alpha_size_]x[alpha_size_] symmetric matrix into a vector of size sym_alpha_size_, useful for the communicator
+     712        4632 : inline unsigned VesDeltaF::get_index(const unsigned i, const unsigned j) const
+     713             : {
+     714        4632 :   if(i<=j)
+     715        4632 :     return j+i*(alpha_size_-1)-i*(i-1)/2;
+     716             :   else
+     717           0 :     return get_index(j,i);
+     718             : }
+     719             : 
+     720             : }
+     721             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html new file mode 100644 index 0000000000..2d9fa4060d --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html @@ -0,0 +1,168 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320D2Ev4168
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func.html b/coverage/ves/VesLinearExpansion.cpp.func.html new file mode 100644 index 0000000000..55b770b27d --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func.html @@ -0,0 +1,168 @@ + + + + + + + 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-05-27 13:05:14Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe3206createERKNS_13ActionOptionsE90
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320C2Ev4168
_ZN4PLMD3ves12_GLOBAL__N_131VesLinearExpansionRegisterMe320D2Ev4168
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.gcov.html b/coverage/ves/VesLinearExpansion.cpp.gcov.html new file mode 100644 index 0000000000..3fac1f4e50 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.gcov.html @@ -0,0 +1,633 @@ + + + + + + + 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-05-27 13:05: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       12684 : PLUMED_REGISTER_ACTION(VesLinearExpansion,"VES_LINEAR_EXPANSION")
+     321             : 
+     322          92 : void VesLinearExpansion::registerKeywords( Keywords& keys ) {
+     323          92 :   VesBias::registerKeywords(keys);
+     324             :   //
+     325          92 :   VesBias::useInitialCoeffsKeywords(keys);
+     326          92 :   VesBias::useTargetDistributionKeywords(keys);
+     327          92 :   VesBias::useBiasCutoffKeywords(keys);
+     328          92 :   VesBias::useGridBinKeywords(keys);
+     329          92 :   VesBias::useProjectionArgKeywords(keys);
+     330             :   //
+     331          92 :   keys.use("ARG");
+     332         184 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the one dimensional basis functions that should be used.");
+     333         184 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential.");
+     334          92 : }
+     335             : 
+     336          90 : VesLinearExpansion::VesLinearExpansion(const ActionOptions&ao):
+     337             :   PLUMED_VES_VESBIAS_INIT(ao),
+     338          90 :   nargs_(getNumberOfArguments()),
+     339          90 :   basisf_pntrs_(0),
+     340          90 :   valueForce2_(NULL),
+     341          90 :   all_values_inside(true),
+     342          90 :   bf_values(0),
+     343          90 :   bf_values_set(false)
+     344             : {
+     345             :   std::vector<std::string> basisf_labels;
+     346          90 :   parseMultipleValues("BASIS_FUNCTIONS",basisf_labels,nargs_);
+     347          90 :   checkRead();
+     348             : 
+     349          90 :   std::string error_msg = "";
+     350         180 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     351          90 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     352             :   //
+     353             : 
+     354          90 :   std::vector<Value*> args_pntrs = getArguments();
+     355             :   // check arguments and basis functions
+     356             :   // this is done to avoid some issues with integration of target distribution
+     357             :   // and periodic CVs, needs to be fixed later on.
+     358         207 :   for(unsigned int i=0; i<args_pntrs.size(); i++) {
+     359         117 :     if(args_pntrs[i]->isPeriodic() && !(basisf_pntrs_[i]->arePeriodic()) ) {
+     360           0 :       plumed_merror("argument "+args_pntrs[i]->getName()+" is periodic while the basis functions " + basisf_pntrs_[i]->getLabel()+ " are not. You need to use the COMBINE action to remove the periodicity of the argument if you want to use these basis functions");
+     361             :     }
+     362         117 :     else if(!(args_pntrs[i]->isPeriodic()) && basisf_pntrs_[i]->arePeriodic() ) {
+     363           1 :       log.printf("  warning: argument %s is not periodic while the basis functions %s used for it are periodic\n",args_pntrs[i]->getName().c_str(),basisf_pntrs_[i]->getLabel().c_str());
+     364             :     }
+     365             :   }
+     366             : 
+     367          90 :   addCoeffsSet(args_pntrs,basisf_pntrs_);
+     368          90 :   ncoeffs_ = numberOfCoeffs();
+     369          90 :   bool coeffs_read = readCoeffsFromFiles();
+     370             : 
+     371          90 :   checkThatTemperatureIsGiven();
+     372         180 :   bias_expansion_pntr_ = Tools::make_unique<LinearBasisSetExpansion>(getLabel(),getBeta(),comm,args_pntrs,basisf_pntrs_,getCoeffsPntr());
+     373          90 :   bias_expansion_pntr_->linkVesBias(this);
+     374          90 :   bias_expansion_pntr_->setGridBins(this->getGridBins());
+     375             :   //
+     376          90 :   bf_values.assign(ncoeffs_,0.0);
+     377             : 
+     378             : 
+     379             : 
+     380          90 :   if(getNumberOfTargetDistributionPntrs()==0) {
+     381          45 :     log.printf("  using an uniform target distribution: \n");
+     382          45 :     bias_expansion_pntr_->setupUniformTargetDistribution();
+     383             :     disableStaticTargetDistFileOutput();
+     384             :   }
+     385          45 :   else if(getNumberOfTargetDistributionPntrs()==1) {
+     386          51 :     if(biasCutoffActive()) {getTargetDistributionPntrs()[0]->setupBiasCutoff();}
+     387          45 :     bias_expansion_pntr_->setupTargetDistribution(getTargetDistributionPntrs()[0]);
+     388          90 :     log.printf("  using target distribution of type %s with label %s \n",getTargetDistributionPntrs()[0]->getName().c_str(),getTargetDistributionPntrs()[0]->getLabel().c_str());
+     389             :   }
+     390             :   else {
+     391           0 :     plumed_merror("problem with the TARGET_DISTRIBUTION keyword, either give no label or just one label.");
+     392             :   }
+     393          90 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     394             :   //
+     395          90 :   if(coeffs_read && biasCutoffActive()) {
+     396           1 :     VesLinearExpansion::updateTargetDistributions();
+     397             :   }
+     398             :   //
+     399          90 :   if(coeffs_read) {
+     400           4 :     VesLinearExpansion::setupBiasFileOutput();
+     401           4 :     VesLinearExpansion::writeBiasToFile();
+     402             :   }
+     403             : 
+     404         180 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     405          90 :   valueForce2_=getPntrToComponent("force2");
+     406          90 : }
+     407             : 
+     408             : 
+     409         180 : VesLinearExpansion::~VesLinearExpansion() {
+     410         270 : }
+     411             : 
+     412             : 
+     413       23750 : void VesLinearExpansion::calculate() {
+     414             : 
+     415       23750 :   std::vector<double> cv_values(nargs_);
+     416       23750 :   std::vector<double> forces(nargs_);
+     417             : 
+     418       60967 :   for(unsigned int k=0; k<nargs_; k++) {
+     419       37217 :     cv_values[k]=getArgument(k);
+     420             :   }
+     421             : 
+     422       23750 :   all_values_inside = true;
+     423       23750 :   double bias = bias_expansion_pntr_->getBiasAndForces(cv_values,all_values_inside,forces,bf_values);
+     424       23750 :   if(biasCutoffActive()) {
+     425          63 :     applyBiasCutoff(bias,forces,bf_values);
+     426          63 :     bf_values[0]=1.0;
+     427             :   }
+     428             :   double totalForce2 = 0.0;
+     429       23750 :   if(all_values_inside) {
+     430       60408 :     for(unsigned int k=0; k<nargs_; k++) {
+     431       36852 :       setOutputForce(k,forces[k]);
+     432       36852 :       totalForce2 += forces[k]*forces[k];
+     433             :     }
+     434             :   }
+     435             : 
+     436       23750 :   setBias(bias);
+     437       23750 :   valueForce2_->set(totalForce2);
+     438             : 
+     439       23750 :   bf_values_set = true;
+     440       23750 : }
+     441             : 
+     442             : 
+     443       23750 : void VesLinearExpansion::update() {
+     444       23750 :   if(!bf_values_set) {
+     445           0 :     warning("VesLinearExpansion::update() is being called without calling VesLinearExpansion::calculate() first to calculate the basis function values. This can lead to incorrect behavior.");
+     446             :   }
+     447       23750 :   if(all_values_inside && bf_values_set) {
+     448       23556 :     addToSampledAverages(bf_values);
+     449             :   }
+     450             :   std::fill(bf_values.begin(), bf_values.end(), 0.0);
+     451       23750 :   bf_values_set = false;
+     452       23750 : }
+     453             : 
+     454             : 
+     455             : 
+     456             : 
+     457             : 
+     458             : 
+     459         355 : void VesLinearExpansion::updateTargetDistributions() {
+     460         355 :   bias_expansion_pntr_->updateTargetDistribution();
+     461         355 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     462         355 : }
+     463             : 
+     464             : 
+     465           8 : void VesLinearExpansion::restartTargetDistributions() {
+     466          16 :   bias_expansion_pntr_->readInRestartTargetDistribution(getCurrentTargetDistOutputFilename());
+     467           8 :   bias_expansion_pntr_->restartTargetDistribution();
+     468           8 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     469           8 : }
+     470             : 
+     471             : 
+     472          87 : void VesLinearExpansion::setupBiasFileOutput() {
+     473          87 :   bias_expansion_pntr_->setupBiasGrid(true);
+     474          87 : }
+     475             : 
+     476             : 
+     477         173 : void VesLinearExpansion::writeBiasToFile() {
+     478         173 :   bias_expansion_pntr_->updateBiasGrid();
+     479         519 :   auto ofile_pntr = getOFile(getCurrentBiasOutputFilename(),useMultipleWalkers());
+     480         173 :   bias_expansion_pntr_->writeBiasGridToFile(*ofile_pntr);
+     481         173 :   if(biasCutoffActive()) {
+     482           5 :     bias_expansion_pntr_->updateBiasWithoutCutoffGrid();
+     483          15 :     auto ofile_pntr2 = getOFile(getCurrentBiasOutputFilename("without-cutoff"),useMultipleWalkers());
+     484           5 :     bias_expansion_pntr_->writeBiasWithoutCutoffGridToFile(*ofile_pntr2);
+     485           5 :   }
+     486         173 : }
+     487             : 
+     488             : 
+     489          36 : void VesLinearExpansion::resetBiasFileOutput() {
+     490             :   bias_expansion_pntr_->resetStepOfLastBiasGridUpdate();
+     491          36 : }
+     492             : 
+     493             : 
+     494          83 : void VesLinearExpansion::setupFesFileOutput() {
+     495          83 :   bias_expansion_pntr_->setupFesGrid();
+     496          83 : }
+     497             : 
+     498             : 
+     499         169 : void VesLinearExpansion::writeFesToFile() {
+     500         169 :   bias_expansion_pntr_->updateFesGrid();
+     501         507 :   auto ofile_pntr = getOFile(getCurrentFesOutputFilename(),useMultipleWalkers());
+     502         169 :   bias_expansion_pntr_->writeFesGridToFile(*ofile_pntr);
+     503         169 : }
+     504             : 
+     505             : 
+     506          36 : void VesLinearExpansion::resetFesFileOutput() {
+     507             :   bias_expansion_pntr_->resetStepOfLastFesGridUpdate();
+     508          36 : }
+     509             : 
+     510             : 
+     511          17 : void VesLinearExpansion::setupFesProjFileOutput() {
+     512          17 :   if(getNumberOfProjectionArguments()>0) {
+     513           8 :     bias_expansion_pntr_->setupFesProjGrid();
+     514             :   }
+     515          17 : }
+     516             : 
+     517             : 
+     518          36 : void VesLinearExpansion::writeFesProjToFile() {
+     519          36 :   bias_expansion_pntr_->updateFesGrid();
+     520          72 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     521             :     std::string suffix;
+     522          36 :     Tools::convert(i+1,suffix);
+     523          36 :     suffix = "proj-" + suffix;
+     524          72 :     auto ofile_pntr = getOFile(getCurrentFesOutputFilename(suffix),useMultipleWalkers());
+     525             :     std::vector<std::string> args = getProjectionArgument(i);
+     526          36 :     bias_expansion_pntr_->writeFesProjGridToFile(args,*ofile_pntr);
+     527          36 :   }
+     528          36 : }
+     529             : 
+     530             : 
+     531          82 : void VesLinearExpansion::writeTargetDistToFile() {
+     532         164 :   auto ofile1_pntr = getOFile(getCurrentTargetDistOutputFilename(),useMultipleWalkers());
+     533         164 :   auto ofile2_pntr = getOFile(getCurrentTargetDistOutputFilename("log"),useMultipleWalkers());
+     534          82 :   bias_expansion_pntr_->writeTargetDistGridToFile(*ofile1_pntr);
+     535          82 :   bias_expansion_pntr_->writeLogTargetDistGridToFile(*ofile2_pntr);
+     536          82 : }
+     537             : 
+     538             : 
+     539          13 : void VesLinearExpansion::writeTargetDistProjToFile() {
+     540          33 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     541             :     std::string suffix;
+     542          20 :     Tools::convert(i+1,suffix);
+     543          20 :     suffix = "proj-" + suffix;
+     544          40 :     auto ofile_pntr = getOFile(getCurrentTargetDistOutputFilename(suffix),useMultipleWalkers());
+     545             :     std::vector<std::string> args = getProjectionArgument(i);
+     546          20 :     bias_expansion_pntr_->writeTargetDistProjGridToFile(args,*ofile_pntr);
+     547          20 :   }
+     548          13 : }
+     549             : 
+     550             : 
+     551           0 : double VesLinearExpansion::calculateReweightFactor() const {
+     552           0 :   return bias_expansion_pntr_->calculateReweightFactor();
+     553             : }
+     554             : 
+     555             : 
+     556             : }
+     557             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func-sort-c.html b/coverage/ves/VesTools.cpp.func-sort-c.html new file mode 100644 index 0000000000..7831aa8293 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func.html b/coverage/ves/VesTools.cpp.func.html new file mode 100644 index 0000000000..dff2d9eebe --- /dev/null +++ b/coverage/ves/VesTools.cpp.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.gcov.html b/coverage/ves/VesTools.cpp.gcov.html new file mode 100644 index 0000000000..a14729dccb --- /dev/null +++ b/coverage/ves/VesTools.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func-sort-c.html b/coverage/ves/VesTools.h.func-sort-c.html new file mode 100644 index 0000000000..0922acec36 --- /dev/null +++ b/coverage/ves/VesTools.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func.html b/coverage/ves/VesTools.h.func.html new file mode 100644 index 0000000000..370d2894c8 --- /dev/null +++ b/coverage/ves/VesTools.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/VesTools.h.gcov.html b/coverage/ves/VesTools.h.gcov.html new file mode 100644 index 0000000000..81d8fe6814 --- /dev/null +++ b/coverage/ves/VesTools.h.gcov.html @@ -0,0 +1,216 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html new file mode 100644 index 0000000000..5dcfae356c --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func.html b/coverage/ves/WaveletCoeffs.cpp.func.html new file mode 100644 index 0000000000..6f6382e486 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.gcov.html b/coverage/ves/WaveletCoeffs.cpp.gcov.html new file mode 100644 index 0000000000..84dda8c983 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.gcov.html @@ -0,0 +1,1058 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func-sort-c.html b/coverage/ves/WaveletGrid.cpp.func-sort-c.html new file mode 100644 index 0000000000..072c2cc4a2 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func.html b/coverage/ves/WaveletGrid.cpp.func.html new file mode 100644 index 0000000000..dae2ff3800 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.gcov.html b/coverage/ves/WaveletGrid.cpp.gcov.html new file mode 100644 index 0000000000..4e8a90f076 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.gcov.html @@ -0,0 +1,330 @@ + + + + + + + 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-05-27 13:05: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         517 :   {std::to_string(maxsupport)}, {gridsize}, false, true, {false}, {"0."}, {"0."}));
+      73             : 
+      74          47 :   BinaryMap values = cascade(h_Matvec, g_Matvec, values_at_integers, recursion_number, bins_per_int, 0, use_mother_wavelet);
+      75          47 :   BinaryMap derivs = cascade(h_Matvec, g_Matvec, derivs_at_integers, recursion_number, bins_per_int, 1, use_mother_wavelet);
+      76             : 
+      77          47 :   fillGridFromMaps(grid, values, derivs);
+      78             : 
+      79          47 :   return grid;
+      80          47 : }
+      81             : 
+      82             : 
+      83             : 
+      84          49 : std::vector<Matrix<double>> WaveletGrid::setupMatrices(const std::vector<double>& coeffs) {
+      85             :   Matrix<double> M0, M1;
+      86          49 :   const int N = coeffs.size() -1;
+      87             :   M0.resize(N,N); M1.resize(N,N);
+      88        1108 :   for (int i = 0; i < N; ++i) {
+      89       27644 :     for (int j = 0; j < N; ++j) {
+      90       26585 :       int shift = 2*i -j;
+      91       26585 :       if (0 <= shift && shift <= N) {
+      92       13822 :         M0[i][j] = coeffs[2*i -j]; // normalization is already included in coeffs
+      93             :       }
+      94       26585 :       if (-1 <= shift && shift <= N -1) {
+      95       13822 :         M1[i][j] = coeffs[2*i -j + 1];
+      96             :       }
+      97             :     }
+      98             :   }
+      99         196 :   return std::vector<Matrix<double>> {M0, M1};
+     100             : }
+     101             : 
+     102             : 
+     103          94 : std::vector<double> WaveletGrid::calcIntegerValues(const Matrix<double> &M, const int deriv) {
+     104             :   // corresponding eigenvalue of the matrix
+     105             :   double eigenvalue = std::pow(0.5, deriv);
+     106          94 :   std::vector<double> values = getEigenvector(M, eigenvalue);
+     107             : 
+     108             :   // normalization of the eigenvector
+     109             :   double normfactor = 0.;
+     110             :   // i=0 is always 0; for derivs > 1 an additional factorial would have to be added
+     111        2042 :   for (unsigned i=1; i<values.size(); ++i) {
+     112        1948 :     normfactor += values[i] * std::pow(-i, deriv);
+     113             :   }
+     114          94 :   normfactor = 1/normfactor;
+     115        2136 :   for (auto& value : values) {
+     116        2042 :     value *= normfactor;
+     117             :   }
+     118             : 
+     119          94 :   return values;
+     120             : }
+     121             : 
+     122             : 
+     123             : // maybe move this to the tools/matrix.h file?
+     124             : // this works reliably only for singular eigenvalues
+     125             : //
+     126          94 : std::vector<double> WaveletGrid::getEigenvector(const Matrix<double> &A, const double eigenvalue) {
+     127             :   // mostly copied from tools/matrix.h
+     128          94 :   int info, N = A.ncols(); // ncols == nrows
+     129          94 :   std::vector<double> da(N*N);
+     130          94 :   std::vector<double> S(N);
+     131          94 :   std::vector<double> U(N*N);
+     132          94 :   std::vector<double> VT(N*N);
+     133          94 :   std::vector<int> iwork(8*N);
+     134             : 
+     135             :   // Transfer the matrix to the local array and substract eigenvalue
+     136       53862 :   for (int i=0; i<N; ++i) for (int j=0; j<N; ++j) {
+     137       51726 :       da[i*N+j]=static_cast<double>( A(j,i) );
+     138       51726 :       if (i==j) da[i*N+j] -= eigenvalue;
+     139             :     }
+     140             : 
+     141             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     142          94 :   int lwork=-1;
+     143          94 :   std::vector<double> work(1);
+     144          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     145             : 
+     146             :   // Retrieve correct sizes for work and reallocate
+     147          94 :   lwork=static_cast<int>(work[0]); work.resize(lwork);
+     148             : 
+     149             :   // This does the singular value decomposition
+     150          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     151             : 
+     152             :   // fill eigenvector with last column of VT
+     153          94 :   std::vector<double> eigenvector(N);
+     154        2136 :   for (int i=0; i<N; ++i) eigenvector[i] = VT[N-1 + i*N];
+     155             : 
+     156          94 :   return eigenvector;
+     157             : }
+     158             : 
+     159             : 
+     160          94 : WaveletGrid::BinaryMap WaveletGrid::cascade(std::vector<Matrix<double>>& h_Matvec, std::vector<Matrix<double>>& g_Matvec, const std::vector<double>& values_at_integers, const unsigned recursion_number, const unsigned bins_per_int, const unsigned derivnum, const bool use_mother_wavelet) {
+     161             :   BinaryMap scaling_map, wavelet_map;
+     162          94 :   scaling_map.reserve(bins_per_int);
+     163             :   // vector to store the binary representation of all the decimal parts
+     164             :   std::vector<std::string> binary_vec;
+     165             :   // vector used as result of the matrix multiplications
+     166             :   std::vector<double> temp_values;
+     167             : 
+     168             :   // multiply matrices by 2 if derivatives are calculated (assumes ascending order)
+     169         188 :   if (derivnum != 0) for (auto& M : h_Matvec) M *= 2;
+     170             : 
+     171          94 :   if (use_mother_wavelet) {
+     172             :     wavelet_map.reserve(bins_per_int);
+     173           8 :     if (derivnum != 0) for (auto& M : g_Matvec) M *= 2;
+     174             :   }
+     175             : 
+     176             :   // fill the first two datasets by hand
+     177         282 :   scaling_map["0"] = values_at_integers;
+     178          94 :   mult(h_Matvec[1], values_at_integers, temp_values);
+     179         188 :   scaling_map["1"] = temp_values;
+     180             : 
+     181          94 :   if (use_mother_wavelet) {
+     182           4 :     mult(g_Matvec[0], values_at_integers, temp_values);
+     183          12 :     wavelet_map["0"] = temp_values;
+     184           4 :     mult(g_Matvec[1], values_at_integers, temp_values);
+     185          12 :     wavelet_map["1"] = temp_values;
+     186             :   }
+     187             : 
+     188             :   // now do the cascade
+     189          94 :   binary_vec.emplace_back("1");
+     190         252 :   for (unsigned i=1; i<recursion_number; ++i) {
+     191             :     std::vector<std::string> new_binary_vec;
+     192        1144 :     for (const auto& binary : binary_vec) {
+     193        2958 :       for (unsigned k=0; k<2; ++k) {
+     194             :         // prepend the new bit
+     195        3944 :         std::string new_binary = std::to_string(k) + binary;
+     196        1972 :         mult(h_Matvec[k], scaling_map[binary], temp_values);
+     197        1972 :         scaling_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     198        1972 :         if (use_mother_wavelet) {
+     199           8 :           mult(g_Matvec[k], scaling_map[binary], temp_values);
+     200          16 :           wavelet_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     201             :         }
+     202        1972 :         new_binary_vec.push_back(new_binary);
+     203             :       }
+     204             :     }
+     205         158 :     binary_vec = new_binary_vec;
+     206         158 :   }
+     207             : 
+     208         188 :   return use_mother_wavelet ? wavelet_map : scaling_map;
+     209          94 : }
+     210             : 
+     211             : 
+     212             : // Fill the Grid with the values of the unordered maps
+     213          47 : void WaveletGrid::fillGridFromMaps(std::unique_ptr<Grid>& grid, const BinaryMap& values_map, const BinaryMap& derivs_map) {
+     214          47 :   unsigned bins_per_int = values_map.size();
+     215             :   // this is somewhat complicated… not sure if the unordered_map way is the best way for c++
+     216        1127 :   for (const auto& value_iter : values_map) {
+     217             :     // get decimal of binary key
+     218        1080 :     unsigned decimal = std::stoi(value_iter.first, nullptr, 2);
+     219             :     // corresponding iterator of deriv
+     220        1080 :     auto deriv_iter = derivs_map.find(value_iter.first);
+     221             :     // calculate first grid element
+     222        1080 :     unsigned first_grid_element = decimal * (bins_per_int >> value_iter.first.length());
+     223       19480 :     for (unsigned i=0; i<value_iter.second.size(); ++i) {
+     224             :       // derivative has to be passed as vector
+     225       18400 :       std::vector<double> deriv {deriv_iter->second[i]};
+     226       18400 :       grid->setValueAndDerivatives(first_grid_element + bins_per_int*i, value_iter.second[i], deriv);
+     227             :     }
+     228             :   }
+     229          47 : }
+     230             : 
+     231             : 
+     232          47 : WaveletGrid::Type WaveletGrid::stringToType(std::string& type_str) {
+     233         188 :   std::unordered_map<std::string, Type> typemap = { {"DAUBECHIES", Type::db}, {"SYMLETS", Type::sym} };
+     234          47 :   try { return typemap.at(type_str); }
+     235           0 :   catch(const std::out_of_range& e) {plumed_merror("The specified wavelet type "+type_str+" is not implemented."); }
+     236             : }
+     237             : 
+     238             : 
+     239          47 : std::string WaveletGrid::typeToString(Type type, bool abbrev) {
+     240             :   std::string type_str;
+     241          47 :   switch(type) {
+     242          23 :   case Type::db:
+     243          23 :     type_str = abbrev ? "Db" : "DAUBECHIES";
+     244             :     break;
+     245          24 :   case Type::sym:
+     246          24 :     type_str = abbrev ? "Sym" : "SYMLETS";
+     247             :     break;
+     248             :   }
+     249          47 :   return type_str;
+     250             : }
+     251             : 
+     252             : 
+     253             : }
+     254             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-f.html b/coverage/ves/index-sort-f.html new file mode 100644 index 0000000000..dc70a8150e --- /dev/null +++ b/coverage/ves/index-sort-f.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5938723082.1 %
Date:2024-05-27 13:05: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.6%75.6%
+
75.6 %59 / 7869.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.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
TargetDistribution.cpp +
87.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_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_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
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %148 / 15288.9 %8 / 9
TD_Custom.cpp +
86.7%86.7%
+
86.7 %78 / 9090.0 %9 / 10
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
VesDeltaF.cpp +
97.2%97.2%
+
97.2 %346 / 35690.9 %10 / 11
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-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_Grid.cpp +
94.9%94.9%
+
94.9 %56 / 59100.0 %6 / 6
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
BF_CubicBsplines.cpp +
100.0%
+
100.0 %59 / 59100.0 %7 / 7
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %55 / 56100.0 %7 / 7
BF_Legendre.cpp +
100.0%
+
100.0 %43 / 43100.0 %7 / 7
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %39 / 39100.0 %7 / 7
BF_Chebyshev.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Gaussians.cpp +
100.0%
+
100.0 %53 / 53100.0 %7 / 7
TD_ExponentiallyModifiedGaussian.cpp +
90.6%90.6%
+
90.6 %58 / 64100.0 %7 / 7
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_Wavelets.cpp +
100.0%
+
100.0 %119 / 119100.0 %8 / 8
BF_Sine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %75 / 76100.0 %8 / 8
BF_Custom.cpp +
82.4%82.4%
+
82.4 %126 / 153100.0 %8 / 8
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
BF_Cosine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_Combined.cpp +
97.0%97.0%
+
97.0 %64 / 66100.0 %8 / 8
TD_Gaussian.cpp +
90.6%90.6%
+
90.6 %77 / 85100.0 %8 / 8
BF_Fourier.cpp +
100.0%
+
100.0 %39 / 39100.0 %8 / 8
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %326 / 336100.0 %9 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-l.html b/coverage/ves/index-sort-l.html new file mode 100644 index 0000000000..aa13f2609d --- /dev/null +++ b/coverage/ves/index-sort-l.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5938723082.1 %
Date:2024-05-27 13:05: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
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
TD_LinearCombination.cpp +
75.6%75.6%
+
75.6 %59 / 7869.2 %9 / 13
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.7%87.7%
+
87.7 %222 / 25381.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.5%89.5%
+
89.5 %682 / 76284.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
Opt_Dummy.cpp +
95.5%95.5%
+
95.5 %21 / 2285.7 %6 / 7
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
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_Chebyshev.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
BF_Cosine.cpp +
100.0%
+
100.0 %36 / 36100.0 %8 / 8
BF_Powers.cpp +
100.0%
+
100.0 %36 / 36100.0 %7 / 7
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %39 / 39100.0 %7 / 7
BF_Fourier.cpp +
100.0%
+
100.0 %39 / 39100.0 %8 / 8
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.16
+
+ + + diff --git a/coverage/ves/index.html b/coverage/ves/index.html new file mode 100644 index 0000000000..dd449c70f9 --- /dev/null +++ b/coverage/ves/index.html @@ -0,0 +1,723 @@ + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5938723082.1 %
Date:2024-05-27 13:05: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.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %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.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %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.6%75.6%
+
75.6 %59 / 7869.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.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html new file mode 100644 index 0000000000..74a846dced --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410995.4 %
Date:2024-05-27 13:05: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_8KeywordsE93
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.func.html b/coverage/vesselbase/ActionWithAveraging.cpp.func.html new file mode 100644 index 0000000000..4141fa5e8b --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.func.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410995.4 %
Date:2024-05-27 13:05:14Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging12runFinalJobsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD10vesselbase19ActionWithAveraging17performOperationsERKb0
_ZN4PLMD10vesselbase19ActionWithAveraging18setAveragingActionESt10unique_ptrINS0_15AveragingVesselESt14default_deleteIS3_EERKb68
_ZN4PLMD10vesselbase19ActionWithAveraging29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZN4PLMD10vesselbase19ActionWithAveragingC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase19ActionWithAveragingC2ERKNS_13ActionOptionsE73
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
_ZNK4PLMD10vesselbase19ActionWithAveraging19ignoreNormalizationEv53
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html b/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html new file mode 100644 index 0000000000..68f0e77a26 --- /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:10410995.4 %
Date:2024-05-27 13:05: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          93 : void ActionWithAveraging::registerKeywords( Keywords& keys ) {
+      33          93 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      34          93 :   ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithVessel::registerKeywords( keys );
+      35         186 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      36         186 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      37             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      38         186 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      39         186 :   keys.add("compulsory","NORMALIZATION","true","This controls how the data is normalized it can be set equal to true, false or ndata.  The differences between these options are explained in the manual page for \\ref HISTOGRAM");
+      40          93 :   keys.remove("NUMERICAL_DERIVATIVES");
+      41          93 : }
+      42             : 
+      43          73 : ActionWithAveraging::ActionWithAveraging( const ActionOptions& ao ):
+      44             :   Action(ao),
+      45             :   ActionPilot(ao),
+      46             :   ActionAtomistic(ao),
+      47             :   ActionWithArguments(ao),
+      48             :   ActionWithValue(ao),
+      49             :   ActionWithVessel(ao),
+      50          73 :   myaverage(NULL),
+      51          73 :   activated(false),
+      52          73 :   my_analysis_object(NULL),
+      53          73 :   normalization(t),
+      54          73 :   useRunAllTasks(false),
+      55          73 :   clearstride(0),
+      56          73 :   lweight(0),cweight(0)
+      57             : {
+      58         146 :   if( keywords.exists("CLEAR") ) {
+      59          58 :     parse("CLEAR",clearstride);
+      60          58 :     if( clearstride>0 ) {
+      61          12 :       if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      62          12 :       log.printf("  clearing grid every %u steps \n",clearstride);
+      63             :     }
+      64             :   }
+      65          73 :   if( ActionWithAveraging::getNumberOfArguments()>0 ) {
+      66          29 :     my_analysis_object=dynamic_cast<analysis::AnalysisBase*>( getPntrToArgument(0)->getPntrToAction() );
+      67          38 :     for(unsigned i=1; i<ActionWithAveraging::getNumberOfArguments(); i++) {
+      68           9 :       if( my_analysis_object && my_analysis_object->getLabel()!=(getPntrToArgument(i)->getPntrToAction())->getLabel() ) {
+      69           0 :         error("all arguments should be from one single analysis object");
+      70             :       }
+      71             :     }
+      72          29 :     if( my_analysis_object ) {
+      73           7 :       if( getStride()!=1 ) error("stride should not have been set when calculating average from analysis data");
+      74           7 :       setStride(0); addDependency( my_analysis_object );
+      75             :     }
+      76             :   }
+      77         146 :   if( keywords.exists("LOGWEIGHTS") ) {
+      78         116 :     std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr);
+      79          58 :     if( wwstr.size()>0 ) log.printf("  reweighting using weights from ");
+      80          58 :     std::vector<Value*> arg( getArguments() );
+      81          66 :     for(unsigned i=0; i<wwstr.size(); ++i) {
+      82           8 :       ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]);
+      83           8 :       if( !val ) error("could not find value named");
+      84           8 :       bias::ReweightBase* iswham=dynamic_cast<bias::ReweightBase*>( val );
+      85           8 :       if( iswham && iswham->buildsWeightStore() ) error("to use wham you must gather data using COLLECT_FRAMES");
+      86           8 :       weights.push_back( val->copyOutput(val->getLabel()) );
+      87           8 :       arg.push_back( val->copyOutput(val->getLabel()) );
+      88           8 :       log.printf("%s ",wwstr[i].c_str() );
+      89             :     }
+      90          58 :     if( wwstr.size()>0 ) log.printf("\n");
+      91          51 :     else log.printf("  weights are all equal to one\n");
+      92          58 :     requestArguments( arg );
+      93          58 :   }
+      94         146 :   if( keywords.exists("NORMALIZATION") ) {
+      95         116 :     std::string normstr; parse("NORMALIZATION",normstr);
+      96          58 :     if( normstr=="true" ) normalization=t;
+      97          35 :     else if( normstr=="false" ) normalization=f;
+      98          26 :     else if( normstr=="ndata" ) normalization=ndata;
+      99           0 :     else error("invalid instruction for NORMALIZATION flag should be true, false, or ndata");
+     100             :   }
+     101          73 : }
+     102             : 
+     103          53 : bool ActionWithAveraging::ignoreNormalization() const {
+     104          53 :   if( normalization==f ) return true;
+     105             :   return false;
+     106             : }
+     107             : 
+     108          68 : void ActionWithAveraging::setAveragingAction( std::unique_ptr<AveragingVessel> av_vessel, const bool& usetasks ) {
+     109             :   // cppcheck-suppress danglingLifetime
+     110          68 :   myaverage=av_vessel.get();
+     111          68 :   addVessel( std::move(av_vessel) );
+     112          68 :   useRunAllTasks=usetasks; resizeFunctions();
+     113          68 : }
+     114             : 
+     115        1240 : void ActionWithAveraging::lockRequests() {
+     116             :   ActionAtomistic::lockRequests();
+     117             :   ActionWithArguments::lockRequests();
+     118        1240 : }
+     119             : 
+     120        1240 : void ActionWithAveraging::unlockRequests() {
+     121             :   ActionAtomistic::unlockRequests();
+     122             :   ActionWithArguments::unlockRequests();
+     123        1240 : }
+     124             : 
+     125         374 : unsigned ActionWithAveraging::getNumberOfQuantities() const {
+     126         374 :   if( my_analysis_object ) return getNumberOfArguments()+2;
+     127             :   return 2;
+     128             : }
+     129             : 
+     130           0 : void ActionWithAveraging::calculateNumericalDerivatives(PLMD::ActionWithValue*) {
+     131           0 :   error("not possible to compute numerical derivatives for this action");
+     132             : }
+     133             : 
+     134        1258 : void ActionWithAveraging::update() {
+     135        1258 :   if( (clearstride!=1 && getStep()==0) || (!onStep() && !my_analysis_object) ) return;
+     136        1177 :   if( my_analysis_object ) {
+     137           7 :     analysis::ReadAnalysisFrames* myfram = dynamic_cast<analysis::ReadAnalysisFrames*>( my_analysis_object );
+     138           7 :     if( !activated && !myfram && !onStep() ) return ;
+     139           7 :     else if( !activated && !my_analysis_object->onStep() ) return ;
+     140             :   }
+     141             : 
+     142             :   // Clear if it is time to reset
+     143        1177 :   if( myaverage ) {
+     144        1176 :     if( myaverage->wasreset() ) clearAverage();
+     145             :   }
+     146             :   // Calculate the weight for all reweighting
+     147        1177 :   if ( weights.size()>0 && !my_analysis_object ) {
+     148        3018 :     double sum=0; for(unsigned i=0; i<weights.size(); ++i) sum+=weights[i]->get();
+     149        1009 :     lweight=sum; cweight = exp( sum );
+     150             :   } else {
+     151         168 :     lweight=0; cweight=1.0;
+     152             :   }
+     153             :   // Prepare the task list for averaging
+     154        1177 :   if( my_analysis_object ) {
+     155        2115 :     for(unsigned i=getFullNumberOfTasks(); i<my_analysis_object->getNumberOfDataPoints(); ++i) addTaskToList(i);
+     156           7 :     deactivateAllTasks(); cweight=0;
+     157        2115 :     for(unsigned i=0; i<my_analysis_object->getNumberOfDataPoints(); ++i) {
+     158        2108 :       taskFlags[i]=1; cweight += my_analysis_object->getWeight(i);
+     159             :     }
+     160           7 :     lockContributors();
+     161             :   }
+     162             :   // Prepare to do the averaging
+     163        1177 :   prepareForAveraging();
+     164             :   // Run all the tasks (if required
+     165        1177 :   if( my_analysis_object || useRunAllTasks ) runAllTasks();
+     166             :   // This the averaging if it is not done using task list
+     167        1032 :   else performOperations( true );
+     168             :   // Update the norm
+     169        1177 :   double normt = cweight; if( !my_analysis_object && normalization==ndata ) normt = 1;
+     170        1177 :   if( myaverage && my_analysis_object ) myaverage->setNorm( normt );
+     171        1170 :   else if( myaverage ) myaverage->setNorm( normt + myaverage->getNorm() );
+     172             :   // Finish the averaging
+     173        1177 :   finishAveraging();
+     174             :   // By resetting here we are ensuring that the grid will be cleared at the start of the next step
+     175        1177 :   if( myaverage ) {
+     176        1176 :     if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) myaverage->reset();
+     177             :   }
+     178             : }
+     179             : 
+     180       60010 : void ActionWithAveraging::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     181       60010 :   if( my_analysis_object ) {
+     182        2108 :     const analysis::DataCollectionObject& mystore=my_analysis_object->getStoredData( current, false );
+     183        4216 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) myvals.setValue( 1+i, mystore.getArgumentValue( ActionWithArguments::getArguments()[i]->getName() ) );
+     184        2108 :     myvals.setValue( 0, my_analysis_object->getWeight(current) );
+     185        2108 :     if( normalization==f ) myvals.setValue( 1+getNumberOfArguments(), 1.0 ); else myvals.setValue( 1+getNumberOfArguments(), 1.0 / cweight );
+     186        2108 :     accumulateAverage( myvals );
+     187             :   } else {
+     188       57902 :     runTask( current, myvals );
+     189             :   }
+     190       60010 : }
+     191             : 
+     192         102 : void ActionWithAveraging::clearAverage() { plumed_assert( myaverage->wasreset() ); myaverage->clear(); }
+     193             : 
+     194           0 : void ActionWithAveraging::performOperations( const bool& from_update ) { plumed_error(); }
+     195             : 
+     196          58 : void ActionWithAveraging::runFinalJobs() {
+     197          58 :   if( my_analysis_object && getStride()==0 ) { activated=true; update(); }
+     198          58 : }
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html b/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html new file mode 100644 index 0000000000..50a2db6e81 --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.func.html b/coverage/vesselbase/ActionWithAveraging.h.func.html new file mode 100644 index 0000000000..4841807db1 --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.gcov.html b/coverage/vesselbase/ActionWithAveraging.h.gcov.html new file mode 100644 index 0000000000..f81fa03aba --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.gcov.html @@ -0,0 +1,212 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..e7dcb16194 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_8KeywordsE30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.func.html b/coverage/vesselbase/ActionWithInputVessel.cpp.func.html new file mode 100644 index 0000000000..2e92ab261b --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel12readArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD10vesselbase21ActionWithInputVessel16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD10vesselbase21ActionWithInputVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase21ActionWithInputVessel29calculateNumericalDerivativesEPNS_15ActionWithValueE5
_ZN4PLMD10vesselbase21ActionWithInputVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase21ActionWithInputVesselC2ERKNS_13ActionOptionsE24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html new file mode 100644 index 0000000000..62542e4b6e --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + 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-05-27 13:05: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          30 : void ActionWithInputVessel::registerKeywords(Keywords& keys) {
+      32          60 :   keys.add("compulsory","DATA","certain actions in plumed work by calculating a list of variables and summing over them. "
+      33             :            "This particular action can be used to calculate functions of these base variables or prints "
+      34             :            "them to a file. This keyword thus takes the label of one of those such variables as input.");
+      35          60 :   keys.reserve("compulsory","GRID","the action that creates the input grid you would like to use");
+      36          30 : }
+      37             : 
+      38          24 : ActionWithInputVessel::ActionWithInputVessel(const ActionOptions&ao):
+      39             :   Action(ao),
+      40          24 :   arguments(NULL),
+      41          24 :   myBridgeVessel(NULL)
+      42             : {
+      43          24 : }
+      44             : 
+      45          24 : void ActionWithInputVessel::readArgument( const std::string& type ) {
+      46             :   std::string mlab;
+      47          96 :   if( keywords.exists("DATA") && type!="grid" ) parse("DATA",mlab);
+      48          24 :   ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<ActionWithVessel*>(mlab);
+      49          24 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      50          24 :   addDependency(mves);
+      51             : 
+      52          24 :   ActionWithValue* aval=dynamic_cast<ActionWithValue*>( this );
+      53          24 :   if(aval) {
+      54           2 :     if( aval->checkNumericalDerivatives() ) {
+      55           1 :       ActionWithValue* aval2=dynamic_cast<ActionWithValue*>( mves );
+      56           1 :       plumed_assert( aval2 ); aval2->useNumericalDerivatives();
+      57             :     }
+      58             :   }
+      59             : 
+      60          24 :   if( type=="bridge" ) {
+      61           2 :     ActionWithVessel* aves=dynamic_cast<ActionWithVessel*>( this );
+      62           2 :     plumed_assert(aves); myBridgeVessel = mves->addBridgingVessel( aves );
+      63           2 :     arguments = dynamic_cast<Vessel*>( myBridgeVessel );
+      64          22 :   } else  if( type=="store" ) {
+      65          22 :     arguments = dynamic_cast<Vessel*>( mves->buildDataStashes( NULL ) );
+      66             :   } else {
+      67           0 :     plumed_error();
+      68             :   }
+      69          24 : }
+      70             : 
+      71           5 : void ActionWithInputVessel::calculateNumericalDerivatives( ActionWithValue* a ) {
+      72           5 :   if(!a) {
+      73           5 :     a=dynamic_cast<ActionWithValue*>(this);
+      74           5 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+      75             :   }
+      76           5 :   if( myBridgeVessel ) {
+      77           5 :     myBridgeVessel->completeNumericalDerivatives();
+      78             :   } else {
+      79           0 :     error("numerical derivatives are not implemented");
+      80             :   }
+      81           5 : }
+      82             : 
+      83           0 : void ActionWithInputVessel::applyBridgeForces( const std::vector<double>& bb ) {
+      84           0 :   plumed_dbg_assert( myBridgeVessel ); addBridgeForces( bb );
+      85           0 : }
+      86             : 
+      87             : }
+      88             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html b/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html new file mode 100644 index 0000000000..88144dfe38 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.func.html b/coverage/vesselbase/ActionWithInputVessel.h.func.html new file mode 100644 index 0000000000..1cb87b93b8 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.gcov.html b/coverage/vesselbase/ActionWithInputVessel.h.gcov.html new file mode 100644 index 0000000000..0821477ece --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.gcov.html @@ -0,0 +1,146 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..4104105907 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html @@ -0,0 +1,176 @@ + + + + + + + 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-05-27 13:05: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_i359
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv417
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE555
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE570
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev570
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE796
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv812
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1375
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3316
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3316
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7222
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19966
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22991
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22991
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23504
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467194
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.func.html b/coverage/vesselbase/ActionWithVessel.cpp.func.html new file mode 100644 index 0000000000..ccd73be2c2 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.func.html @@ -0,0 +1,176 @@ + + + + + + + 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-05-27 13:05:14Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19966
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661369
_ZN4PLMD10vesselbase16ActionWithVessel14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23504
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1375
_ZN4PLMD10vesselbase16ActionWithVessel16buildDataStashesEPS1_192
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3316
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv812
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE796
_ZN4PLMD10vesselbase16ActionWithVessel17addBridgingVesselEPS1_46
_ZN4PLMD10vesselbase16ActionWithVessel17getVesselWithNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3316
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22991
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv417
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467194
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7222
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22991
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_i359
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE555
_ZN4PLMD10vesselbase16ActionWithVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE570
_ZN4PLMD10vesselbase16ActionWithVesselD0Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD1Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev570
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZNK4PLMD10vesselbase16ActionWithVessel27transformBridgedDerivativesERKjRNS_10MultiValueES5_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithVessel.cpp.gcov.html new file mode 100644 index 0000000000..ae6f929257 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.gcov.html @@ -0,0 +1,471 @@ + + + + + + + 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-05-27 13:05: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         796 : void ActionWithVessel::registerKeywords(Keywords& keys) {
+      38        1592 :   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        1592 :   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        1592 :   keys.addFlag("SERIAL",false,"do the calculation in serial.  Do not use MPI");
+      45        1592 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+      46        1592 :   keys.addFlag("TIMINGS",false,"output information on the timings of the various parts of the calculation");
+      47        1592 :   keys.reserveFlag("HIGHMEM",false,"use a more memory intensive version of this collective variable");
+      48         796 :   keys.add( vesselRegister().getKeywords() );
+      49         796 : }
+      50             : 
+      51         570 : ActionWithVessel::ActionWithVessel(const ActionOptions&ao):
+      52             :   Action(ao),
+      53         570 :   serial(false),
+      54         570 :   lowmem(false),
+      55         570 :   noderiv(true),
+      56         570 :   actionIsBridged(false),
+      57         570 :   nactive_tasks(0),
+      58         570 :   dertime_can_be_off(false),
+      59         570 :   dertime(true),
+      60         570 :   contributorsAreUnlocked(false),
+      61         570 :   weightHasDerivatives(false),
+      62         570 :   mydata(NULL)
+      63             : {
+      64         570 :   maxderivatives=309; parse("MAXDERIVATIVES",maxderivatives);
+      65        1677 :   if( keywords.exists("SERIAL") ) parseFlag("SERIAL",serial);
+      66          33 :   else serial=true;
+      67         570 :   if(serial)log.printf("  doing calculation in serial\n");
+      68        1140 :   if( keywords.exists("LOWMEM") ) {
+      69        1076 :     plumed_assert( !keywords.exists("HIGHMEM") );
+      70         538 :     parseFlag("LOWMEM",lowmem);
+      71         538 :     if(lowmem) {
+      72          29 :       log.printf("  lowering memory requirements\n");
+      73          29 :       dertime_can_be_off=true;
+      74             :     }
+      75             :   }
+      76        1140 :   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         570 :   tolerance=nl_tolerance=epsilon;
+      83        1599 :   if( keywords.exists("TOL") ) parse("TOL",tolerance);
+      84         570 :   if( tolerance>epsilon) {
+      85           6 :     log.printf(" Ignoring contributions less than %f \n",tolerance);
+      86             :   }
+      87         570 :   parseFlag("TIMINGS",timers);
+      88         570 :   stopwatch.start(); stopwatch.pause();
+      89         570 : }
+      90             : 
+      91         570 : ActionWithVessel::~ActionWithVessel() {
+      92         570 :   stopwatch.start(); stopwatch.stop();
+      93         570 :   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         570 : }
+      98             : 
+      99         359 : void ActionWithVessel::addVessel( const std::string& name, const std::string& input, const int numlab ) {
+     100         359 :   VesselOptions da(name,"",numlab,input,this);
+     101         718 :   auto vv=vesselRegister().create(name,da);
+     102         359 :   FunctionVessel* fv=dynamic_cast<FunctionVessel*>(vv.get());
+     103         359 :   if( fv ) {
+     104         329 :     std::string mylabel=Vessel::transformName( name );
+     105         329 :     plumed_massert( keywords.outputComponentExists(mylabel,false), "a description of the value calculated by vessel " + name + " has not been added to the manual");
+     106             :   }
+     107         359 :   addVessel(std::move(vv));
+     108         359 : }
+     109             : 
+     110         555 : 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         555 :   if(dynamic_cast<ShortcutVessel*>(vv_ptr.get())) return;
+     116             : 
+     117         544 :   vv_ptr->checkRead();
+     118             : 
+     119         544 :   StoreDataVessel* mm=dynamic_cast<StoreDataVessel*>( vv_ptr.get() );
+     120         544 :   if( mydata && mm ) error("cannot have more than one StoreDataVessel in one action");
+     121         544 :   else if( mm ) mydata=mm;
+     122         413 :   else dertime_can_be_off=false;
+     123             : 
+     124             : // Ownership is transferred to functions
+     125         544 :   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    12661369 : void ActionWithVessel::addTaskToList( const unsigned& taskCode ) {
+     160    12661369 :   fullTaskList.push_back( taskCode ); taskFlags.push_back(0);
+     161    12661369 :   plumed_assert( fullTaskList.size()==taskFlags.size() );
+     162    12661369 : }
+     163             : 
+     164         417 : void ActionWithVessel::readVesselKeywords() {
+     165             :   // Set maxderivatives if it is too big
+     166         417 :   if( maxderivatives>getNumberOfDerivatives() ) maxderivatives=getNumberOfDerivatives();
+     167             : 
+     168             :   // Loop over all keywords find the vessels and create appropriate functions
+     169       10136 :   for(unsigned i=0; i<keywords.size(); ++i) {
+     170        9719 :     std::string thiskey,input; thiskey=keywords.getKeyword(i);
+     171             :     // Check if this is a key for a vessel
+     172        9719 :     if( vesselRegister().check(thiskey) ) {
+     173        5526 :       plumed_assert( keywords.style(thiskey,"vessel") );
+     174        2763 :       bool dothis=false; parseFlag(thiskey,dothis);
+     175        2763 :       if(dothis) addVessel( thiskey, input );
+     176             : 
+     177        2763 :       parse(thiskey,input);
+     178        2763 :       if(input.size()!=0) {
+     179         125 :         addVessel( thiskey, input );
+     180             :       } else {
+     181        2638 :         for(unsigned i=1;; ++i) {
+     182        2663 :           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         417 :   if( functions.size()>0 ) resizeFunctions();
+     193         417 : }
+     194             : 
+     195        1375 : void ActionWithVessel::resizeFunctions() {
+     196        3548 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->resize();
+     197        1375 : }
+     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        3316 : void ActionWithVessel::lockContributors() {
+     212        3316 :   nactive_tasks = 0;
+     213    18492791 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     214    18489475 :     if( taskFlags[i]>0 ) nactive_tasks++;
+     215             :   }
+     216             : 
+     217             :   unsigned n=0;
+     218        3316 :   partialTaskList.resize( nactive_tasks );
+     219        3316 :   indexOfTaskInFullList.resize( nactive_tasks );
+     220    18492791 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     221             :     // Deactivate sets inactive tasks to number not equal to zero
+     222    18489475 :     if( taskFlags[i]>0 ) {
+     223     5482474 :       partialTaskList[n] = fullTaskList[i];
+     224     5482474 :       indexOfTaskInFullList[n]=i;
+     225     5482474 :       n++;
+     226             :     }
+     227             :   }
+     228             :   plumed_dbg_assert( n==nactive_tasks );
+     229        8196 :   for(unsigned i=0; i<functions.size(); ++i) {
+     230        4880 :     BridgeVessel* bb = dynamic_cast<BridgeVessel*>( functions[i].get() );
+     231        4880 :     if( bb ) bb->copyTaskFlags();
+     232             :   }
+     233             :   // Resize mydata to accommodate all active tasks
+     234        3316 :   if( mydata ) mydata->resize();
+     235        3316 :   contributorsAreUnlocked=false;
+     236        3316 : }
+     237             : 
+     238        3316 : void ActionWithVessel::deactivateAllTasks() {
+     239        3316 :   contributorsAreUnlocked=true; nactive_tasks = 0;
+     240        3316 :   taskFlags.assign(taskFlags.size(),0);
+     241        3316 : }
+     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       22991 : void ActionWithVessel::doJobsRequiredBeforeTaskList() {
+     248             :   // Do any preparatory stuff for functions
+     249       58260 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->prepare();
+     250       22991 : }
+     251             : 
+     252       23504 : unsigned ActionWithVessel::getSizeOfBuffer( unsigned& bufsize ) {
+     253       59449 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->setBufferStart( bufsize );
+     254       23504 :   if( buffer.size()!=bufsize ) buffer.resize( bufsize );
+     255       23504 :   if( mydata ) {
+     256             :     unsigned dsize=mydata->getSizeOfDerivativeList();
+     257        2554 :     if( der_list.size()!=dsize ) der_list.resize( dsize );
+     258             :   }
+     259       23504 :   return bufsize;
+     260             : }
+     261             : 
+     262       19966 : void ActionWithVessel::runAllTasks() {
+     263       19966 :   plumed_massert( !contributorsAreUnlocked && functions.size()>0, "you must have a call to readVesselKeywords somewhere" );
+     264       19966 :   unsigned stride=comm.Get_size();
+     265       19966 :   unsigned rank=comm.Get_rank();
+     266       19966 :   if(serial) { stride=1; rank=0; }
+     267             : 
+     268             :   // Make sure jobs are done
+     269       19966 :   if(timers) stopwatch.start("1 Prepare Tasks");
+     270       19966 :   doJobsRequiredBeforeTaskList();
+     271       19966 :   if(timers) stopwatch.stop("1 Prepare Tasks");
+     272             : 
+     273             :   // Get number of threads for OpenMP
+     274       19966 :   unsigned nt=OpenMP::getNumThreads();
+     275       19966 :   if( nt*stride*2>nactive_tasks || !threadSafe()) nt=1;
+     276             : 
+     277             :   // Get size for buffer
+     278       19966 :   unsigned bsize=0, bufsize=getSizeOfBuffer( bsize );
+     279             :   // Clear buffer
+     280       19966 :   buffer.assign( buffer.size(), 0.0 );
+     281             :   // Switch off calculation of derivatives in main loop
+     282       19966 :   if( dertime_can_be_off ) dertime=false;
+     283             : 
+     284       19966 :   if(timers) stopwatch.start("2 Loop over tasks");
+     285       19966 :   #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       19966 :   if(timers) stopwatch.stop("2 Loop over tasks");
+     323             :   // Turn back on derivative calculation
+     324       19966 :   dertime=true;
+     325             : 
+     326       19966 :   if(timers) stopwatch.start("3 MPI gather");
+     327             :   // MPI Gather everything
+     328       19966 :   if( !serial && buffer.size()>0 ) comm.Sum( buffer );
+     329             :   // MPI Gather index stores
+     330       19966 :   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       19966 :   if(timers) stopwatch.stop("3 MPI gather");
+     336             : 
+     337       19966 :   if(timers) stopwatch.start("4 Finishing computations");
+     338       19966 :   finishComputations( buffer );
+     339       19966 :   if(timers) stopwatch.stop("4 Finishing computations");
+     340       19966 : }
+     341             : 
+     342           0 : void ActionWithVessel::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+     343           0 :   plumed_error();
+     344             : }
+     345             : 
+     346      467194 : void ActionWithVessel::calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) {
+     347     1079096 :   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      611902 :     functions[j]->calculate( taskCode, functions[j]->transformDerivatives(taskCode, myvals, bvals), buffer, der_list );
+     351      611902 :     if( !actionIsBridged ) bvals.clearAll();
+     352             :   }
+     353      467194 :   return;
+     354             : }
+     355             : 
+     356       22991 : void ActionWithVessel::finishComputations( const std::vector<double>& buffer ) {
+     357             :   // Set the final value of the function
+     358       58260 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->finish( buffer );
+     359       22991 : }
+     360             : 
+     361        7222 : bool ActionWithVessel::getForcesFromVessels( std::vector<double>& forcesToApply ) {
+     362             : #ifndef NDEBUG
+     363             :   if( forcesToApply.size()>0 ) plumed_dbg_assert( forcesToApply.size()==getNumberOfDerivatives() );
+     364             : #endif
+     365        7222 :   if(tmpforces.size()!=forcesToApply.size() ) tmpforces.resize( forcesToApply.size() );
+     366             : 
+     367        7222 :   forcesToApply.assign( forcesToApply.size(),0.0 );
+     368             :   bool wasforced=false;
+     369       21110 :   for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     370       13888 :     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        7222 :   return wasforced;
+     376             : }
+     377             : 
+     378           0 : void ActionWithVessel::retrieveDomain( std::string& min, std::string& max ) {
+     379           0 :   plumed_merror("If your function is periodic you need to add a retrieveDomain function so that ActionWithVessel can retrieve the domain");
+     380             : }
+     381             : 
+     382           0 : Vessel* ActionWithVessel::getVesselWithName( const std::string& mynam ) {
+     383             :   int target=-1;
+     384           0 :   for(unsigned i=0; i<functions.size(); ++i) {
+     385           0 :     if( functions[i]->getName().find(mynam)!=std::string::npos ) {
+     386           0 :       if( target<0 ) target=i;
+     387           0 :       else error("found more than one " + mynam + " object in action");
+     388             :     }
+     389             :   }
+     390           0 :   plumed_assert(target>=0);
+     391           0 :   return functions[target].get();
+     392             : }
+     393             : 
+     394             : }
+     395             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html b/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html new file mode 100644 index 0000000000..cc620424f1 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196791
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.func.html b/coverage/vesselbase/ActionWithVessel.h.func.html new file mode 100644 index 0000000000..e99ac95e96 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196791
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.gcov.html b/coverage/vesselbase/ActionWithVessel.h.gcov.html new file mode 100644 index 0000000000..94b25f2ea3 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.gcov.html @@ -0,0 +1,367 @@ + + + + + + + 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-05-27 13:05: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      698726 :   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    12537462 :   return functions.size();
+     213             : }
+     214             : 
+     215             : inline
+     216      196791 : unsigned ActionWithVessel::getNumberOfQuantities() const {
+     217      196791 :   return 2;
+     218             : }
+     219             : 
+     220             : inline
+     221             : Vessel* ActionWithVessel::getPntrToVessel( const unsigned& i ) {
+     222             :   plumed_dbg_assert( i<functions.size() );
+     223        2502 :   return functions[i].get();
+     224             : }
+     225             : 
+     226             : inline
+     227             : unsigned ActionWithVessel::getFullNumberOfTasks() const {
+     228    15830326 :   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      714800 :   return !noderiv;
+     272             : }
+     273             : 
+     274             : inline
+     275             : bool ActionWithVessel::weightWithDerivatives() const {
+     276       13904 :   return weightHasDerivatives;
+     277             : }
+     278             : 
+     279             : inline
+     280      224556 : unsigned ActionWithVessel::getPositionInCurrentTaskList( const unsigned& myind ) const {
+     281      224556 :   if( nactive_tasks==fullTaskList.size() ) return myind;
+     282             : 
+     283   253764165 :   for(unsigned i=0; i<nactive_tasks; ++i) {
+     284   253764165 :     if( myind==indexOfTaskInFullList[i] ) return i;
+     285             :   }
+     286           0 :   plumed_merror("requested task is not active");
+     287             : }
+     288             : 
+     289             : }
+     290             : }
+     291             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.func-sort-c.html b/coverage/vesselbase/AltMin.cpp.func-sort-c.html new file mode 100644 index 0000000000..232de19325 --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_116AltMinRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev4168
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.func.html b/coverage/vesselbase/AltMin.cpp.func.html new file mode 100644 index 0000000000..5b49eca913 --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev4168
_ZN4PLMD10vesselbase6AltMin14finalTransformERKdRd5
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase6AltMin16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase6AltMin16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase6AltMinC2ERKNS0_13VesselOptionsE2
_ZNK4PLMD10vesselbase6AltMin13calcTransformERKdRd10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.gcov.html b/coverage/vesselbase/AltMin.cpp.gcov.html new file mode 100644 index 0000000000..51b6b8e6b7 --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.gcov.html @@ -0,0 +1,153 @@ + + + + + + + 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-05-27 13:05: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       12506 : 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        4168 : void AltMin::reserveKeyword( Keywords& keys ) {
+      48        8336 :   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        8336 :   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        4168 : }
+      55             : 
+      56           2 : AltMin::AltMin( const vesselbase::VesselOptions& da ):
+      57           2 :   FunctionVessel(da)
+      58             : {
+      59           2 :   if( getAction()->isPeriodic() ) error("MIN is not a meaningful option for periodic variables");
+      60           2 :   parse("BETA",beta); usetol=true;
+      61           2 : }
+      62             : 
+      63           2 : std::string AltMin::value_descriptor() {
+      64           2 :   std::string str_beta; Tools::convert( beta, str_beta );
+      65           4 :   return "the minimum value. Beta is equal to " + str_beta;
+      66             : }
+      67             : 
+      68          10 : double AltMin::calcTransform( const double& val, double& dv ) const {
+      69          10 :   double f = exp( -beta*val ); dv = -beta*f; return f;
+      70             : }
+      71             : 
+      72           5 : double AltMin::finalTransform( const double& val, double& dv ) {
+      73           5 :   dv = - 1.0 /(beta*val); return -std::log( val ) / beta;
+      74             : }
+      75             : 
+      76             : }
+      77             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html b/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..fcd059c3ea --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.func.html b/coverage/vesselbase/AveragingVessel.cpp.func.html new file mode 100644 index 0000000000..0d5cc68140 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.gcov.html b/coverage/vesselbase/AveragingVessel.cpp.gcov.html new file mode 100644 index 0000000000..8df20fc123 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.func-sort-c.html b/coverage/vesselbase/AveragingVessel.h.func-sort-c.html new file mode 100644 index 0000000000..bea5d2ea97 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.func-sort-c.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999387
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.func.html b/coverage/vesselbase/AveragingVessel.h.func.html new file mode 100644 index 0000000000..8695e356d3 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.func.html @@ -0,0 +1,80 @@ + + + + + + + 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-05-27 13:05:14Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999387
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.gcov.html b/coverage/vesselbase/AveragingVessel.h.gcov.html new file mode 100644 index 0000000000..e322b94700 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.gcov.html @@ -0,0 +1,177 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.func-sort-c.html b/coverage/vesselbase/Between.cpp.func-sort-c.html new file mode 100644 index 0000000000..522e4bf25f --- /dev/null +++ b/coverage/vesselbase/Between.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_117BetweenRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.func.html b/coverage/vesselbase/Between.cpp.func.html new file mode 100644 index 0000000000..124ad3cda8 --- /dev/null +++ b/coverage/vesselbase/Between.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMe6createERKNS0_13VesselOptionsE65
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase7Between16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD10vesselbase7Between16value_descriptorB5cxx11Ev65
_ZN4PLMD10vesselbase7Between9getCutoffEv60
_ZN4PLMD10vesselbase7BetweenC2ERKNS0_13VesselOptionsE65
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.gcov.html b/coverage/vesselbase/Between.cpp.gcov.html new file mode 100644 index 0000000000..294662820f --- /dev/null +++ b/coverage/vesselbase/Between.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + 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-05-27 13:05: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       12569 : 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        4168 : void Between::reserveKeyword( Keywords& keys ) {
+      38        8336 :   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        8336 :   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        4168 : }
+      45             : 
+      46          65 : Between::Between( const VesselOptions& da ) :
+      47          65 :   FunctionVessel(da)
+      48             : {
+      49          65 :   usetol=true;
+      50          65 :   bool isPeriodic=getAction()->isPeriodic();
+      51             :   double min, max; std::string str_min, str_max;
+      52          65 :   if( isPeriodic ) {
+      53           1 :     getAction()->retrieveDomain( str_min, str_max );
+      54           1 :     Tools::convert(str_min,min); Tools::convert(str_max,max);
+      55             :   }
+      56             : 
+      57         130 :   parseFlag("NORM",norm); std::string errormsg;
+      58             : 
+      59          65 :   hist.set( getAllInput(),errormsg );
+      60          65 :   if( !isPeriodic ) hist.isNotPeriodic();
+      61           1 :   else hist.isPeriodic( min, max );
+      62          65 :   if( errormsg.size()!=0 ) error( errormsg );
+      63          65 : }
+      64             : 
+      65          65 : std::string Between::value_descriptor() {
+      66          66 :   if(norm) return "the fraction of values " + hist.description();
+      67         128 :   return "the number of values " + hist.description();
+      68             : }
+      69             : 
+      70        8224 : double Between::calcTransform( const double& val, double& dv ) const {
+      71        8224 :   double f = hist.calculate(val, dv); return f;
+      72             : }
+      73             : 
+      74          60 : double Between::getCutoff() {
+      75          60 :   return std::numeric_limits<double>::max();
+      76             : }
+      77             : 
+      78             : }
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html b/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..d83221e7cb --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.func.html b/coverage/vesselbase/BridgeVessel.cpp.func.html new file mode 100644 index 0000000000..a26f39947b --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.func.html @@ -0,0 +1,124 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.gcov.html b/coverage/vesselbase/BridgeVessel.cpp.gcov.html new file mode 100644 index 0000000000..cdc163b252 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.func-sort-c.html b/coverage/vesselbase/BridgeVessel.h.func-sort-c.html new file mode 100644 index 0000000000..04d9d5ea11 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.func.html b/coverage/vesselbase/BridgeVessel.h.func.html new file mode 100644 index 0000000000..0ad2d49dc1 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.gcov.html b/coverage/vesselbase/BridgeVessel.h.gcov.html new file mode 100644 index 0000000000..482c5cae11 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html b/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..72442203b8 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE329
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE329
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv912
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22778
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26616
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244832
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.func.html b/coverage/vesselbase/FunctionVessel.cpp.func.html new file mode 100644 index 0000000000..b052767cf5 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22778
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE329
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26616
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv912
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE329
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244832
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.gcov.html b/coverage/vesselbase/FunctionVessel.cpp.gcov.html new file mode 100644 index 0000000000..51b3cbebf0 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.gcov.html @@ -0,0 +1,180 @@ + + + + + + + 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-05-27 13:05: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         329 : void FunctionVessel::registerKeywords( Keywords& keys ) {
+      29         329 :   ValueVessel::registerKeywords( keys );
+      30         329 : }
+      31             : 
+      32         329 : FunctionVessel::FunctionVessel( const VesselOptions& da ):
+      33             :   ValueVessel(da),
+      34         329 :   norm(false),
+      35         329 :   usetol(false)
+      36             : {
+      37         329 :   diffweight=getAction()->weightHasDerivatives;
+      38         329 : }
+      39             : 
+      40         912 : void FunctionVessel::resize() {
+      41         912 :   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         372 :     diffweight=false;  // Don't need to worry about differentiable weights if no derivatives
+      49             :   }
+      50         912 : }
+      51             : 
+      52      244832 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      53      244832 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      54             :   double weight=myvals.get(0);
+      55             :   plumed_dbg_assert( weight>=getTolerance() );
+      56             : 
+      57             :   // This deals with the value
+      58      244832 :   double dval, f=calcTransform( myvals.get(mycomp), dval );
+      59             : 
+      60      244832 :   if( norm ) {
+      61       82908 :     if( usetol && weight<getTolerance() ) return;
+      62       82908 :     buffer[bufstart+1+nderivatives] += weight;
+      63       82908 :     if( getAction()->derivativesAreRequired() && diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
+      64             :   }
+      65             : 
+      66      244832 :   double contr=weight*f;
+      67      244832 :   if( usetol && contr<getTolerance() ) return;
+      68      239910 :   buffer[bufstart] += contr;
+      69             : 
+      70      239910 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer );
+      71      239910 :   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       26616 : void FunctionVessel::finish( const std::vector<double>& buffer ) {
+      81       26616 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      82       26616 :   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       26616 :   } else if( norm ) {
+      89        1227 :     double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
+      90        1227 :     getFinalValue()->set( val / weight );
+      91      156783 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight );
+      92             :   } else {
+      93       20275 :     double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val );
+      94     1530087 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] );
+      95             :   }
+      96       26616 : }
+      97             : 
+      98       22778 : double FunctionVessel::finalTransform( const double& val, double& dv ) {
+      99       22778 :   dv=1.0; return val;
+     100             : }
+     101             : 
+     102             : }
+     103             : }
+     104             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.func-sort-c.html b/coverage/vesselbase/FunctionVessel.h.func-sort-c.html new file mode 100644 index 0000000000..fb3ab1bed0 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.func.html b/coverage/vesselbase/FunctionVessel.h.func.html new file mode 100644 index 0000000000..7dffb7689d --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.gcov.html b/coverage/vesselbase/FunctionVessel.h.gcov.html new file mode 100644 index 0000000000..705a5fd644 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.func-sort-c.html b/coverage/vesselbase/Highest.cpp.func-sort-c.html new file mode 100644 index 0000000000..758629d480 --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.func.html b/coverage/vesselbase/Highest.cpp.func.html new file mode 100644 index 0000000000..ed4dc11dee --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMe6createERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase7Highest16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD10vesselbase7Highest16value_descriptorB5cxx11Ev5
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
_ZN4PLMD10vesselbase7HighestC2ERKNS0_13VesselOptionsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.gcov.html b/coverage/vesselbase/Highest.cpp.gcov.html new file mode 100644 index 0000000000..3f148b2bf3 --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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       12509 : PLUMED_REGISTER_VESSEL(Highest,"HIGHEST")
+      38             : 
+      39           5 : void Highest::registerKeywords( Keywords& keys ) {
+      40           5 :   OrderingVessel::registerKeywords( keys );
+      41           5 : }
+      42             : 
+      43        4168 : void Highest::reserveKeyword( Keywords& keys ) {
+      44        8336 :   keys.reserve("vessel","HIGHEST","this flag allows you to recover the highest of these variables.");
+      45        8336 :   keys.addOutputComponent("highest","HIGHEST","the highest of the quantities calculated by this action");
+      46        4168 : }
+      47             : 
+      48           5 : Highest::Highest( const VesselOptions& da ) :
+      49           5 :   OrderingVessel(da)
+      50             : {
+      51           5 : }
+      52             : 
+      53           5 : std::string Highest::value_descriptor() {
+      54           5 :   return "the highest of the individual colvar values";
+      55             : }
+      56             : 
+      57        4047 : bool Highest::compare( const double& val1, const double& val2 ) {
+      58        4047 :   return val1>val2;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.func-sort-c.html b/coverage/vesselbase/Histogram.cpp.func-sort-c.html new file mode 100644 index 0000000000..a7fc1f48e1 --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.func-sort-c.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05: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_119HistogramRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev4168
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.func.html b/coverage/vesselbase/Histogram.cpp.func.html new file mode 100644 index 0000000000..333569f07d --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.func.html @@ -0,0 +1,96 @@ + + + + + + + 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-05-27 13:05:14Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMe6createERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev4168
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase9Histogram16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase9HistogramC2ERKNS0_13VesselOptionsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.gcov.html b/coverage/vesselbase/Histogram.cpp.gcov.html new file mode 100644 index 0000000000..52818441b3 --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + 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-05-27 13:05: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       12515 : 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        4168 : void Histogram::reserveKeyword( Keywords& keys ) {
+      47        8336 :   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        4168 : }
+      50             : 
+      51          11 : Histogram::Histogram( const VesselOptions& da ):
+      52          11 :   ShortcutVessel(da)
+      53             : {
+      54          22 :   bool norm; parseFlag("NORM",norm); std::string normstr="";
+      55          11 :   if(norm) normstr=" NORM";
+      56          11 :   std::string compstr; parse("COMPONENT",compstr);
+      57          22 :   normstr+=" COMPONENT=" + compstr;
+      58          11 :   std::vector<std::string> bins; HistogramBead::generateBins( getAllInput(), bins );
+      59          43 :   for(unsigned i=0; i<bins.size(); ++i) addVessel("BETWEEN",bins[i] + normstr);
+      60          22 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.func-sort-c.html b/coverage/vesselbase/LessThan.cpp.func-sort-c.html new file mode 100644 index 0000000000..cc1021afe5 --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_118LessThanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57355
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.func.html b/coverage/vesselbase/LessThan.cpp.func.html new file mode 100644 index 0000000000..76bc73a82a --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMe6createERKNS0_13VesselOptionsE59
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase8LessThan16registerKeywordsERNS_8KeywordsE59
_ZN4PLMD10vesselbase8LessThan16value_descriptorB5cxx11Ev59
_ZN4PLMD10vesselbase8LessThan9getCutoffEv16
_ZN4PLMD10vesselbase8LessThanC2ERKNS0_13VesselOptionsE59
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57355
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.gcov.html b/coverage/vesselbase/LessThan.cpp.gcov.html new file mode 100644 index 0000000000..7dac400075 --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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       12563 : 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        4168 : void LessThan::reserveKeyword( Keywords& keys ) {
+      36        8336 :   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        8336 :   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        4168 : }
+      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.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.func-sort-c.html b/coverage/vesselbase/Lowest.cpp.func-sort-c.html new file mode 100644 index 0000000000..0b75515a5e --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_116LowestRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev4168
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.func.html b/coverage/vesselbase/Lowest.cpp.func.html new file mode 100644 index 0000000000..085c2c9116 --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev4168
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase6Lowest16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase6Lowest16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase6Lowest7compareERKdS3_68
_ZN4PLMD10vesselbase6LowestC2ERKNS0_13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.gcov.html b/coverage/vesselbase/Lowest.cpp.gcov.html new file mode 100644 index 0000000000..cbe6d3a6c6 --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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       12507 : PLUMED_REGISTER_VESSEL(Lowest,"LOWEST")
+      38             : 
+      39           3 : void Lowest::registerKeywords( Keywords& keys ) {
+      40           3 :   OrderingVessel::registerKeywords( keys );
+      41           3 : }
+      42             : 
+      43        4168 : void Lowest::reserveKeyword( Keywords& keys ) {
+      44        8336 :   keys.reserve("vessel","LOWEST","this flag allows you to recover the lowest of these variables.");
+      45        8336 :   keys.addOutputComponent("lowest","LOWEST","the lowest of the quantities calculated by this action");
+      46        4168 : }
+      47             : 
+      48           3 : Lowest::Lowest( const VesselOptions& da ) :
+      49           3 :   OrderingVessel(da)
+      50             : {
+      51           3 : }
+      52             : 
+      53           3 : std::string Lowest::value_descriptor() {
+      54           3 :   return "the lowest of the individual colvar values";
+      55             : }
+      56             : 
+      57          68 : bool Lowest::compare( const double& val1, const double& val2 ) {
+      58          68 :   return val1<val2;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.func-sort-c.html b/coverage/vesselbase/Max.cpp.func-sort-c.html new file mode 100644 index 0000000000..887ce74abe --- /dev/null +++ b/coverage/vesselbase/Max.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_113MaxRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.func.html b/coverage/vesselbase/Max.cpp.func.html new file mode 100644 index 0000000000..899fccdb55 --- /dev/null +++ b/coverage/vesselbase/Max.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Max14finalTransformERKdRd6
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase3Max16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Max16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MaxC2ERKNS0_13VesselOptionsE3
_ZNK4PLMD10vesselbase3Max13calcTransformERKdRd13
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.gcov.html b/coverage/vesselbase/Max.cpp.gcov.html new file mode 100644 index 0000000000..04fc88a88e --- /dev/null +++ b/coverage/vesselbase/Max.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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       12507 : 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        4168 : void Max::reserveKeyword( Keywords& keys ) {
+      49        8336 :   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        8336 :   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        4168 : }
+      57             : 
+      58           3 : Max::Max( const VesselOptions& da ) :
+      59           3 :   FunctionVessel(da)
+      60             : {
+      61           3 :   if( getAction()->isPeriodic() ) error("max is not a meaningful option for periodic variables");
+      62           3 :   parse("BETA",beta);
+      63             : 
+      64           3 :   if( diffweight ) error("can't calculate max if weight is differentiable");
+      65           3 : }
+      66             : 
+      67           3 : std::string Max::value_descriptor() {
+      68           3 :   std::string str_beta; Tools::convert( beta, str_beta );
+      69           6 :   return "the maximum value. Beta is equal to " + str_beta;
+      70             : }
+      71             : 
+      72          13 : double Max::calcTransform( const double& val, double& dv ) const {
+      73          13 :   double f = exp(val/beta); dv=f/beta; return f;
+      74             : }
+      75             : 
+      76           6 : double Max::finalTransform( const double& val, double& dv ) {
+      77           6 :   double dist=beta*std::log( val );
+      78           6 :   dv = beta/val; return dist;
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.func-sort-c.html b/coverage/vesselbase/Mean.cpp.func-sort-c.html new file mode 100644 index 0000000000..0171a560e5 --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE84
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev84
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE84
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.func.html b/coverage/vesselbase/Mean.cpp.func.html new file mode 100644 index 0000000000..cb6f5cc663 --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE84
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE84
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev84
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE84
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.gcov.html b/coverage/vesselbase/Mean.cpp.gcov.html new file mode 100644 index 0000000000..680b1beab5 --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.gcov.html @@ -0,0 +1,142 @@ + + + + + + + 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-05-27 13:05: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       12588 : PLUMED_REGISTER_VESSEL(Mean,"MEAN")
+      39             : 
+      40          84 : void Mean::registerKeywords( Keywords& keys ) {
+      41          84 :   FunctionVessel::registerKeywords(keys);
+      42          84 : }
+      43             : 
+      44        4168 : void Mean::reserveKeyword( Keywords& keys ) {
+      45        8336 :   keys.reserve("vessel","MEAN","take the mean of these variables.");
+      46        8336 :   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        4168 : }
+      49             : 
+      50          84 : Mean::Mean( const vesselbase::VesselOptions& da ) :
+      51          84 :   FunctionVessel(da)
+      52             : {
+      53          84 :   if( getAction()->isPeriodic() ) error("MEAN cannot be used with periodic variables");
+      54          84 :   norm=true;   // Makes sure we calculate the average
+      55          84 : }
+      56             : 
+      57          84 : std::string Mean::value_descriptor() {
+      58          84 :   return "the mean value";
+      59             : }
+      60             : 
+      61       80199 : double Mean::calcTransform( const double& val, double& dv ) const {
+      62       80199 :   dv=1.0; return val;
+      63             : }
+      64             : 
+      65             : }
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.func-sort-c.html b/coverage/vesselbase/Min.cpp.func-sort-c.html new file mode 100644 index 0000000000..42720bd858 --- /dev/null +++ b/coverage/vesselbase/Min.cpp.func-sort-c.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05: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_113MinRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE4168
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.func.html b/coverage/vesselbase/Min.cpp.func.html new file mode 100644 index 0000000000..0310b329c5 --- /dev/null +++ b/coverage/vesselbase/Min.cpp.func.html @@ -0,0 +1,108 @@ + + + + + + + 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-05-27 13:05:14Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Min14finalTransformERKdRd5
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase3Min16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase3Min16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase3MinC2ERKNS0_13VesselOptionsE2
_ZNK4PLMD10vesselbase3Min13calcTransformERKdRd10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.gcov.html b/coverage/vesselbase/Min.cpp.gcov.html new file mode 100644 index 0000000000..a2469017d9 --- /dev/null +++ b/coverage/vesselbase/Min.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + 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-05-27 13:05: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       12506 : 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        4168 : void Min::reserveKeyword( Keywords& keys ) {
+      49        8336 :   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        8336 :   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        4168 : }
+      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.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.func-sort-c.html b/coverage/vesselbase/Moments.cpp.func-sort-c.html new file mode 100644 index 0000000000..cb9068d60c --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05: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_117MomentsRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.func.html b/coverage/vesselbase/Moments.cpp.func.html new file mode 100644 index 0000000000..9db1cfd735 --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMe6createERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev4168
_ZN4PLMD10vesselbase7Moments10applyForceERSt6vectorIdSaIdEE432
_ZN4PLMD10vesselbase7Moments11descriptionB5cxx11Ev8
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase7Moments16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase7Moments6finishERKSt6vectorIdSaIdEE822
_ZN4PLMD10vesselbase7Moments6resizeEv28
_ZN4PLMD10vesselbase7MomentsC2ERKNS0_13VesselOptionsE8
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.gcov.html b/coverage/vesselbase/Moments.cpp.gcov.html new file mode 100644 index 0000000000..94dcd8fc98 --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.gcov.html @@ -0,0 +1,267 @@ + + + + + + + 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-05-27 13:05: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       12512 : 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        4168 : void Moments::reserveKeyword( Keywords& keys ) {
+      61        8336 :   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        8336 :   keys.reset_style("MOMENTS","vessel");
+      68        8336 :   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        4168 : }
+      72             : 
+      73           8 : Moments::Moments( const vesselbase::VesselOptions& da) :
+      74           8 :   Vessel(da)
+      75             : {
+      76           8 :   mystash = getAction()->buildDataStashes( NULL );
+      77           8 :   ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
+      78           8 :   plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
+      79             : 
+      80           8 :   std::vector<std::string> moments; std::string valstr = "moment-";
+      81          24 :   parse("COMPONENT",mycomponent); parseVector("MOMENTS",moments);
+      82          10 :   if( getNumericalLabel()!=0 ) { std::string numstr; Tools::convert( mycomponent, numstr); valstr = "moment-" + numstr + "-"; }
+      83          14 :   if( moments.size()==0 ) moments=Tools::getWords(getAllInput(),"\t\n ,");
+      84           8 :   Tools::interpretRanges(moments); unsigned nn;
+      85          20 :   for(unsigned i=0; i<moments.size(); ++i) {
+      86          24 :     a->addComponentWithDerivatives( valstr + moments[i] );
+      87          24 :     a->componentIsNotPeriodic( valstr + moments[i] );
+      88          12 :     value_out.push_back( a->copyOutput( a->getNumberOfComponents()-1 ) );
+      89          12 :     Tools::convert( moments[i], nn );
+      90          12 :     if( nn<2 ) error("moments are only possible for m>=2" );
+      91          12 :     powers.push_back( nn ); std::string num; Tools::convert(powers[i],num);
+      92             :   }
+      93           8 : }
+      94             : 
+      95          28 : void Moments::resize() {
+      96             :   resizeBuffer(0);
+      97          28 :   if( getAction()->derivativesAreRequired() ) {
+      98          56 :     for(unsigned i=0; i<value_out.size(); ++i) value_out[i]->resizeDerivatives( getAction()->getNumberOfDerivatives() );
+      99             :   }
+     100          28 : }
+     101             : 
+     102           8 : std::string Moments::description() {
+     103             :   std::string descri, num;
+     104           8 :   Tools::convert(powers[0],num);
+     105           8 :   if( getNumericalLabel()==0 ) {
+     106          12 :     descri = "value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
+     107           8 :     for(unsigned i=1; i<powers.size(); ++i) {
+     108           2 :       Tools::convert(powers[i],num);
+     109           4 :       descri = descri + "\n  value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
+     110             :     }
+     111             :   } else {
+     112           2 :     std::string numlab; Tools::convert( mycomponent, numlab );
+     113           4 :     descri = "value " + getAction()->getLabel() + "." + "moment-" + numlab + "-" + num + " contains the " + num + "th moment for the distribution of component " + numlab;
+     114           4 :     for(unsigned i=1; i<powers.size(); ++i) {
+     115           2 :       Tools::convert(powers[i],num);
+     116           4 :       descri = descri + "\n  value " + getAction()->getLabel() + "." + "moment-" + numlab + "-" + num + " contains the " + num + "th moment for the distribution of component " + numlab;
+     117             :     }
+     118             :   }
+     119           8 :   return descri;
+     120             : }
+     121             : 
+     122         822 : void Moments::finish( const std::vector<double>& buffer ) {
+     123             :   const double pi=3.141592653589793238462643383279502884197169399375105820974944592307;
+     124             :   unsigned nvals=getAction()->getFullNumberOfTasks();
+     125         822 :   std::vector<double>  myvalues( getAction()->getNumberOfQuantities() );
+     126             : 
+     127         822 :   double mean=0; Value myvalue;
+     128         822 :   if( getAction()->isPeriodic() ) {
+     129           0 :     std::string str_min, str_max; getAction()->retrieveDomain( str_min, str_max );
+     130           0 :     double pfactor, min, max; Tools::convert(str_min,min); Tools::convert(str_max,max);
+     131           0 :     pfactor = 2*pi / ( max-min ); myvalue.setDomain( str_min, str_max );
+     132             :     double sinsum=0, cossum=0, val;
+     133           0 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     134           0 :       mystash->retrieveSequentialValue( i, false, myvalues );
+     135           0 :       val=pfactor*( myvalues[mycomponent] - min );
+     136           0 :       sinsum+=std::sin(val); cossum+=std::cos(val);
+     137             :     }
+     138           0 :     mean = 0.5 + std::atan2( sinsum / static_cast<double>( nvals ), cossum / static_cast<double>( nvals ) ) / (2*pi);
+     139           0 :     mean = min + (max-min)*mean;
+     140             :   } else {
+     141        7758 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     142        6936 :       mystash->retrieveSequentialValue( i, false, myvalues ); mean+=myvalues[mycomponent];
+     143             :     }
+     144         822 :     mean/=static_cast<double>( nvals ); myvalue.setNotPeriodic();
+     145             :   }
+     146             : 
+     147        2056 :   for(unsigned npow=0; npow<powers.size(); ++npow) {
+     148             :     double dev1=0;
+     149        1234 :     if( value_out[0]->getNumberOfDerivatives()>0 ) {
+     150        4606 :       for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     151        4172 :         mystash->retrieveSequentialValue( i, false, myvalues );
+     152        4172 :         dev1+=pow( myvalue.difference( mean, myvalues[mycomponent] ), powers[npow] - 1 );
+     153             :       }
+     154         434 :       dev1/=static_cast<double>( nvals );
+     155             :     }
+     156             : 
+     157             :     double moment=0;
+     158        1234 :     MultiValue myvals( getAction()->getNumberOfQuantities(), getAction()->getNumberOfDerivatives() ); myvals.clearAll();
+     159       11006 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     160        9772 :       mystash->retrieveSequentialValue( i, false, myvalues );
+     161        9772 :       double tmp=myvalue.difference( mean, myvalues[mycomponent] );
+     162        9772 :       moment+=pow( tmp, powers[npow] );
+     163        9772 :       if( value_out[npow]->getNumberOfDerivatives() ) {
+     164        4172 :         double pref=pow( tmp, powers[npow] - 1 ) - dev1;
+     165        4172 :         mystash->retrieveDerivatives( i, false, myvals );
+     166      166880 :         for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     167             :           unsigned jatom=myvals.getActiveIndex(j);
+     168      162708 :           value_out[npow]->addDerivative(jatom, pref*myvals.getDerivative( mycomponent, jatom ) );
+     169             :         }
+     170        4172 :         myvals.clearAll();
+     171             :       }
+     172             :     }
+     173        1234 :     if( value_out[npow]->getNumberOfDerivatives()>0 ) value_out[npow]->chainRule( powers[npow] / static_cast<double>( nvals ) );
+     174        1234 :     value_out[npow]->set( moment / static_cast<double>( nvals ) );
+     175        1234 :   }
+     176        1644 : }
+     177             : 
+     178         432 : bool Moments::applyForce( std::vector<double>& forces ) {
+     179         432 :   std::vector<double> tmpforce( forces.size() );
+     180         432 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+     181        1276 :   for(unsigned i=0; i<value_out.size(); ++i) {
+     182         844 :     if( value_out[i]->applyForce( tmpforce ) ) {
+     183             :       wasforced=true;
+     184           0 :       for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+     185             :     }
+     186             :   }
+     187         432 :   return wasforced;
+     188             : }
+     189             : 
+     190             : }
+     191             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.func-sort-c.html b/coverage/vesselbase/MoreThan.cpp.func-sort-c.html new file mode 100644 index 0000000000..b61071851e --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE32
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev32
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE32
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd19012
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.func.html b/coverage/vesselbase/MoreThan.cpp.func.html new file mode 100644 index 0000000000..0ca170bd55 --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE32
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev4168
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev32
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE32
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd19012
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.gcov.html b/coverage/vesselbase/MoreThan.cpp.gcov.html new file mode 100644 index 0000000000..acc5dbe9e9 --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.gcov.html @@ -0,0 +1,152 @@ + + + + + + + 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-05-27 13:05: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       12536 : PLUMED_REGISTER_VESSEL(MoreThan,"MORE_THAN")
+      43             : 
+      44          32 : void MoreThan::registerKeywords( Keywords& keys ) {
+      45          32 :   FunctionVessel::registerKeywords( keys );
+      46          32 :   SwitchingFunction::registerKeywords( keys );
+      47          32 : }
+      48             : 
+      49        4168 : void MoreThan::reserveKeyword( Keywords& keys ) {
+      50        8336 :   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        8336 :   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        4168 : }
+      57             : 
+      58          32 : MoreThan::MoreThan( const VesselOptions& da ) :
+      59          32 :   FunctionVessel(da)
+      60             : {
+      61          32 :   usetol=true;
+      62          32 :   if( getAction()->isPeriodic() ) error("more than is not a meaningful option for periodic variables");
+      63          64 :   std::string errormsg; sf.set( getAllInput(), errormsg );
+      64          32 :   if( errormsg.size()!=0 ) error( errormsg );
+      65          32 : }
+      66             : 
+      67          32 : std::string MoreThan::value_descriptor() {
+      68          64 :   return "the number of values more than " + sf.description();
+      69             : }
+      70             : 
+      71       19012 : double MoreThan::calcTransform( const double& val, double& dv ) const {
+      72       19012 :   double f = 1.0 - sf.calculate(val, dv); dv*=-val; return f;
+      73             : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html b/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..8f7dfa7d70 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.func.html b/coverage/vesselbase/OrderingVessel.cpp.func.html new file mode 100644 index 0000000000..64f81a00de --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.gcov.html b/coverage/vesselbase/OrderingVessel.cpp.gcov.html new file mode 100644 index 0000000000..205985bfb3 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.func-sort-c.html b/coverage/vesselbase/OrderingVessel.h.func-sort-c.html new file mode 100644 index 0000000000..dfbd4bc1e1 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.func-sort-c.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.func.html b/coverage/vesselbase/OrderingVessel.h.func.html new file mode 100644 index 0000000000..8928b3e22f --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.func.html @@ -0,0 +1,76 @@ + + + + + + + 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-05-27 13:05:14Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.gcov.html b/coverage/vesselbase/OrderingVessel.h.gcov.html new file mode 100644 index 0000000000..4d6402c5d2 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html b/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..98fee08c88 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.func.html b/coverage/vesselbase/ShortcutVessel.cpp.func.html new file mode 100644 index 0000000000..707706d9a0 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.func.html @@ -0,0 +1,84 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.gcov.html b/coverage/vesselbase/ShortcutVessel.cpp.gcov.html new file mode 100644 index 0000000000..7b1dc78acc --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.gcov.html @@ -0,0 +1,123 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html b/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html new file mode 100644 index 0000000000..3cda4ce717 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.func.html b/coverage/vesselbase/ShortcutVessel.h.func.html new file mode 100644 index 0000000000..5083483f81 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.func.html @@ -0,0 +1,92 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.gcov.html b/coverage/vesselbase/ShortcutVessel.h.gcov.html new file mode 100644 index 0000000000..b79d637acf --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html b/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..f46e4c45b1 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.func.html b/coverage/vesselbase/StoreDataVessel.cpp.func.html new file mode 100644 index 0000000000..c3b9643d55 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.func.html @@ -0,0 +1,132 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.gcov.html b/coverage/vesselbase/StoreDataVessel.cpp.gcov.html new file mode 100644 index 0000000000..d70d637780 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.gcov.html @@ -0,0 +1,255 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html b/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html new file mode 100644 index 0000000000..f3cf668694 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.func.html b/coverage/vesselbase/StoreDataVessel.h.func.html new file mode 100644 index 0000000000..18f1665b70 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.gcov.html b/coverage/vesselbase/StoreDataVessel.h.gcov.html new file mode 100644 index 0000000000..7fa4f94d77 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.gcov.html @@ -0,0 +1,286 @@ + + + + + + + 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-05-27 13:05: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.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.func-sort-c.html b/coverage/vesselbase/Sum.cpp.func-sort-c.html new file mode 100644 index 0000000000..4c8c00c89a --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05: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_113SumRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE4168
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.func.html b/coverage/vesselbase/Sum.cpp.func.html new file mode 100644 index 0000000000..d9932abbed --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + 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-05-27 13:05:14Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMe6createERKNS0_13VesselOptionsE57
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeC2Ev4168
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev4168
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE4168
_ZN4PLMD10vesselbase3Sum16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD10vesselbase3Sum16value_descriptorB5cxx11Ev57
_ZN4PLMD10vesselbase3SumC2ERKNS0_13VesselOptionsE57
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.gcov.html b/coverage/vesselbase/Sum.cpp.gcov.html new file mode 100644 index 0000000000..d8d7237fc5 --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.gcov.html @@ -0,0 +1,138 @@ + + + + + + + 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-05-27 13:05: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       12561 : PLUMED_REGISTER_VESSEL(Sum,"SUM")
+      38             : 
+      39          57 : void Sum::registerKeywords( Keywords& keys ) {
+      40          57 :   FunctionVessel::registerKeywords( keys );
+      41          57 : }
+      42             : 
+      43        4168 : void Sum::reserveKeyword( Keywords& keys ) {
+      44        8336 :   keys.reserve("vessel","SUM","calculate the sum of all the quantities.");
+      45        8336 :   keys.addOutputComponent("sum","SUM","the sum of values");
+      46        4168 : }
+      47             : 
+      48          57 : Sum::Sum( const VesselOptions& da ) :
+      49          57 :   FunctionVessel(da)
+      50             : {
+      51          57 : }
+      52             : 
+      53          57 : std::string Sum::value_descriptor() {
+      54          57 :   return "the sum of all the values";
+      55             : }
+      56             : 
+      57       60444 : double Sum::calcTransform( const double& val, double& dv ) const {
+      58       60444 :   dv=1.0; return val;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html b/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..fa88815cbb --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev337
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE337
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE337
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11445
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.func.html b/coverage/vesselbase/ValueVessel.cpp.func.html new file mode 100644 index 0000000000..f1d51d4abe --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.func.html @@ -0,0 +1,88 @@ + + + + + + + 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-05-27 13:05:14Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11445
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev337
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE337
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE337
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.gcov.html b/coverage/vesselbase/ValueVessel.cpp.gcov.html new file mode 100644 index 0000000000..225ad62976 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + 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-05-27 13:05: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         337 : void ValueVessel::registerKeywords( Keywords& keys ) {
+      28         337 :   Vessel::registerKeywords( keys );
+      29         674 :   keys.add("compulsory","COMPONENT","1","the component of the vector for which to calculate this quantity");
+      30         337 : }
+      31             : 
+      32         337 : ValueVessel::ValueVessel( const VesselOptions& da ):
+      33         337 :   Vessel(da)
+      34             : {
+      35         674 :   parse("COMPONENT",mycomp);
+      36         337 :   ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
+      37         337 :   plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
+      38             :   int numval = getNumericalLabel();
+      39         337 :   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         301 :   } 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         598 :     plumed_massert( !a->exists(getAction()->getLabel() + "." + getLabel() ), "you can't create the name multiple times");
+      49         299 :     a->addComponentWithDerivatives( getLabel() );
+      50         598 :     a->componentIsNotPeriodic( getLabel() );
+      51         299 :     final_value=a->copyOutput( a->getNumberOfComponents()-1 );
+      52             :   }
+      53         337 : }
+      54             : 
+      55         337 : std::string ValueVessel::description() {
+      56         373 :   if( final_value->getName()==getAction()->getLabel() ) return "value " + getAction()->getLabel() + " contains " + value_descriptor();
+      57         301 :   std::string compstr; Tools::convert(mycomp,compstr);
+      58         602 :   return "value " + getAction()->getLabel() + "." + getLabel() + " is obtained by taking the " + compstr + "th component and finding " + value_descriptor();
+      59             : }
+      60             : 
+      61       11445 : bool ValueVessel::applyForce( std::vector<double>& forces ) {
+      62       11445 :   std::vector<double> tmpforce( forces.size() );
+      63       11445 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+      64       11445 :   if( final_value->applyForce( tmpforce ) ) {
+      65             :     wasforced=true;
+      66      524318 :     for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+      67             :   }
+      68       11445 :   return wasforced;
+      69             : }
+      70             : 
+      71             : }
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.func-sort-c.html b/coverage/vesselbase/ValueVessel.h.func-sort-c.html new file mode 100644 index 0000000000..bec40e6362 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.func.html b/coverage/vesselbase/ValueVessel.h.func.html new file mode 100644 index 0000000000..008916ba24 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func.html @@ -0,0 +1,72 @@ + + + + + + + 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-05-27 13:05:14Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.gcov.html b/coverage/vesselbase/ValueVessel.h.gcov.html new file mode 100644 index 0000000000..057756bc9a --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + 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-05-27 13:05: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     2406417 :   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.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.func-sort-c.html b/coverage/vesselbase/Vessel.cpp.func-sort-c.html new file mode 100644 index 0000000000..31bbd4a5fa --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.func-sort-c.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev173
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE451
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE451
_ZN4PLMD10vesselbase6Vessel9checkReadEv544
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE602
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE603
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE800
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28589
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.func.html b/coverage/vesselbase/Vessel.cpp.func.html new file mode 100644 index 0000000000..775af5d863 --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.func.html @@ -0,0 +1,116 @@ + + + + + + + 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-05-27 13:05:14Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE602
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE451
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev173
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE800
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE451
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase6Vessel9checkReadEv544
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE603
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28589
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.gcov.html b/coverage/vesselbase/Vessel.cpp.gcov.html new file mode 100644 index 0000000000..de0afa908b --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.gcov.html @@ -0,0 +1,226 @@ + + + + + + + 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-05-27 13:05: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         602 : VesselOptions::VesselOptions(const std::string& thisname, const std::string& thislab, const unsigned& nlab, const std::string& params, ActionWithVessel* aa ):
+      34         602 :   myname(thisname),
+      35         602 :   mylabel(thislab),
+      36         602 :   numlab(nlab),
+      37         602 :   action(aa),
+      38         602 :   keywords(emptyKeys),
+      39         602 :   parameters(params)
+      40             : {
+      41         602 : }
+      42             : 
+      43         451 : VesselOptions::VesselOptions(const VesselOptions& da, const Keywords& keys ):
+      44         451 :   myname(da.myname),
+      45         451 :   mylabel(da.mylabel),
+      46         451 :   numlab(da.numlab),
+      47         451 :   action(da.action),
+      48         451 :   keywords(keys),
+      49         451 :   parameters(da.parameters)
+      50             : {
+      51         451 : }
+      52             : 
+      53         451 : void Vessel::registerKeywords( Keywords& keys ) {
+      54         451 :   plumed_assert( keys.size()==0 );
+      55         902 :   keys.add("optional","LABEL","the label used to reference this particular quantity");
+      56         451 : }
+      57             : 
+      58         800 : std::string Vessel::transformName( const std::string& name ) {
+      59         800 :   std::string tlabel=name;
+      60             :   // Convert to lower case
+      61        4637 :   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         984 :     std::size_t num=tlabel.find_first_of("_");
+      65         984 :     if( num==std::string::npos ) break;
+      66         184 :     tlabel.erase( tlabel.begin() + num, tlabel.begin() + num + 1 );
+      67         184 :   }
+      68         800 :   return tlabel;
+      69             : }
+      70             : 
+      71         603 : Vessel::Vessel( const VesselOptions& da ):
+      72         603 :   myname(da.myname),
+      73         603 :   numlab(da.numlab),
+      74         603 :   action(da.action),
+      75         603 :   line(Tools::getWords( da.parameters )),
+      76         603 :   keywords(da.keywords),
+      77         603 :   finished_read(false)
+      78             : {
+      79         603 :   if( da.mylabel.length()>0) {
+      80           0 :     mylabel=da.mylabel;
+      81             :   } else {
+      82        1613 :     if( keywords.exists("LABEL") ) parse("LABEL",mylabel);
+      83         603 :     if( mylabel.length()==0 && numlab>=0 ) {
+      84         942 :       mylabel=transformName( myname ); std::string nn;
+      85         524 :       if(numlab>0) { Tools::convert( numlab, nn ); mylabel =  mylabel + "-" + nn; }
+      86             :     }
+      87             :   }
+      88         603 : }
+      89             : 
+      90          89 : std::string Vessel::getName() const {
+      91          89 :   return myname;
+      92             : }
+      93             : 
+      94       28589 : std::string Vessel::getLabel() const {
+      95       28589 :   return mylabel;
+      96             : }
+      97             : 
+      98         173 : std::string Vessel::getAllInput() {
+      99             :   std::string fullstring;
+     100         736 :   for(unsigned i=0; i<line.size(); ++i) {
+     101        1126 :     fullstring = fullstring + " " + line[i];
+     102             :   }
+     103         173 :   line.clear(); line.resize(0);
+     104         173 :   return fullstring;
+     105             : }
+     106             : 
+     107         122 : void Vessel::parseFlag(const std::string&key, bool & t) {
+     108             :   // Check keyword has been registered
+     109         122 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     110             :   // Check keyword is a flag
+     111         244 :   if(!keywords.style(key,"nohtml")) {
+     112         244 :     plumed_massert(keywords.style(key,"flag"), "keyword " + key + " is not a flag");
+     113             :   }
+     114             : 
+     115             :   // Read in the flag otherwise get the default value from the keywords object
+     116         122 :   if(!Tools::parseFlag(line,key,t)) {
+     117         198 :     if( keywords.style(key,"nohtml") ) {
+     118           0 :       t=false;
+     119          99 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     120           0 :       plumed_merror("there is a flag with no logical default in a vessel - weird");
+     121             :     }
+     122             :   }
+     123         122 : }
+     124             : 
+     125         544 : void Vessel::checkRead() {
+     126         544 :   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         544 :   finished_read=true;
+     135         544 :   std::string describe=description();
+     136         544 :   if( describe.length()>0 && action ) action->log.printf("  %s\n", describe.c_str() );
+     137         544 : }
+     138             : 
+     139           0 : [[noreturn]] void Vessel::error( const std::string& msg ) {
+     140           0 :   if( action ) {
+     141           0 :     action->log.printf("ERROR for keyword %s in action %s with label %s : %s \n \n",myname.c_str(), (action->getName()).c_str(), (action->getLabel()).c_str(), msg.c_str() );
+     142           0 :     if(finished_read) keywords.print( action->log );
+     143           0 :     plumed_merror("ERROR for keyword " + myname + " in action "  + action->getName() + " with label " + action->getLabel() + " : " + msg );
+     144             :   } else {
+     145           0 :     plumed_merror("ERROR: " + msg);
+     146             :   }
+     147             : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.func-sort-c.html b/coverage/vesselbase/Vessel.h.func-sort-c.html new file mode 100644 index 0000000000..76bd6bf208 --- /dev/null +++ b/coverage/vesselbase/Vessel.h.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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_345
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_528
_ZN4PLMD10vesselbase6VesselD2Ev603
_ZN4PLMD10vesselbase6Vessel7prepareEv26784
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32920
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_509159
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.func.html b/coverage/vesselbase/Vessel.h.func.html new file mode 100644 index 0000000000..0e646c755f --- /dev/null +++ b/coverage/vesselbase/Vessel.h.func.html @@ -0,0 +1,112 @@ + + + + + + + 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-05-27 13:05: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
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32920
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_509159
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_528
_ZN4PLMD10vesselbase6Vessel5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_9
_ZN4PLMD10vesselbase6Vessel5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_345
_ZN4PLMD10vesselbase6Vessel7prepareEv26784
_ZN4PLMD10vesselbase6VesselD0Ev0
_ZN4PLMD10vesselbase6VesselD2Ev603
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.gcov.html b/coverage/vesselbase/Vessel.h.gcov.html new file mode 100644 index 0000000000..d4b0dce76f --- /dev/null +++ b/coverage/vesselbase/Vessel.h.gcov.html @@ -0,0 +1,321 @@ + + + + + + + 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-05-27 13:05: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         603 :   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       26784 :   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         882 : void Vessel::parse(const std::string&key, T&t ) {
+     158         882 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     159             : 
+     160             :   // Now try to read the keyword
+     161         882 :   bool found=Tools::parse(line,key,t); std::string def;
+     162        2015 :   if ( !found && keywords.style(key,"compulsory") ) {
+     163         365 :     if( keywords.getDefaultValue(key,def) ) {
+     164         365 :       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         882 : }
+     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         353 :   return numlab;
+     206             : }
+     207             : 
+     208             : inline
+     209       32920 : void Vessel::setBufferStart( unsigned& start ) {
+     210       32920 :   bufstart=start; start+=bufsize;
+     211       32920 : }
+     212             : 
+     213             : inline
+     214      509159 : MultiValue& Vessel::transformDerivatives( const unsigned& current, MultiValue& myvals, MultiValue& bvals ) {
+     215      509159 :   return myvals;
+     216             : }
+     217             : 
+     218             : inline
+     219             : void Vessel::resizeBuffer( const unsigned& n ) {
+     220        2830 :   bufsize=n;
+     221           0 : }
+     222             : 
+     223             : inline
+     224             : double Vessel::getTolerance() const {
+     225      134266 :   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     3907293 :   return action;
+     236             : }
+     237             : 
+     238             : inline
+     239             : unsigned Vessel::getSizeOfBuffer() const {
+     240             :   return bufsize;
+     241             : }
+     242             : 
+     243             : }
+     244             : }
+     245             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html b/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html new file mode 100644 index 0000000000..6f1575e26f --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister6createENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE359
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv796
_ZN4PLMD10vesselbase14VesselRegisterD2Ev4168
_ZN4PLMD10vesselbase14VesselRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10078
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_75024
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE75024
_ZN4PLMD10vesselbase14vesselRegisterEv160922
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.func.html b/coverage/vesselbase/VesselRegister.cpp.func.html new file mode 100644 index 0000000000..2e8e31eeec --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.func.html @@ -0,0 +1,100 @@ + + + + + + + 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-05-27 13:05:14Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv796
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_75024
_ZN4PLMD10vesselbase14VesselRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10078
_ZN4PLMD10vesselbase14VesselRegister6createENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE359
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE75024
_ZN4PLMD10vesselbase14VesselRegisterD2Ev4168
_ZN4PLMD10vesselbase14vesselRegisterEv160922
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.gcov.html b/coverage/vesselbase/VesselRegister.cpp.gcov.html new file mode 100644 index 0000000000..ef6ae46c46 --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + 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-05-27 13:05: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        4168 : VesselRegister::~VesselRegister() {
+      30        4168 :   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        4168 : }
+      36             : 
+      37      160922 : VesselRegister& vesselRegister() {
+      38      160922 :   static VesselRegister ans;
+      39      160922 :   return ans;
+      40             : }
+      41             : 
+      42       75024 : void VesselRegister::remove(creator_pointer f) {
+      43      475152 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      44      475152 :     if((*p).second==f) {
+      45       75024 :       m.erase(p); break;
+      46             :     }
+      47             :   }
+      48       75024 : }
+      49             : 
+      50       75024 : 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       75024 :   m.insert(std::pair<std::string,creator_pointer>(keyword,f));
+      53       75024 :   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       75024 :   mk.insert(std::pair<std::string,keyword_pointer>(keyword,ik));
+      58       75024 : }
+      59             : 
+      60       10078 : bool VesselRegister::check(const std::string & key) {
+      61        3122 :   if( m.count(key)>0 ) return true;
+      62             :   return false;
+      63             : }
+      64             : 
+      65         359 : std::unique_ptr<Vessel> VesselRegister::create(std::string keyword, const VesselOptions&da) {
+      66         359 :   std::unique_ptr<Vessel> df;
+      67         359 :   if(check(keyword)) {
+      68         359 :     Keywords keys; mk[keyword](keys);
+      69         359 :     VesselOptions nda( da,keys );
+      70         718 :     df=m[keyword](nda);
+      71         359 :   }
+      72         359 :   return df;
+      73           0 : }
+      74             : 
+      75         796 : Keywords VesselRegister::getKeywords() {
+      76         796 :   return keywords;
+      77             : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/index-sort-f.html b/coverage/vesselbase/index-sort-f.html new file mode 100644 index 0000000000..2c654ebbed --- /dev/null +++ b/coverage/vesselbase/index-sort-f.html @@ -0,0 +1,433 @@ + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-05-27 13:05: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.4%95.4%
+
95.4 %104 / 10978.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
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
FunctionVessel.h +
0.0%
+
0.0 %0 / 1-0 / 0
ValueVessel.h +
100.0%
+
100.0 %4 / 4-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
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
VesselRegister.cpp +
84.8%84.8%
+
84.8 %28 / 33100.0 %7 / 7
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
Highest.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.16
+
+ + + diff --git a/coverage/vesselbase/index-sort-l.html b/coverage/vesselbase/index-sort-l.html new file mode 100644 index 0000000000..c9bf31555e --- /dev/null +++ b/coverage/vesselbase/index-sort-l.html @@ -0,0 +1,433 @@ + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-05-27 13:05: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.4%95.4%
+
95.4 %104 / 10978.6 %11 / 14
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.7 %6 / 7
OrderingVessel.cpp +
96.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
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Lowest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Mean.cpp +
100.0%
+
100.0 %17 / 17100.0 %8 / 8
MoreThan.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
Histogram.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
AltMin.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
LessThan.cpp +
100.0%
+
100.0 %22 / 22100.0 %9 / 9
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
Max.cpp +
100.0%
+
100.0 %23 / 23100.0 %9 / 9
Min.cpp +
100.0%
+
100.0 %24 / 24100.0 %9 / 9
Between.cpp +
100.0%
+
100.0 %30 / 30100.0 %9 / 9
ValueVessel.cpp +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/index.html b/coverage/vesselbase/index.html new file mode 100644 index 0000000000..0dc71dd21a --- /dev/null +++ b/coverage/vesselbase/index.html @@ -0,0 +1,433 @@ + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-05-27 13:05:14Functions:23125889.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithAveraging.cpp +
95.4%95.4%
+
95.4 %104 / 10978.6 %11 / 14
ActionWithAveraging.h +
92.3%92.3%
+
92.3 %12 / 1385.7 %6 / 7
ActionWithInputVessel.cpp +
86.5%86.5%
+
86.5 %32 / 3766.7 %4 / 6
ActionWithInputVessel.h +
66.7%66.7%
+
66.7 %2 / 30.0 %0 / 1
ActionWithVessel.cpp +
93.5%93.5%
+
93.5 %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.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func-sort-c.html b/coverage/wrapper/Plumed.h.func-sort-c.html new file mode 100644 index 0000000000..1d8cb20d5e --- /dev/null +++ b/coverage/wrapper/Plumed.h.func-sort-c.html @@ -0,0 +1,1080 @@ + + + + + + + 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:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_GVALID__0
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionEC2EPKc0
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_cmd_nothrow0
plumed_f_create_invalid0
plumed_f_create_invalid_0
plumed_f_create_invalid__0
plumed_f_create_invalid_static0
plumed_f_safeptr_char_scalar0
plumed_f_safeptr_float_scalar0
plumed_f_safeptr_long0
plumed_f_safeptr_long_double0
plumed_f_safeptr_long_double_scalar0
plumed_f_safeptr_long_scalar0
plumed_f_safeptr_ptr_scalar0
plumed_f_safeptr_short0
plumed_f_safeptr_short_scalar0
plumed_f_valid0
plumed_f_valid_0
plumed_f_valid__0
plumed_f_valid_static0
plumed_gcmd_safe0
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
plumed_f_create_dlopen1
plumed_f_create_dlopen_1
plumed_f_create_dlopen__1
plumed_f_create_reference1
plumed_f_create_reference_1
plumed_f_create_reference__1
plumed_f_global_1
plumed_f_global__1
plumed_f_gvalid1
plumed_f_gvalid_1
plumed_f_gvalid__1
plumed_f_installed1
plumed_f_installed_1
plumed_f_installed__1
plumed_f_safeptr_float1
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE__2
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED__2
PLUMED_F_GVALID_2
plumed_c2v2
plumed_create_invalid2
plumed_create_reference_v2
plumed_f_create__2
plumed_f_gcreate__2
plumed_f_gfinalize__2
plumed_v2c2
PLUMED_F_GINITIALIZED3
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
plumed_f_gcreate3
plumed_f_gcreate_3
plumed_f_gfinalize3
plumed_f_gfinalize_3
plumed_f_ginitialized3
plumed_f_ginitialized_3
plumed_f_ginitialized__3
plumed_f_safeptr_double_scalar3
plumed_f_use_count3
plumed_f_use_count_3
plumed_f_use_count__3
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GINITIALIZED_4
plumed_f_create_4
plumed_f_finalize__4
plumed_f_create6
plumed_f_create_dlopen_static6
plumed_f_create_reference_static6
plumed_f_finalize_6
plumed_f_gvalid_static6
plumed_f_installed_static6
plumed_f_safeptr_int6
plumed_attempt_dlopen8
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_reference_f8
plumed_f_finalize8
plumed_gvalid8
plumed_search_symbols8
plumed_installed9
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
plumed_f_gcmd10
plumed_f_gcmd__10
plumed_f_safeptr_int_scalar13
plumed_kernel_register13
plumed_f_gcreate_static14
plumed_f_gfinalize_static14
plumed_f_safeptr_double16
plumed_f_create_static18
plumed_f_ginitialized_static18
plumed_f_use_count_static18
plumed_f_global19
plumed_f_safeptr_char20
plumed_gcreate22
plumed_gfinalize22
plumed_valid23
plumed_f_global_static24
plumed_f_safeptr_ptr24
plumed_ginitialized24
plumed_f_gcmd_28
plumed_f_finalize_static30
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
plumed_f_cmd__40
plumed_global41
plumed_use_count42
plumed_c2f56
plumed_f_cmd_59
plumed_f_cmd60
plumed_f_gcmd_static78
plumed_gcmd78
plumed_cmd_safe95
_ZN12_GLOBAL__N_123plumed_cmd_safe_nothrowE6plumedPKc14plumed_safeptr22plumed_nothrow_handler222
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
plumed_f_cmd_static279
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error338
plumed_cmd357
plumed_f2c373
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error4133
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error8266
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error12737
plumed_cmd_safe_nothrow14075
plumed_symbol_table_reexport678211
plumed_retrieve_functions707688
plumed_malloc735661
plumed_malloc_pimpl737713
plumed_create737744
plumed_free751876
plumed_create_reference7642099
plumed_finalize8376023
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func.html b/coverage/wrapper/Plumed.h.func.html new file mode 100644 index 0000000000..1ee1002945 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func.html @@ -0,0 +1,1080 @@ + + + + + + + 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:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_CREATE__2
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED3
PLUMED_F_GINITIALIZED_4
PLUMED_F_GINITIALIZED__2
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_GVALID_2
PLUMED_F_GVALID__0
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
_ZN12_GLOBAL__N_123plumed_cmd_safe_nothrowE6plumedPKc14plumed_safeptr22plumed_nothrow_handler222
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionEC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocEC2EPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionEC2EPKc0
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error338
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error4133
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error8266
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error12737
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_attempt_dlopen8
plumed_c2f56
plumed_c2v2
plumed_cmd357
plumed_cmd_nothrow0
plumed_cmd_safe95
plumed_cmd_safe_nothrow14075
plumed_create737744
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_invalid2
plumed_create_reference7642099
plumed_create_reference_f8
plumed_create_reference_v2
plumed_f2c373
plumed_f_cmd60
plumed_f_cmd_59
plumed_f_cmd__40
plumed_f_cmd_static279
plumed_f_create6
plumed_f_create_4
plumed_f_create__2
plumed_f_create_dlopen1
plumed_f_create_dlopen_1
plumed_f_create_dlopen__1
plumed_f_create_dlopen_static6
plumed_f_create_invalid0
plumed_f_create_invalid_0
plumed_f_create_invalid__0
plumed_f_create_invalid_static0
plumed_f_create_reference1
plumed_f_create_reference_1
plumed_f_create_reference__1
plumed_f_create_reference_static6
plumed_f_create_static18
plumed_f_finalize8
plumed_f_finalize_6
plumed_f_finalize__4
plumed_f_finalize_static30
plumed_f_gcmd10
plumed_f_gcmd_28
plumed_f_gcmd__10
plumed_f_gcmd_static78
plumed_f_gcreate3
plumed_f_gcreate_3
plumed_f_gcreate__2
plumed_f_gcreate_static14
plumed_f_gfinalize3
plumed_f_gfinalize_3
plumed_f_gfinalize__2
plumed_f_gfinalize_static14
plumed_f_ginitialized3
plumed_f_ginitialized_3
plumed_f_ginitialized__3
plumed_f_ginitialized_static18
plumed_f_global19
plumed_f_global_1
plumed_f_global__1
plumed_f_global_static24
plumed_f_gvalid1
plumed_f_gvalid_1
plumed_f_gvalid__1
plumed_f_gvalid_static6
plumed_f_installed1
plumed_f_installed_1
plumed_f_installed__1
plumed_f_installed_static6
plumed_f_safeptr_char20
plumed_f_safeptr_char_scalar0
plumed_f_safeptr_double16
plumed_f_safeptr_double_scalar3
plumed_f_safeptr_float1
plumed_f_safeptr_float_scalar0
plumed_f_safeptr_int6
plumed_f_safeptr_int_scalar13
plumed_f_safeptr_long0
plumed_f_safeptr_long_double0
plumed_f_safeptr_long_double_scalar0
plumed_f_safeptr_long_scalar0
plumed_f_safeptr_ptr24
plumed_f_safeptr_ptr_scalar0
plumed_f_safeptr_short0
plumed_f_safeptr_short_scalar0
plumed_f_use_count3
plumed_f_use_count_3
plumed_f_use_count__3
plumed_f_use_count_static18
plumed_f_valid0
plumed_f_valid_0
plumed_f_valid__0
plumed_f_valid_static0
plumed_finalize8376023
plumed_free751876
plumed_gcmd78
plumed_gcmd_safe0
plumed_gcreate22
plumed_gfinalize22
plumed_ginitialized24
plumed_global41
plumed_gvalid8
plumed_installed9
plumed_kernel_register13
plumed_malloc735661
plumed_malloc_pimpl737713
plumed_retrieve_functions707688
plumed_search_symbols8
plumed_symbol_table_reexport678211
plumed_use_count42
plumed_v2c2
plumed_valid23
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.gcov.html b/coverage/wrapper/Plumed.h.gcov.html new file mode 100644 index 0000000000..6200cf1068 --- /dev/null +++ b/coverage/wrapper/Plumed.h.gcov.html @@ -0,0 +1,4315 @@ + + + + + + + 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:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_wrapper_Plumed_h
+      23             : #define __PLUMED_wrapper_Plumed_h
+      24             : 
+      25             : /*
+      26             :   This header might be included more than once in order to provide
+      27             :   the declarations and the definitions. The guard is thus closed before the end of the file
+      28             :   (match this brace) {
+      29             :   and a new guard is added for the definitions.
+      30             : */
+      31             : 
+      32             : /**
+      33             : \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
+      34             : 
+      35             :   Plumed.h and Plumed.c contain the external plumed interface, which is used to
+      36             :   integrate it with MD engines. This interface is very general, and is expected
+      37             :   not to change across plumed versions. Plumed.c also implements a dummy version
+      38             :   of the interface, so as to allow a code to be fully linked even if the plumed
+      39             :   library is not available yet. These files could be directly included in the official
+      40             :   host MD distribution. In this manner, it will be sufficient to link the plumed
+      41             :   library at link time (on all systems) or directly at runtime (on systems where
+      42             :   dynamic loading is enabled) to include plumed features.
+      43             : 
+      44             :   Notice that in PLUMED 2.5 this interface has been rewritten in order to allow
+      45             :   more debugging features and a better behavior in multithread environments.
+      46             :   The interface is almost perfectly backward compatible, although it implements
+      47             :   a few additional functions. See more details below.
+      48             : 
+      49             :   A further improvement has been made in PLUMED 2.8, where the interface has
+      50             :   been modified to allow dynamic type checking. See more details below.
+      51             : 
+      52             :   Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
+      53             :   needs to be linked with the host MD code immediately (whereas the rest of plumed
+      54             :   could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
+      55             :   link the Plumed.o file we would like not to need any C++ library linked. In this
+      56             :   manner, we do not need to know which C++ compiler will be used to compile plumed.
+      57             :   The C++ library is only linked to the "rest" of plumed, which actually uses it.
+      58             :   Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
+      59             :   (C++ is a bit stricter than C). This will
+      60             :   allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
+      61             :   Plumed.cpp), without the need of configuring a plain C compiler.
+      62             : 
+      63             :   Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
+      64             :   is hidden inside a single object type, which is described in C by a structure
+      65             :   (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
+      66             :   fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
+      67             :   and class interfaces, but the second should be preferred since it will automatically take
+      68             :   care of objects constructions and destructions. The reference interface
+      69             :   is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
+      70             :   around it.
+      71             :   In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
+      72             :   In the C and FORTRAN interfaces, all the routines are named plumed_*, to
+      73             :   avoid potential name clashes. Notice that the entire plumed library
+      74             :   is implemented in C++, and it is hidden inside the PLMD namespace.
+      75             : 
+      76             :   Handlers to the plumed object can be converted among different representations,
+      77             :   to allow inter-operability among languages. In C, there are tools to convert
+      78             :   to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
+      79             : 
+      80             :   These handlers only contain a pointer to the real structure, so that
+      81             :   when a plumed object is brought from one language to another,
+      82             :   it brings a reference to the same environment.
+      83             : 
+      84             :   Moreover, to simplify life in all cases where a single Plumed object is
+      85             :   required for the entire simulation (which covers many of the practical
+      86             :   applications with conventional MD codes) it is possible to take advantage
+      87             :   of a global interface, which is implicitly referring to a unique global instance.
+      88             :   The global object should still be initialized and finalized properly.
+      89             :   This global object is obviously not usable in a multithread context. In addition,
+      90             :   it is difficult to use it in an exception-safe manner, so its usage in C++ is
+      91             :   allowed but discouraged.
+      92             : 
+      93             :   As of PLUMED 2.5, the interface contains a reference counter that allows
+      94             :   for a better control of plumed initializations and deallocations.
+      95             :   This is particularly useful for the C++ interface that now
+      96             :   behaves similarly to a primitive shared pointer and can be thus copied.
+      97             :   In other languages, to use the reference counter correctly it is sufficient to
+      98             :   remember the following rule: for any `plumed_create*` call, there should be a corresponding
+      99             :   `plumed_finalize` call. More examples can be found below.
+     100             : 
+     101             :   Notice that up to PLUMED 2.8 the reference counter was not thread safe. This is fixed
+     102             :   when using PLUMED>=2.9 wrappers with a PLUMED>=2.9 kernel.
+     103             : 
+     104             :   The basic method to send a message to plumed is
+     105             : \verbatim
+     106             :   (C) plumed_cmd
+     107             :   (C++) PLMD::Plumed::cmd
+     108             :   (FORTRAN)  PLUMED_F_CMD
+     109             : \endverbatim
+     110             : 
+     111             :   To initialize a plumed object, use:
+     112             : \verbatim
+     113             :   (C)        plumed_create
+     114             :   (C++)      (constructor of PLMD::Plumed)
+     115             :   (FORTRAN)  PLUMED_F_CREATE
+     116             : \endverbatim
+     117             : 
+     118             :   As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
+     119             :   that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
+     120             :   for dlopen. The C++ version accepts an optional argument to this aim.
+     121             : \verbatim
+     122             :   (C)        plumed_create_dlopen or plumed_create_dlopen2
+     123             :   (C++)      PLMD::Plumed::dlopen
+     124             :   (FORTRAN)  PLUMED_F_CREATE_DLOPEN
+     125             : \endverbatim
+     126             : 
+     127             :   As of PLUMED 2.8, you can also initialize a plumed object using the following function,
+     128             :   that loads a kernel from an already loaded shared library. It accepts a handler
+     129             :   returned by `dlopen`:
+     130             : \verbatim
+     131             :   (C)        plumed_create_dlsym
+     132             :   (C++)      PLMD::Plumed::dlsym
+     133             :   (FORTRAN not allowed)
+     134             : \endverbatim
+     135             : 
+     136             :   To finalize a plumed object, use
+     137             : \verbatim
+     138             :   (C)        plumed_finalize
+     139             :   (C++)      (destructor of PLMD::Plumed)
+     140             :   (FORTRAN)  PLUMED_F_FINALIZE
+     141             : \endverbatim
+     142             : 
+     143             :   To access to the global-object, use
+     144             : \verbatim
+     145             :   (C)        plumed_gcreate, plumed_gfinalize, plumed_gcmd
+     146             :   (C++)      PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
+     147             :   (FORTRAN)  PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
+     148             : \endverbatim
+     149             : 
+     150             :   To check if the global object has been initialized, use
+     151             : \verbatim
+     152             :   (C)        plumed_ginitialized
+     153             :   (C++)      PLMD::Plumed::ginitialized
+     154             :   (FORTRAN)  PLUMED_F_GINITIALIZED
+     155             : \endverbatim
+     156             : 
+     157             :   Notice that when using runtime binding the plumed library might be not available.
+     158             :   In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
+     159             :   call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
+     160             :   unpleasant situation you have two options.
+     161             : 
+     162             :   First, you can check if plumed library is available before actually creating an object
+     163             :   using this function:
+     164             : \verbatim
+     165             :   (C)        plumed_installed
+     166             :   (C++)      PLMD::Plumed::installed
+     167             :   (FORTRAN)  PLUMED_F_INSTALLED
+     168             : \endverbatim
+     169             : 
+     170             :   Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
+     171             :   object using the following function:
+     172             : \verbatim
+     173             :   (C)        plumed_valid
+     174             :   (C++)      PLMD::Plumed::valid
+     175             :   (FORTRAN)  PLUMED_F_VALID
+     176             : \endverbatim
+     177             : 
+     178             :   If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
+     179             :   the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
+     180             : 
+     181             :   To know if the global object is valid instead you should use the following function:
+     182             : \verbatim
+     183             :   (C)        plumed_gvalid
+     184             :   (C++)      PLMD::Plumed::gvalid
+     185             :   (FORTRAN)  PLUMED_F_GVALID
+     186             : \endverbatim
+     187             : 
+     188             :   To convert handlers between different languages, use
+     189             : \verbatim
+     190             :   (C)        plumed_c2f                 (C to FORTRAN)
+     191             :   (C)        plumed_f2c                 (FORTRAN to C)
+     192             :   (C++)      Plumed(plumed) constructor (C to C++)
+     193             :   (C++)      operator plumed() cast     (C++ to C)
+     194             :   (C++)      Plumed(char*)  constructor (FORTRAN to C++)
+     195             :   (C++)      toFortran(char*)           (C++ to FORTRAN)
+     196             : \endverbatim
+     197             : 
+     198             :   As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
+     199             :   a void pointer (indeed: that's the only thing contained in a plumed object).
+     200             :   This might be useful in case you do not want to include the Plumed.h header in some
+     201             :   of your headers. In order to convert to/from void pointers you can use the following functions
+     202             : \verbatim
+     203             :   (C)        plumed_v2c                 (void* to C)
+     204             :   (C)        plumed_c2v                 (C to void*)
+     205             :   (C++)      Plumed(void*) constructor  (void* to C++)
+     206             :   (C++)      toVoid()                   (C++ to void*)
+     207             : \endverbatim
+     208             :   Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
+     209             :   since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
+     210             : 
+     211             :   As of PLUMED 2.5, we added a reference count. It is in practice possible
+     212             :   to create multiple `plumed` objects that refer to the same environment.
+     213             :   This is done using the following functions
+     214             : \verbatim
+     215             :   (C)        plumed_create_reference     (from a C object)
+     216             :   (C)        plumed_create_reference_f   (from a FORTRAN object)
+     217             :   (C)        plumed_create_reference_v   (from a void pointer)
+     218             :   (FORTRAN)  plumed_f_create_reference   (from a FORTRAN object)
+     219             : \endverbatim
+     220             :   In C++ references are managed automatically by constructors and destructor.
+     221             :   In addition, you can manually manage them (with care!) using incref() and decref().
+     222             : 
+     223             :   The interface of the FORTRAN functions is very similar to that of the C functions
+     224             :   and is listed below:
+     225             : 
+     226             : \verbatim
+     227             :   FORTRAN interface
+     228             :     SUBROUTINE PLUMED_F_CREATE(p)
+     229             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     230             :     SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
+     231             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     232             :       CHARACTER(LEN=*),  INTENT(IN)    :: path
+     233             :     SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
+     234             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     235             :       CHARACTER(LEN=32), INTENT(IN)    :: r
+     236             :     SUBROUTINE PLUMED_F_CREATE_INVALID(p)
+     237             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     238             :     SUBROUTINE PLUMED_F_CMD(p,key,val)
+     239             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     240             :       CHARACTER(LEN=*),  INTENT(IN)    :: key
+     241             :       UNSPECIFIED_TYPE,  INTENT(INOUT) :: val(*)
+     242             :     SUBROUTINE PLUMED_F_FINALIZE(p)
+     243             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     244             :     SUBROUTINE PLUMED_F_INSTALLED(i)
+     245             :       INTEGER,           INTENT(OUT)   :: i
+     246             :     SUBROUTINE PLUMED_F_VALID(p,i)
+     247             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     248             :       INTEGER,           INTENT(OUT)   :: i
+     249             :     SUBROUTINE PLUMED_F_USE_COUNT(p,i)
+     250             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     251             :       INTEGER,           INTENT(OUT)   :: i
+     252             :     SUBROUTINE PLUMED_F_GLOBAL(p)
+     253             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     254             :     SUBROUTINE PLUMED_F_GINITIALIZED(i)
+     255             :       INTEGER,           INTENT(OUT)   :: i
+     256             :     SUBROUTINE PLUMED_F_GCREATE()
+     257             :     SUBROUTINE PLUMED_F_GCMD(key,val)
+     258             :       CHARACTER(LEN=*), INTENT(IN)     :: key
+     259             :       UNSPECIFIED_TYPE, INTENT(INOUT)  :: val(*)
+     260             :     SUBROUTINE PLUMED_F_GFINALIZE()
+     261             :     SUBROUTINE PLUMED_F_GVALID(i)
+     262             :       INTEGER,           INTENT(OUT)   :: i
+     263             : \endverbatim
+     264             : 
+     265             :   Almost all C functions have a corresponding FORTRAN function.
+     266             :   As a simple mnemonic, if you know the name of the C function you can obtain the
+     267             :   corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
+     268             :   In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
+     269             :   holding the same information. These pointers basically contain a text representation
+     270             :   of the stored pointer, that is suitable to be contained in a string.
+     271             :   Finally, whenever a C function returns a value,
+     272             :   the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
+     273             :   passed as the its last argument.
+     274             : 
+     275             :   When you compile the FORTRAN interface, wrapper functions are added with several possible
+     276             :   name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
+     277             : 
+     278             : \section ReferencePlumedH-exceptions Error handling
+     279             : 
+     280             :   In case an error is detected by PLUMED, either because of some user error, some internal bug,
+     281             :   or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
+     282             :   PLUMED from C/FORTRAN or from C++.
+     283             : 
+     284             :   First of all, notice that access to PLUMED goes through three functions:
+     285             :   - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
+     286             :     just return a plumed object containing a NULL pointer
+     287             :   - plumed_cmd: this function might throw exceptions.
+     288             :   - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
+     289             : 
+     290             :   The following discussion concerns all the exceptions thrown by plumed_cmd.
+     291             : 
+     292             :   If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
+     293             : 
+     294             :   If you use C++ and you are calling the C++ interface (e.g. \ref Plumed::cmd), as of PLUMED 2.5 we implemented a complete
+     295             :   remapping of the exceptions thrown by PLUMED.  This solves both the problems mentioned above. In particular:
+     296             :   - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
+     297             :   - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
+     298             : 
+     299             :   As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
+     300             : 
+     301             :   If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
+     302             :   able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
+     303             :   so you might want to catch it by reference. By default, as of PLUMED 2.8 \ref plumed_cmd is redefined as a macro and directly calls
+     304             :   the \ref Plumed::cmd interface, and thus behaves in an equivalent manner. With previous versions of this header
+     305             :   one could have encountered problems with stack unwinding performed during exception handling in the C layer.
+     306             : 
+     307             :   Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
+     308             :   leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
+     309             :   the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
+     310             : 
+     311             :   The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
+     312             :   PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
+     313             :   Notice that this implies some loss of information, since the original exception might have been of a different type.
+     314             :   However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
+     315             :   completely decouple the MD code from the PLUMED library.
+     316             : 
+     317             : \section ReferencePlumedH-typesafe Typesafe interface
+     318             : 
+     319             :   Starting with PLUMED 2.8, the `cmd` function of the C++ interface, and the similar function `gcmd`, can be called
+     320             :   with several interfaces and can perform a typechecking on the passed argument. In particular, the following
+     321             :   forms are now possible:
+     322             : \verbatim
+     323             :   cmd("string",value);        // by value
+     324             :   cmd("string",&value);       // by pointer
+     325             :   cmd("string",&value,nelem); // by pointer, specifying the number of elements of the passed array
+     326             :   cmd("string",&value,shape); // by pointer, specifying the shape of the passed array
+     327             : \endverbati
+     328             :   The `nelem` and `shape` arguments are used by PLUMED to check that the user
+     329             :   provided enough elements. If nelem is provided, the check is done on the flatten array, whereas if shape
+     330             :   is passed a more thorough check is performed controlling each of the dimensions of the array.
+     331             :   In addition to this, the type of the pointer (or of the value) is checked at runtime.
+     332             : 
+     333             :   All these checks are only implemented if the PLUMED library is recent (>=2.8). However, it will still be
+     334             :   possible to load at runtime an older PLUMED library (<=2.7). For this reason, it is still compulsory
+     335             :   to pass the correct types to the `cmd` function, also when the argument is passed by value.
+     336             :   Type conversions are only performed between pointers and only in ways compatible with
+     337             :   what is allowed in C++ (e.g., `const void*` cannot be converted to `void*`, but `void*` can
+     338             :   be converted to `const void*`).
+     339             : 
+     340             :   Type checkes can be disabled in two ways:
+     341             :   - By compiling `Plumed.h` with `-D__PLUMED_WRAPPER_CXX_TYPESAFE=0`
+     342             :   - By setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
+     343             : 
+     344             :   Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
+     345             :   In particular:
+     346             :   - If the C interface is used in C++ code, it calls the C++ interface. Can be disabled with `-D__PLUMED_WRAPPER_CXX_BIND_C=0`.
+     347             :   - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
+     348             :     Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
+     349             : 
+     350             : \section ReferencePlumedH-2-5 New in PLUMED 2.5
+     351             : 
+     352             :   The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
+     353             :   The interface is almost perfectly backward compatible, although the behavior of C++ constructors
+     354             :   has been modified slightly.
+     355             :   In addition, a few new functions are introduced (explicitly marked in the documentation).
+     356             :   As a consequence, if your code uses some of the new functions, you will not be able
+     357             :   to link it directly with an older PLUMED library (though you will still be able to load
+     358             :   an older PLUMED library at runtime). In addition, the reference counter changes slightly
+     359             :   the behavior of the C++ methods used to interoperate with C and FORTRAN.
+     360             : 
+     361             :   An important novelty is in the way the runtime loader is implemented.
+     362             :   In particular, the loader works also if the symbols of the main executable are not exported.
+     363             :   The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
+     364             : 
+     365             :   Some additional features can be enabled using suitable environment variables. In particular:
+     366             :   - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
+     367             :   - `PLUMED_LOAD_NAMESPACE` can be set to `LOCAL` to load the PLUMED kernel in a separate
+     368             :     namespace. The default is global namespace, which is the same behavior of PLUMED <=2.4,
+     369             :     and is consistent with what happens when linking PLUMED as a shared library.
+     370             :   - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
+     371             :     mode implies that the symbols defined in the library are preferred to other symbols with the same name.
+     372             :     Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
+     373             : 
+     374             :   Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
+     375             :   file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
+     376             :   procedure you could compile the wrappers directly into your code making it unnecessary to link
+     377             :   the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
+     378             : 
+     379             :   As written above, the plumed object now implements a reference counter.  Consider the following example
+     380             : \verbatim
+     381             :   plumed p=plumed_create();
+     382             :   plumed_cmd(p,"init",NULL);
+     383             :   plumed q=plumed_create_reference(p);
+     384             :   plumed_finalize(p);
+     385             : // at this stage, object q still exists
+     386             :   plumed_cmd(q,"whatever",NULL);
+     387             :   plumed_finalize(q);
+     388             : // now plumed has been really finalized
+     389             : \endverbatim
+     390             : 
+     391             :   In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
+     392             :   \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
+     393             :   Notice that in C++ whenever an object goes out of scope the reference counter
+     394             :   will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
+     395             :   is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
+     396             :   that is the number of references is unchanged.
+     397             : 
+     398             :   The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
+     399             : \verbatim
+     400             :   plumed p=plumed_create();
+     401             :   plumed_cmd(p,"init",NULL);
+     402             :   Plumed q(p);
+     403             :   plumed_finalize(p);
+     404             : // at this stage, object q still exists with PLUMED 2.5
+     405             : // on the other hand, with PLUMED 2.4 object q refers to an
+     406             : // already finalized object
+     407             :   q.cmd("whatever",NULL);
+     408             : \endverbatim
+     409             : 
+     410             :   Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
+     411             :   plumed object is instantiated. So, you might even use it to load different plumed versions
+     412             :   simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
+     413             :   Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
+     414             :   \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
+     415             :   you also set env var `PLUMED_NAMESPACE=LOCAL`.
+     416             : 
+     417             :   Finally, a few functions have been added, namely:
+     418             :   - Functions to find if a plumed object is valid
+     419             :     (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
+     420             :   - Functions to create a plumed object based on the path of a specific kernel
+     421             :     (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
+     422             :   - Functions to create a plumed object referencing to another one, implementing a reference counter
+     423             :     (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
+     424             : 
+     425             : */
+     426             : 
+     427             : /* BEGINNING OF DECLARATIONS */
+     428             : 
+     429             : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
+     430             : 
+     431             : /*
+     432             :   1: make the C wrapper functions extern (default)
+     433             :   0: make the C wrapper functions static (C) or inline (C++)
+     434             : 
+     435             :   If set to zero, it disables all functions that only make sense as extern, such as
+     436             :   Fortran wrappers, global objects, and plumed_kernel_register.
+     437             : 
+     438             :   It can be set to zero to include multiple copies of the wrapper implementation without worrying
+     439             :   about duplicated symbols.
+     440             : 
+     441             :   Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
+     442             :   (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
+     443             :   with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
+     444             :   in the root namespace.
+     445             : 
+     446             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     447             : */
+     448             : 
+     449             : #ifndef __PLUMED_WRAPPER_EXTERN
+     450             : #define __PLUMED_WRAPPER_EXTERN 1
+     451             : #endif
+     452             : 
+     453             : /*
+     454             :   1: emit global plumed object and related functions (default)
+     455             :   0: do not emit global plumed object and related functions
+     456             : 
+     457             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     458             : */
+     459             : 
+     460             : #ifndef __PLUMED_WRAPPER_GLOBAL
+     461             : #define __PLUMED_WRAPPER_GLOBAL 1
+     462             : #endif
+     463             : 
+     464             : /*
+     465             :   1: Enable typesafe C interface (default)
+     466             :   0: Disable typesafe C interface
+     467             : 
+     468             :   Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
+     469             :   disabled by default with C++ and pre C11 compilers.
+     470             : 
+     471             :   https://mort.coffee/home/c-compiler-quirks/
+     472             : */
+     473             : 
+     474             : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     475             : #  if defined(__STDC_VERSION__)
+     476             : #    if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+     477             : #      if defined(__GNUC__) && !defined(__clang__)
+     478             : #        if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+     479             : #          define __PLUMED_WRAPPER_C_TYPESAFE 1
+     480             : #        endif
+     481             : #      else
+     482             : #        define __PLUMED_WRAPPER_C_TYPESAFE 1
+     483             : #      endif
+     484             : #    endif
+     485             : #  endif
+     486             : #  ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     487             : #    define __PLUMED_WRAPPER_C_TYPESAFE 0
+     488             : #  endif
+     489             : #endif
+     490             : 
+     491             : /*
+     492             :   1: Enable RTLD_DEEPBIND when possible (default)
+     493             :   0: Disable RTLD_DEEPBIND
+     494             : */
+     495             : 
+     496             : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+     497             : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
+     498             : #endif
+     499             : 
+     500             : /*
+     501             :   1: enable C++ wrapper (default)
+     502             :   0: disable C++ wrapper
+     503             : 
+     504             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     505             : */
+     506             : 
+     507             : #ifndef __PLUMED_WRAPPER_CXX
+     508             : #define __PLUMED_WRAPPER_CXX 1
+     509             : #endif
+     510             : 
+     511             : /*
+     512             :   1: new headers such as cstdlib are included in C++ (default)
+     513             :   0: old headers such as stdlib.h are included in C++
+     514             : 
+     515             :   Should only be set to zero when including the Plumed.h file in a file using the
+     516             :   old (stdlib.h) convention.
+     517             : 
+     518             :   Used both in declarations and definitions.
+     519             : */
+     520             : 
+     521             : #ifndef __PLUMED_WRAPPER_CXX_STD
+     522             : #define __PLUMED_WRAPPER_CXX_STD 1
+     523             : #endif
+     524             : 
+     525             : /*
+     526             :   1: place C++ wrappers in an anonymous namespace
+     527             :   0: place C++ wrappers in the PLMD namespace (default)
+     528             : 
+     529             :   It will make PLMD::Plumed a different class (though with the same name)
+     530             :   in each of the translation units in which `Plumed.h` is included.
+     531             : 
+     532             :   Can be used to completey separate C++ implementations. However, it will make
+     533             :   it impossible to transfer Plumed objects between different translation units
+     534             :   without converting to a void* or plumed object.
+     535             : 
+     536             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     537             : */
+     538             : 
+     539             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
+     540             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
+     541             : #endif
+     542             : 
+     543             : 
+     544             : /*
+     545             :   1: throw exceptions such as PLMD::Exception
+     546             :   0: throw exceptions such as PLMD::Plumed::Exception (default)
+     547             : 
+     548             :   This is useful when including Plumed.h within the plumed library
+     549             :   in anonymous mode, to make sure that the exception types from the
+     550             :   library are used.
+     551             : */
+     552             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+     553             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 0
+     554             : #endif
+     555             : 
+     556             : /*
+     557             :   1: make PLMD::Plumed class polymorphic (default)
+     558             :   0: make PLMD::Plumed class non-polymorphic
+     559             : 
+     560             :   Only used in declarations.
+     561             : */
+     562             : 
+     563             : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
+     564             : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
+     565             : #endif
+     566             : 
+     567             : /*
+     568             :   1: Enable typesafe interface (default)
+     569             :   0: Disable typesafe interface
+     570             : 
+     571             :   Only used in declarations.
+     572             : */
+     573             : 
+     574             : #ifndef __PLUMED_WRAPPER_CXX_TYPESAFE
+     575             : #define __PLUMED_WRAPPER_CXX_TYPESAFE 1
+     576             : #endif
+     577             : 
+     578             : /*
+     579             :   1: Define macros plumed_cmd and plumed_gcmd to use the C++ interface (default).
+     580             :   0: Don't define macros plumed_cmd and plumed_gcmd.
+     581             : 
+     582             :   Only used in declarations.
+     583             : */
+     584             : 
+     585             : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
+     586             : #define __PLUMED_WRAPPER_CXX_BIND_C 1
+     587             : #endif
+     588             : 
+     589             : /*
+     590             :   1: Enable passing long long int
+     591             :   0: Disable passing long long int
+     592             : 
+     593             :   Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
+     594             : */
+     595             : 
+     596             : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
+     597             : #if __cplusplus > 199711L
+     598             : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
+     599             : #else
+     600             : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
+     601             : #endif
+     602             : #endif
+     603             : 
+     604             : /*
+     605             :   1: make the default constructor create an invalid object
+     606             :   0: make the default constructor create a valid object
+     607             : 
+     608             :   Only for internal usage.
+     609             : */
+     610             : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+     611             : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
+     612             : #endif
+     613             : 
+     614             : /*
+     615             :   Size of a buffer used to store message for exceptions with noexcept constructor.
+     616             :   Should typically hold short messages. Anyway, as long as the stack size stays within the correct
+     617             :   limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
+     618             :   PLMD::Plumed::cmd, so that it should be in practice irrelevant.
+     619             : */
+     620             : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
+     621             : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
+     622             : #endif
+     623             : 
+     624             : /*
+     625             :   1: enable nested exceptions (only with C++11) (default)
+     626             :   0: disable nested exceptions
+     627             : 
+     628             :   For internal testing, used to mimic pre C++11 behavior on
+     629             :   nested exception.
+     630             : 
+     631             :   Only used in declarations.
+     632             : */
+     633             : 
+     634             : #ifndef __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+     635             : #define __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS 1
+     636             : #endif
+     637             : 
+     638             : /*
+     639             :  By default, assume C++11 compliant library is not available.
+     640             : */
+     641             : 
+     642             : #ifndef __PLUMED_WRAPPER_LIBCXX11
+     643             : #define __PLUMED_WRAPPER_LIBCXX11 0
+     644             : #endif
+     645             : 
+     646             : /* The following macros are just to define shortcuts */
+     647             : 
+     648             : /* Simplify addition of extern "C" blocks.  */
+     649             : #ifdef __cplusplus
+     650             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
+     651             : #define __PLUMED_WRAPPER_EXTERN_C_END }
+     652             : #else
+     653             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
+     654             : #define __PLUMED_WRAPPER_EXTERN_C_END
+     655             : #endif
+     656             : 
+     657             : /* Without C++, stdlib functions should not be prepended with ::std:: */
+     658             : #ifndef __cplusplus
+     659             : #undef __PLUMED_WRAPPER_CXX_STD
+     660             : #define __PLUMED_WRAPPER_CXX_STD 0
+     661             : #endif
+     662             : 
+     663             : /* Set prefix for stdlib functions */
+     664             : #if __PLUMED_WRAPPER_CXX_STD
+     665             : #define __PLUMED_WRAPPER_STD ::std::
+     666             : #else
+     667             : #define __PLUMED_WRAPPER_STD
+     668             : #endif
+     669             : 
+     670             : /* Allow using noexcept, explicit, and override with C++11 compilers */
+     671             : #ifdef __cplusplus /*{*/
+     672             : #if __cplusplus > 199711L
+     673             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
+     674             : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
+     675             : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
+     676             : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
+     677             : #define __PLUMED_WRAPPER_CXX_NULLPTR  nullptr
+     678             : #else
+     679             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
+     680             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     681             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     682             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     683             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     684             : #endif
+     685             : #else
+     686             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
+     687             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     688             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     689             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     690             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     691             : #endif /*}*/
+     692             : 
+     693             : /* static inline, for to avoid compiler warnings */
+     694             : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
+     695             : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
+     696             : #else
+     697             : #define __PLUMED_WRAPPER_STATIC_INLINE static
+     698             : #endif
+     699             : 
+     700             : /* Macros for anonymous namespace */
+     701             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
+     702             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
+     703             : #define __PLUMED_WRAPPER_ANONYMOUS_END }
+     704             : #else
+     705             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
+     706             : #define __PLUMED_WRAPPER_ANONYMOUS_END
+     707             : #endif /*}*/
+     708             : 
+     709             : #if __PLUMED_WRAPPER_EXTERN /*{*/
+     710             : 
+     711             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
+     712             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
+     713             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
+     714             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
+     715             : 
+     716             : #else
+     717             : 
+     718             : #ifdef __cplusplus
+     719             : #define __PLUMED_WRAPPER_C_BEGIN  __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
+     720             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
+     721             : #else
+     722             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
+     723             : #define __PLUMED_WRAPPER_C_END
+     724             : #endif
+     725             : 
+     726             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
+     727             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
+     728             : 
+     729             : /* with an not-external interface, it does not make sense to define global functions */
+     730             : #undef __PLUMED_WRAPPER_GLOBAL
+     731             : #define __PLUMED_WRAPPER_GLOBAL 0
+     732             : 
+     733             : #endif /*}*/
+     734             : 
+     735             : #if __PLUMED_WRAPPER_CXX_STD
+     736             : #include <cstddef> /* size_t */
+     737             : #include <cstring> /* memcpy */
+     738             : #include <cstdio> /* fprintf */
+     739             : #include <cstdlib> /* abort */
+     740             : #include <cassert> /* assert */
+     741             : #else
+     742             : #include <stddef.h>
+     743             : #include <string.h>
+     744             : #include <stdio.h> /* FILE and fprintf */
+     745             : #include <stdlib.h> /* abort */
+     746             : #include <limits.h> /* CHAR_MIN */
+     747             : #include <assert.h> /* assert */
+     748             : #endif
+     749             : 
+     750             : /**
+     751             :   This is an internal tool, to make sure that all malloc calls inside the
+     752             :   plumed library refer to the same implementation. When compiling with
+     753             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     754             :   allocations and deallocations, so as to debug the wrappers.
+     755             : */
+     756             : __PLUMED_WRAPPER_C_BEGIN
+     757             : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size);
+     758             : __PLUMED_WRAPPER_C_END
+     759             : 
+     760             : /**
+     761             :   This is an internal tool, to make sure that all free calls inside the
+     762             :   plumed library refer to the same implementation. When compiling with
+     763             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     764             :   allocations and deallocations, so as to debug the wrappers.
+     765             : */
+     766             : __PLUMED_WRAPPER_C_BEGIN
+     767             : void plumed_free(void* ptr);
+     768             : __PLUMED_WRAPPER_C_END
+     769             : 
+     770             : /**
+     771             :   \brief Main plumed object
+     772             : 
+     773             :   This is an object containing a Plumed instance, which should be used in
+     774             :   the MD engine. It should first be initialized with plumed_create(),
+     775             :   then it communicates with the MD engine using plumed_cmd(). Finally,
+     776             :   before the termination, it should be deallocated with plumed_finalize().
+     777             :   Its interface is very simple and general, and is expected
+     778             :   not to change across plumed versions. See \ref ReferencePlumedH.
+     779             : */
+     780             : typedef struct {
+     781             :   /**
+     782             :     \private
+     783             :     \brief Void pointer holding the real PlumedMain structure
+     784             : 
+     785             :     To maintain binary compatibility, we should not add members to this structure.
+     786             :     As of PLUMED 2.5, in order to add new components we do not store the pointer
+     787             :     to \ref PlumedMain here but rather a pointer to an intermediate private structure
+     788             :     that contains all the details.
+     789             :   */
+     790             :   void*p;
+     791             : } plumed;
+     792             : 
+     793             : typedef struct {
+     794             :   void* ptr;
+     795             :   void (*handler)(void*,int,const char*,const void*);
+     796             : } plumed_nothrow_handler;
+     797             : 
+     798             : /** \relates plumed
+     799             :     \brief Structure holding a typesafe pointer.
+     800             : */
+     801             : 
+     802             : typedef struct {
+     803             :   /** Pointer to data */
+     804             :   const void* ptr;
+     805             :   /** Number of elements (in case pointing to an array) */
+     806             :   __PLUMED_WRAPPER_STD size_t nelem;
+     807             :   /** Shape (scanned up to a zero value is found) */
+     808             :   const __PLUMED_WRAPPER_STD size_t* shape;
+     809             :   /**
+     810             :     sum of:
+     811             :     sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
+     812             :     0x10000    * data type, up to 0xff (255)
+     813             :                0 not typechecked
+     814             :                1 void
+     815             :                2 nullptr
+     816             :                3 integral
+     817             :                4 floating point
+     818             :                5 FILE (size will not be computed as it might be incomplete)
+     819             :                >5 not typechecked, reserved for future extensions
+     820             :     0x1000000  * 1 for unsigned (ignored)
+     821             :     0x2000000  * pointer/const type, up to 8
+     822             :                0 not typechecked
+     823             :                1 T (pass-by-value)
+     824             :                2 T       *
+     825             :                3 T const *
+     826             :                4 T       *       *
+     827             :                5 T       * const *
+     828             :                6 T const *       *
+     829             :                7 T const * const *
+     830             :     0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
+     831             :     0x20000000 and higher bits are ignored, reserved for future extensions
+     832             :   */
+     833             :   __PLUMED_WRAPPER_STD size_t flags;
+     834             :   /** Optional information, not used yet  */
+     835             :   const void* opt;
+     836             : } plumed_safeptr;
+     837             : 
+     838             : /**
+     839             :   Small structure that is only defined locally to retrieve errors.
+     840             : 
+     841             :   It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
+     842             : \verbatim
+     843             :   plumed p;
+     844             :   plumed_error error;
+     845             : 
+     846             :   p=plumed_create();
+     847             : 
+     848             :   plumed_cmd(p,"setNatoms",10,&error);
+     849             :   if(error.code) {
+     850             :     fprintf(errors,"%d\n",error.code);
+     851             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     852             :   }
+     853             :   // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
+     854             :   // but doing it is harmless
+     855             : 
+     856             :   // no need to initialize error, it is written in the plumed_cmd function
+     857             :   plumed_cmd(p,"init",&error);
+     858             :   if(error.code) {
+     859             :     fprintf(errors,"%d\n",error.code);
+     860             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     861             :   }
+     862             : \endverbatim
+     863             : 
+     864             :   The layout of this structure is subject to change, thus all the functions manipulating it
+     865             :   are defined as inline/static functions. In the future, we might reach some form
+     866             :   of ABI stability, and these functions might be moved below to the implementation
+     867             :   file.
+     868             : 
+     869             :   Notice that there is a macro plumed_error() defined in the PLUMED source code
+     870             :   (at tools/Exception.h). There is no conflict with this type since C preprocessor
+     871             :   distinguishes macros and function-like macros.
+     872             : */
+     873             : typedef struct plumed_error {
+     874             :   /** code used for translating messages */
+     875             :   int code;
+     876             :   /** error code for system_error */
+     877             :   int error_code;
+     878             :   /** message */
+     879             :   const char* what;
+     880             :   /** the buffer containing the message to be deallocated */
+     881             :   char* what_buffer;
+     882             :   /** pointer to nested exception */
+     883             :   struct plumed_error* nested;
+     884             : } plumed_error;
+     885             : 
+     886             : /** Initialize error (for internal usage) */
+     887             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     888             :   assert(error);
+     889       12959 :   error->code=0;
+     890       12959 :   error->error_code=0;
+     891       12959 :   error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
+     892       12959 :   error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
+     893       12959 :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+     894             : }
+     895             : 
+     896             : /** Finalize error - should be called when an error is raised to avoid leaks */
+     897           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     898           0 :   if(!error.code) return;
+     899           0 :   if(error.nested) {
+     900           0 :     plumed_error_finalize(*error.nested);
+     901           0 :     plumed_free(error.nested);
+     902             :   }
+     903           0 :   if(error.what_buffer) {
+     904           0 :     plumed_free(error.what_buffer);
+     905             :   }
+     906             : }
+     907             : 
+     908             : /** Access message - more robust than directly accessing what ptr, for future extensibility */
+     909             : __PLUMED_WRAPPER_STATIC_INLINE const char* plumed_error_what(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     910             :   return error.what;
+     911             : }
+     912             : 
+     913             : /** Set error to bad_alloc (for internal usage).
+     914             :     At variance with plumed_error_init, it also finalizes the error, possibly
+     915             :     deallocating any buffer.
+     916             : */
+     917           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set_bad_alloc(plumed_error*error) {
+     918             :   assert(error);
+     919           0 :   plumed_error_finalize(*error);
+     920             :   plumed_error_init(error);
+     921           0 :   error->what="[msg erased due to allocation failure]";
+     922           0 :   error->code=11400;
+     923           0 : }
+     924             : 
+     925             : /** Recursive merge (for internal usage) */
+     926             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_recursive_merge(plumed_error* error,char*buffer,const char*join,__PLUMED_WRAPPER_STD size_t*len) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     927             :   if(error->nested) plumed_error_recursive_merge(error->nested,buffer,join,len);
+     928             :   __PLUMED_WRAPPER_STD strncat(buffer,plumed_error_what(*error),*len);
+     929             :   *len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+     930             :   __PLUMED_WRAPPER_STD strncat(buffer,join,*len);
+     931             :   *len -= __PLUMED_WRAPPER_STD strlen(join);
+     932             : }
+     933             : 
+     934             : /** Merge with nested exceptions */
+     935             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_merge_with_nested(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     936             :   __PLUMED_WRAPPER_STD size_t len;
+     937             :   __PLUMED_WRAPPER_STD size_t len_join;
+     938             :   /* The is temporarily holding the new message */
+     939             :   char* new_buffer;
+     940             :   /* This is the string used to concatenate messages */
+     941             :   const char* join="\n\nThe above exception was the direct cause of the following exception:\n";
+     942             :   /* This is used to iterate over the linked list of nested exceptions */
+     943             :   plumed_error*e;
+     944             : 
+     945             :   /* If exception is not nested, nothing to do */
+     946             :   if(!error->nested) return;
+     947             : 
+     948             :   /* Accumulate the total length of the concatenated message */
+     949             :   len_join=__PLUMED_WRAPPER_STD strlen(join);
+     950             :   e=error;
+     951             :   len=__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     952             :   while(e->nested) {
+     953             :     e=e->nested;
+     954             :     len+=len_join+__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     955             :   }
+     956             : 
+     957             :   /* Allocate the new message */
+     958             :   new_buffer=(char*)plumed_malloc(len+1);
+     959             :   if(new_buffer) {
+     960             :     /* If allocation was successful, merge the messages */
+     961             :     new_buffer[0]='\0';
+     962             :     /* Notice that we have a forward linked list but we need to go through that in backward order
+     963             :        (inner to outer). To do that without allocating an additional array, we use a recursive
+     964             :        function.
+     965             :     */
+     966             :     assert(error->nested);
+     967             :     plumed_error_recursive_merge(error->nested,new_buffer,join,&len);
+     968             :     __PLUMED_WRAPPER_STD strncat(new_buffer,plumed_error_what(*error),len);
+     969             :     len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+     970             :     /* we keep track of length of buffer for safety */
+     971             :     assert(len==0);
+     972             :   }
+     973             :   error->what=new_buffer;
+     974             : 
+     975             :   /* Deallocate the previous message */
+     976             :   if(error->what_buffer) plumed_free(error->what_buffer);
+     977             :   error->what_buffer=new_buffer;
+     978             : 
+     979             :   /* Finalize the chain of nested exceptions */
+     980             :   plumed_error_finalize(*error->nested);
+     981             :   plumed_free(error->nested);
+     982             :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+     983             : 
+     984             :   if(!error->what) {
+     985             :     /* If allocation was not successful, reset to bad_alloc */
+     986             :     plumed_error_set_bad_alloc(error);
+     987             :   }
+     988             : }
+     989             : 
+     990             : /** Rethrow error (calling abort) */
+     991             : __PLUMED_WRAPPER_CXX_NORETURN __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_rethrow(plumed_error h) {
+     992             :   if(h.nested) plumed_error_merge_with_nested(&h);
+     993             :   __PLUMED_WRAPPER_STD fprintf(stderr,"Terminate due to exception. Code: %d\n%s\n",h.code,plumed_error_what(h));
+     994             :   __PLUMED_WRAPPER_STD abort();
+     995             : }
+     996             : 
+     997             : /** Callback (for internal usage) */
+     998           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     999             :   plumed_error* error;
+    1000             :   __PLUMED_WRAPPER_STD size_t len;
+    1001             :   void*const* options;
+    1002             : 
+    1003             :   error=(plumed_error*) ptr;
+    1004             : 
+    1005           0 :   error->code=code;
+    1006           0 :   error->error_code=0;
+    1007           0 :   len=__PLUMED_WRAPPER_STD strlen(what);
+    1008           0 :   error->what_buffer=(char*) plumed_malloc(len+1);
+    1009           0 :   if(!error->what_buffer) {
+    1010           0 :     plumed_error_set_bad_alloc(error);
+    1011           0 :     return;
+    1012             :   }
+    1013             : 
+    1014             :   __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
+    1015           0 :   error->what=error->what_buffer;
+    1016             : 
+    1017             :   /* interpret optional arguments */
+    1018           0 :   if(opt) {
+    1019             :     options=(void*const*)opt;
+    1020           0 :     while(*options) {
+    1021             :       /* c: error code */
+    1022           0 :       if(*((const char*)*options)=='c' && *(options+1)) {
+    1023           0 :         error->error_code=*((const int*)*(options+1));
+    1024           0 :         break;
+    1025             :       }
+    1026           0 :       options+=2;
+    1027             :     }
+    1028             :     options=(void*const*)opt;
+    1029           0 :     while(*options) {
+    1030             :       /* n: nested exception */
+    1031           0 :       if(*((const char*)*options)=='n' && *(options+1)) {
+    1032             :         /* notice that once this is allocated it is guaranteed to be deallocated by the recursive destructor */
+    1033           0 :         error->nested=(plumed_error*) plumed_malloc(sizeof(plumed_error));
+    1034             :         /* this is if malloc fails */
+    1035           0 :         if(!error->nested) {
+    1036           0 :           plumed_error_set_bad_alloc(error);
+    1037           0 :           break;
+    1038             :         }
+    1039             :         plumed_error_init((plumed_error*)error->nested);
+    1040             :         /* plumed will make sure to only use this if it is not null */
+    1041           0 :         *(void**)*(options+1)=error->nested;
+    1042           0 :         break;
+    1043             :       }
+    1044           0 :       options+=2;
+    1045             :     }
+    1046             :   }
+    1047             : }
+    1048             : 
+    1049             : /** \relates plumed
+    1050             :     \brief Constructor
+    1051             : 
+    1052             :     Constructs a plumed object.
+    1053             : 
+    1054             :     Notice that if you are linking against libplumedWrapper.a, if you are
+    1055             :     using a code patched in runtime mode, or if you are including the `Plumed.c`
+    1056             :     file directly in your code, this constructor might return an invalid plumed
+    1057             :     object. In particular, this could happen if the `PLUMED_KERNEL` environment
+    1058             :     variable is not set or set incorrectly. In order to detect an incorrect
+    1059             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1060             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1061             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1062             :     to finalize a plumed object even if it is invalid:
+    1063             : \verbatim
+    1064             :   plumed p=plumed_create();
+    1065             :   if(!plumed_valid(p)) {
+    1066             : // this will happen if the PLUMED_KERNEL variable is not set correctly
+    1067             :     plumed_finalize(p);
+    1068             :     return whatever;
+    1069             :   }
+    1070             : \endverbatim
+    1071             : 
+    1072             :     \return The constructed plumed object
+    1073             : */
+    1074             : __PLUMED_WRAPPER_C_BEGIN
+    1075             : plumed plumed_create(void);
+    1076             : __PLUMED_WRAPPER_C_END
+    1077             : 
+    1078             : /** \relates plumed
+    1079             :     \brief Constructor from path. Available as of PLUMED 2.5
+    1080             : 
+    1081             :     It tries to construct a plumed object loading the kernel located at path.
+    1082             :     Notice that it could leave the resulting object in an invalid state.
+    1083             :     In order to detect an invalid
+    1084             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1085             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1086             : 
+    1087             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1088             :     to finalize a plumed object even if it is invalid.
+    1089             : \verbatim
+    1090             :   plumed p=plumed_create(path);
+    1091             :   if(!plumed_valid(p)) {
+    1092             : // this will happen if the path argument is not set correctly
+    1093             :     plumed_finalize(p);
+    1094             :     return whatever;
+    1095             :   }
+    1096             : \endverbatim
+    1097             : 
+    1098             :     \return The constructed plumed object
+    1099             : */
+    1100             : __PLUMED_WRAPPER_C_BEGIN
+    1101             : plumed plumed_create_dlopen(const char*path);
+    1102             : __PLUMED_WRAPPER_C_END
+    1103             : 
+    1104             : 
+    1105             : /**
+    1106             :   \brief Constructor from path. Available as of PLUMED 2.5
+    1107             : 
+    1108             :   Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
+    1109             : 
+    1110             :   \warning
+    1111             :   Use with care, since not all the possible modes work correctly with PLUMED.
+    1112             : */
+    1113             : __PLUMED_WRAPPER_C_BEGIN
+    1114             : plumed plumed_create_dlopen2(const char*path,int mode);
+    1115             : __PLUMED_WRAPPER_C_END
+    1116             : 
+    1117             : /**
+    1118             :   \brief Constructor from dlopen handle. Available as of PLUMED 2.8
+    1119             : 
+    1120             :   Same as  \ref plumed_create_dlopen, but it acts on an already loaded library.
+    1121             :   This allows to separate the library loading from the construction of the
+    1122             :   plumed object. By using this function, the caller takes the responsibility
+    1123             :   to later use dlclose on this handle.
+    1124             : */
+    1125             : __PLUMED_WRAPPER_C_BEGIN
+    1126             : plumed plumed_create_dlsym(void* dlhandle);
+    1127             : __PLUMED_WRAPPER_C_END
+    1128             : 
+    1129             : /** \relates plumed
+    1130             :     Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
+    1131             : 
+    1132             :     Use it to increase by one the reference count of a plumed object.
+    1133             :     The resulting pointer might be identical to the one passed as an
+    1134             :     argument, but the reference count will be incremented by one.
+    1135             :     Notice that you should finalize the resulting object.
+    1136             : \verbatim
+    1137             :   plumed p1;
+    1138             :   plumed p2;
+    1139             :   p1=plumed_create();
+    1140             :   p2=plumed_create_reference(p1);
+    1141             :   plumed_finalize(p1);
+    1142             : // now you can still use p2
+    1143             :   plumed_cmd(p2,"init",NULL);
+    1144             :   plumed_finalize(p2);
+    1145             : // now the underlying object is destroyed.
+    1146             : \endverbatim
+    1147             : 
+    1148             :     If the `p` object is invalid, also the returned object will be invalid.
+    1149             : 
+    1150             :     \param p The plumed object that will be referenced to.
+    1151             :     \return The constructed plumed object
+    1152             : */
+    1153             : 
+    1154             : __PLUMED_WRAPPER_C_BEGIN
+    1155             : plumed plumed_create_reference(plumed p);
+    1156             : __PLUMED_WRAPPER_C_END
+    1157             : 
+    1158             : /** \relates plumed
+    1159             :     \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
+    1160             : 
+    1161             :   \return The constructed plumed object
+    1162             : */
+    1163             : 
+    1164             : __PLUMED_WRAPPER_C_BEGIN
+    1165             : plumed plumed_create_reference_v(void*v);
+    1166             : __PLUMED_WRAPPER_C_END
+    1167             : 
+    1168             : /** \relates plumed
+    1169             :     \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
+    1170             : 
+    1171             :   \return The constructed plumed object
+    1172             : */
+    1173             : 
+    1174             : __PLUMED_WRAPPER_C_BEGIN
+    1175             : plumed plumed_create_reference_f(const char*f);
+    1176             : __PLUMED_WRAPPER_C_END
+    1177             : 
+    1178             : /** \relates plumed
+    1179             :     \brief Constructor as invalid. Available as of PLUMED 2.5
+    1180             : 
+    1181             :    Can be used to create an object in the same state as if it was returned by
+    1182             :    plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
+    1183             :    and an incorrect PLUMED_KERNEL).
+    1184             : 
+    1185             :    Can be used to initialize a plumed object to a well-defined state without explicitly
+    1186             :    creating it. The resulting object can be checked later with \ref plumed_valid.
+    1187             :    Consider the following example
+    1188             : \verbatim
+    1189             :     plumed p;
+    1190             :     p=plumed_create_invalid();
+    1191             : // at this point p is initialized to a well-defined (invalid) state.
+    1192             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    1193             :     plumed_finalize(p);
+    1194             :     p=plumed_create();
+    1195             : \endverbatim
+    1196             : 
+    1197             :     \return The constructed plumed object
+    1198             : */
+    1199             : 
+    1200             : __PLUMED_WRAPPER_C_BEGIN
+    1201             : plumed plumed_create_invalid();
+    1202             : __PLUMED_WRAPPER_C_END
+    1203             : 
+    1204             : /** \relates plumed
+    1205             :     \brief Tells p to execute a command.
+    1206             : 
+    1207             :     If the object is not valid (see \ref plumed_valid), this command will exit.
+    1208             : 
+    1209             :     \param p The plumed object on which command is acting
+    1210             :     \param key The name of the command to be executed
+    1211             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
+    1212             :                but for some choice of key it can change the content.
+    1213             : 
+    1214             :     Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
+    1215             :     argument of \ref plumed_cmd.
+    1216             : 
+    1217             :     In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
+    1218             :     or you can equivalently pass NULL or nullptr).
+    1219             :     The set of possible keys is the real API of the plumed library, and will be expanded with time.
+    1220             :     New commands will be added, but backward compatibility will be retained as long as possible.
+    1221             : */
+    1222             : 
+    1223             : __PLUMED_WRAPPER_C_BEGIN
+    1224             : void plumed_cmd(plumed p,const char*key,const void*val);
+    1225             : __PLUMED_WRAPPER_C_END
+    1226             : 
+    1227             : /**
+    1228             :   \relates plumed
+    1229             :   \brief Same as \ref plumed_cmd, but does not throw exceptions.
+    1230             : 
+    1231             :   This function is meant to be used when errors should be handled explicitly.
+    1232             :   if an exception is raised within PLUMED, the function nothrow.handler() will
+    1233             :   be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
+    1234             :   to correctly rethrow exceptions, but might be used from C as well. opt can be used
+    1235             :   to pass further information (not used yet).
+    1236             : */
+    1237             : 
+    1238             : __PLUMED_WRAPPER_C_BEGIN
+    1239             : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
+    1240             : __PLUMED_WRAPPER_C_END
+    1241             : 
+    1242             : __PLUMED_WRAPPER_C_BEGIN
+    1243             : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
+    1244             : __PLUMED_WRAPPER_C_END
+    1245             : 
+    1246             : __PLUMED_WRAPPER_C_BEGIN
+    1247             : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
+    1248             : __PLUMED_WRAPPER_C_END
+    1249             : 
+    1250             : /** \relates plumed
+    1251             :     \brief Destructor.
+    1252             : 
+    1253             :     It must be used for any object created using \ref plumed_create(),
+    1254             :     even if the created object is not valid.
+    1255             : 
+    1256             :     \param p The plumed object to be deallocated
+    1257             : */
+    1258             : 
+    1259             : __PLUMED_WRAPPER_C_BEGIN
+    1260             : void plumed_finalize(plumed p);
+    1261             : __PLUMED_WRAPPER_C_END
+    1262             : 
+    1263             : /** \relates plumed
+    1264             :     \brief Check if plumed is installed (for runtime binding).
+    1265             : 
+    1266             :     Notice that this is equivalent to creating a dummy object and checking if it is valid.
+    1267             : 
+    1268             : \verbatim
+    1269             :   // this:
+    1270             :   //int a=plumed_installed();
+    1271             :   // is equivalent to this:
+    1272             : 
+    1273             :   plumed p=plumed_create();
+    1274             :   int a=plumed_valid(p);
+    1275             :   plumed_finalize(p);
+    1276             : 
+    1277             : \endverbatim
+    1278             : 
+    1279             :     This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
+    1280             :     was not available. Using \ref plumed_valid() is now preferred since it creates a single object
+    1281             :     instead of creating a dummy object that is then discarded.
+    1282             : 
+    1283             :     \return 1 if plumed is installed, 0 otherwise
+    1284             : */
+    1285             : 
+    1286             : __PLUMED_WRAPPER_C_BEGIN
+    1287             : int plumed_installed(void);
+    1288             : __PLUMED_WRAPPER_C_END
+    1289             : 
+    1290             : /** \relates plumed
+    1291             :     \brief Check if plumed object is valid. Available as of PLUMED 2.5
+    1292             : 
+    1293             :     It might return false if plumed is not available at runtime.
+    1294             : 
+    1295             :     \return 1 if plumed is valid, 0 otherwise
+    1296             : */
+    1297             : 
+    1298             : __PLUMED_WRAPPER_C_BEGIN
+    1299             : int plumed_valid(plumed p);
+    1300             : __PLUMED_WRAPPER_C_END
+    1301             : 
+    1302             : /** \relates plumed
+    1303             :     \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
+    1304             : */
+    1305             : 
+    1306             : __PLUMED_WRAPPER_C_BEGIN
+    1307             : int plumed_use_count(plumed p);
+    1308             : __PLUMED_WRAPPER_C_END
+    1309             : 
+    1310             : 
+    1311             : /* routines to convert char handler from/to plumed objects */
+    1312             : 
+    1313             : /** \related plumed
+    1314             :     \brief Converts a C handler to a FORTRAN handler
+    1315             : 
+    1316             :     \param p The C handler
+    1317             :     \param c The FORTRAN handler (a char[32])
+    1318             : 
+    1319             :     This function can be used to convert a plumed object created in C to
+    1320             :     a plumed handler that can be used in FORTRAN. Notice that the reference counter
+    1321             :     is not incremented. In other words, the FORTRAN object will be a weak reference.
+    1322             :     If you later finalize the C handler, the FORTRAN handler will be invalid.
+    1323             : \verbatim
+    1324             : #include <plumed/wrapper/Plumed.h>
+    1325             : int main(int argc,char*argv[]){
+    1326             :   plumed p;
+    1327             :   p=plumed_create();
+    1328             :   char fortran_handler[32];
+    1329             :   plumed_c2f(p,fortran_handler);
+    1330             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
+    1331             :   fortran_routine(fortran_handler);
+    1332             :   plumed_finalize(p);
+    1333             :   return 0;
+    1334             : }
+    1335             : \endverbatim
+    1336             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
+    1337             :   fortran_handler.
+    1338             : */
+    1339             : 
+    1340             : __PLUMED_WRAPPER_C_BEGIN
+    1341             : void   plumed_c2f(plumed p,char* c);
+    1342             : __PLUMED_WRAPPER_C_END
+    1343             : 
+    1344             : /** \related plumed
+    1345             :     \brief Converts a FORTRAN handler to a C handler
+    1346             :     \param c The FORTRAN handler (a char[32])
+    1347             :     \return The C handler
+    1348             : 
+    1349             :     This function can be used to convert a plumed object created in FORTRAN
+    1350             :     to a plumed handler that can be used in C.  Notice that the reference counter
+    1351             :     is not incremented. In other words, the C object will be a weak reference.
+    1352             :     If you later finalize the FORTRAN handler, the C handler will be invalid.
+    1353             : \verbatim
+    1354             : void c_routine(char handler[32]){
+    1355             :   plumed p;
+    1356             :   p=plumed_f2c(handler);
+    1357             :   plumed_cmd(p,"init",NULL);
+    1358             : }
+    1359             : \endverbatim
+    1360             :   Here `c_routine` is a C function that can be called from FORTRAN
+    1361             :   and interact with the provided plumed handler.
+    1362             : */
+    1363             : 
+    1364             : __PLUMED_WRAPPER_C_BEGIN
+    1365             : plumed plumed_f2c(const char* c);
+    1366             : __PLUMED_WRAPPER_C_END
+    1367             : 
+    1368             : /** \related plumed
+    1369             :     \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
+    1370             : 
+    1371             :     It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
+    1372             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1373             :     Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
+    1374             : 
+    1375             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1376             : */
+    1377             : 
+    1378             : __PLUMED_WRAPPER_C_BEGIN
+    1379             : void* plumed_c2v(plumed p);
+    1380             : __PLUMED_WRAPPER_C_END
+    1381             : 
+    1382             : 
+    1383             : /** \related plumed
+    1384             :     \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
+    1385             : 
+    1386             :     It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
+    1387             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1388             : 
+    1389             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1390             : */
+    1391             : 
+    1392             : __PLUMED_WRAPPER_C_BEGIN
+    1393             : plumed plumed_v2c(void*);
+    1394             : __PLUMED_WRAPPER_C_END
+    1395             : 
+    1396             : #if ! defined( __cplusplus) /*{*/
+    1397             : 
+    1398             : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
+    1399             : 
+    1400             : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
+    1401             :   static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
+    1402             :     plumed_safeptr safe; \
+    1403             :     plumed_nothrow_handler nothrow; \
+    1404             :     safe.ptr=ptr; \
+    1405             :     safe.nelem=nelem; \
+    1406             :     safe.shape=(const size_t*)shape; \
+    1407             :     safe.flags=flags_; \
+    1408             :     safe.opt=NULL; \
+    1409             :     if(error) { \
+    1410             :       plumed_error_init(error); \
+    1411             :       nothrow.ptr=error; \
+    1412             :       nothrow.handler=plumed_error_set; \
+    1413             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1414             :     } else { \
+    1415             :       plumed_cmd_safe(p,key,safe); \
+    1416             :     } \
+    1417             :   } \
+    1418             :   static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
+    1419             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
+    1420             :   } \
+    1421             :   static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
+    1422             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
+    1423             :   } \
+    1424             :   static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
+    1425             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
+    1426             :   } \
+    1427             :   static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
+    1428             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
+    1429             :   } \
+    1430             :   static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
+    1431             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
+    1432             :   }
+    1433             : 
+    1434             : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
+    1435             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type,             type_ ## _p,  size | (0x10000*(code)) | (0x2000000*2)) \
+    1436             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const,       type_ ## _c,  size | (0x10000*(code)) | (0x2000000*3)) \
+    1437             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*,            type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
+    1438             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const,       type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
+    1439             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*,      type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
+    1440             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
+    1441             : 
+    1442             : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
+    1443             : 
+    1444             : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
+    1445             :   __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
+    1446             :   static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
+    1447             :     plumed_safeptr safe; \
+    1448             :     plumed_nothrow_handler nothrow; \
+    1449             :     (void) nelem; \
+    1450             :     (void) shape; \
+    1451             :     safe.ptr=&val; \
+    1452             :     safe.nelem=1; \
+    1453             :     safe.shape=NULL; \
+    1454             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1455             :     safe.opt=NULL; \
+    1456             :     if(error) { \
+    1457             :       plumed_error_init(error); \
+    1458             :       nothrow.ptr=error; \
+    1459             :       nothrow.handler=plumed_error_set; \
+    1460             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1461             :     } else { \
+    1462             :       plumed_cmd_safe(p,key,safe); \
+    1463             :     } \
+    1464             :   } \
+    1465             :   static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) {  \
+    1466             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
+    1467             :   } \
+    1468             :   static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) {  \
+    1469             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
+    1470             :   } \
+    1471             :   static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) {  \
+    1472             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
+    1473             :   } \
+    1474             :   static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) {  \
+    1475             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
+    1476             :   } \
+    1477             :   static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) {  \
+    1478             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
+    1479             :   }
+    1480             : 
+    1481             : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
+    1482             :     type: plumed_ ## flavor ## _ ## typen_,
+    1483             : 
+    1484             : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1485             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*,             type_ ## _p) \
+    1486             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*,       type_ ## _c) \
+    1487             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type**,            type_ ## _pp) \
+    1488             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*,       type_ ## _pc) \
+    1489             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**,      type_ ## _cp) \
+    1490             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
+    1491             : 
+    1492             : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
+    1493             :   __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1494             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type,             type_ ## _v)
+    1495             : 
+    1496             : /// Here we create all the required instances
+    1497             : /// 1: void
+    1498             : /// 3: integral
+    1499             : /// 4: floating
+    1500             : /// 5: FILE
+    1501             : /// 0x100: unsigned
+    1502             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
+    1503             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
+    1504             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
+    1505             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
+    1506             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
+    1507             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
+    1508             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
+    1509             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
+    1510             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
+    1511             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
+    1512             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
+    1513             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
+    1514             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
+    1515             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
+    1516             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
+    1517             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
+    1518             : 
+    1519             : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
+    1520             :   (void) ignore;
+    1521             :   plumed_cmde_void_p(p,key,NULL,error);
+    1522             : }
+    1523             : 
+    1524             : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
+    1525             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
+    1526             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
+    1527             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
+    1528             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
+    1529             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
+    1530             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
+    1531             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
+    1532             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
+    1533             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
+    1534             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
+    1535             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
+    1536             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
+    1537             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
+    1538             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
+    1539             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
+    1540             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
+    1541             :     default: plumed_ ## flavor ## _void_c)
+    1542             : 
+    1543             : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
+    1544             : 
+    1545             : #define plumed_cmd_3args(p,key,X) _Generic((X), \
+    1546             :     plumed_error*: plumed_cmd_null_e, \
+    1547             :     default:       plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
+    1548             : 
+    1549             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1550             : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
+    1551             :     const size_t *: plumed_cmdnse_inner(cmds,val), \
+    1552             :     size_t *: plumed_cmdnse_inner(cmds,val), \
+    1553             :     size_t: plumed_cmdnse_inner(cmdn,val), \
+    1554             :     plumed_error*: plumed_cmdnse_inner(cmde,val) \
+    1555             :     ) (p,key,val,X)
+    1556             : 
+    1557             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1558             : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
+    1559             :     const size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1560             :     size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1561             :     size_t: plumed_cmdnse_inner(cmdne,val) \
+    1562             :     ) (p,key,val,X,error)
+    1563             : 
+    1564             : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
+    1565             : #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__)
+    1566             : 
+    1567             : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
+    1568             : 
+    1569             : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
+    1570             : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
+    1571             : 
+    1572             : #endif /*}*/
+    1573             : 
+    1574             : #endif /*}*/
+    1575             : 
+    1576             : 
+    1577             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    1578             : 
+    1579             : /* Global C functions are always extern */
+    1580             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    1581             : 
+    1582             : /** \relates plumed
+    1583             :     \brief Retrieves an handler to the global structure.
+    1584             : 
+    1585             :   You can use this if you work on a code that uses the global structure and you want to
+    1586             :   pass to a generic routine an handler to the same structure. E.g.
+    1587             : 
+    1588             : \verbatim
+    1589             :   plumed p=plumed_global();
+    1590             :   some_routine(p);
+    1591             : \endverbatim
+    1592             : */
+    1593             : extern
+    1594             : plumed plumed_global(void);
+    1595             : 
+    1596             : /** \relates plumed
+    1597             :     \brief Check if the global interface has been initialized.
+    1598             : 
+    1599             :     \return 1 if plumed has been initialized, 0 otherwise
+    1600             : */
+    1601             : extern
+    1602             : int plumed_ginitialized(void);
+    1603             : 
+    1604             : /** \relates plumed
+    1605             :     \brief Constructor for the global interface.
+    1606             : 
+    1607             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
+    1608             : */
+    1609             : extern
+    1610             : void plumed_gcreate(void);
+    1611             : 
+    1612             : /** \relates plumed
+    1613             :     \brief Tells to the global interface to execute a command.
+    1614             : 
+    1615             :     \param key The name of the command to be executed
+    1616             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
+    1617             :                but for some choice of key it can change the content
+    1618             : 
+    1619             :     `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
+    1620             : */
+    1621             : extern
+    1622             : void plumed_gcmd(const char* key,const void* val);
+    1623             : 
+    1624             : /** \relates plumed
+    1625             :     \brief Tells to the global interface to execute a command.
+    1626             : 
+    1627             :     \param key The name of the command to be executed
+    1628             :     \param safe A safe pointer
+    1629             : 
+    1630             :     `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
+    1631             : */
+    1632             : extern
+    1633             : void plumed_gcmd_safe(const char* key,plumed_safeptr);
+    1634             : 
+    1635             : /** \relates plumed
+    1636             :     \brief Destructor for the global interface.
+    1637             : 
+    1638             :     `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
+    1639             :     equivalent. In particular, plumed_gfinalize() also makes sure that the global object
+    1640             :     is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
+    1641             : */
+    1642             : extern
+    1643             : void plumed_gfinalize(void);
+    1644             : 
+    1645             : /** \relates plumed
+    1646             :     \brief Check if global plumed object is valid. Available as of PLUMED 2.5
+    1647             : 
+    1648             :     It might return zero if plumed is not available at runtime.
+    1649             : 
+    1650             :     \return 1 if plumed is valid, 0 otherwise.
+    1651             : */
+    1652             : extern
+    1653             : int plumed_gvalid();
+    1654             : 
+    1655             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    1656             : 
+    1657             : #endif /*}*/
+    1658             : 
+    1659             : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
+    1660             : 
+    1661             : #if __PLUMED_WRAPPER_CXX_STD
+    1662             : #include <cstdlib> /* NULL getenv */
+    1663             : #include <cstddef> /* nullptr_t */
+    1664             : #include <cstring> /* strncat strlen */
+    1665             : #include <cassert> /* assert */
+    1666             : #include <climits> /* CHAR_MIN */
+    1667             : #else
+    1668             : #include <stddef.h>
+    1669             : #include <stdlib.h>
+    1670             : #include <string.h>
+    1671             : #include <assert.h>
+    1672             : #include <limits.h>
+    1673             : #endif
+    1674             : 
+    1675             : #include <exception> /* exception bad_exception */
+    1676             : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
+    1677             : #include <string> /* string */
+    1678             : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
+    1679             : #include <new> /* bad_alloc bad_array_new_length (C++11) */
+    1680             : #include <typeinfo> /* bad_typeid bad_cast */
+    1681             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1682             : #include <system_error> /* system_error generic_category system_category */
+    1683             : #include <future> /* future_category */
+    1684             : #include <memory> /* bad_weak_ptr */
+    1685             : #include <functional> /* bad_function_call */
+    1686             : #endif
+    1687             : 
+    1688             : #if __cplusplus > 199711L
+    1689             : #include <array> /* array */
+    1690             : #include <initializer_list> /* initializer_list */
+    1691             : #endif
+    1692             : 
+    1693             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
+    1694             : namespace PLMD {
+    1695             : 
+    1696             : /* Optionally, it is further hidden in an anonymous namespace */
+    1697             : 
+    1698             : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
+    1699             : 
+    1700             : /**
+    1701             :   Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
+    1702             : 
+    1703             :   This function should not be used by external programs. It is defined
+    1704             :   as inline static so that it can store a static variable (for quicker access)
+    1705             :   without adding a unique global symbol to a library including this header file.
+    1706             : */
+    1707           0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1708           0 :   static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
+    1709           0 :   return res;
+    1710             : }
+    1711             : 
+    1712             : /**
+    1713             :   C++ wrapper for \ref plumed.
+    1714             : 
+    1715             :   This class provides a C++ interface to PLUMED.
+    1716             :   It only containts a \ref plumed object, but wraps it with a number of useful methods.
+    1717             :   All methods are inlined so as to avoid the compilation of an extra c++ file.
+    1718             : 
+    1719             : */
+    1720             : 
+    1721             : class Plumed {
+    1722             :   /**
+    1723             :     C structure.
+    1724             :   */
+    1725             :   plumed main;
+    1726             : 
+    1727             : private:
+    1728             : 
+    1729             :   /**
+    1730             :     This is an internal utility to dispatch exceptions based on the plumed_error object.
+    1731             : 
+    1732             :     It takes information about the exception to be thrown by the passed h object
+    1733             :     and use it to call function f() on the resulting exception. Notice that:
+    1734             :     - this function does not consider if the error is nested.
+    1735             :     - f should be a callable object, so that it can store information
+    1736             :     - f operator() should be a template function so as to act based on the
+    1737             :       type of its argument
+    1738             : 
+    1739             :     New exceptions added here should be kept in sync with core/PlumedMainInitializer.cpp
+    1740             : 
+    1741             :     Notice that this function also finalizes in place plumed_error h, so as to avoid
+    1742             :     memory leaks.
+    1743             :   */
+    1744             :   template<typename F>
+    1745           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void exception_dispatch(plumed_error&h,F f) {
+    1746             :     /* this is required to make sure h is finalized when leaving this function */
+    1747             :     finalize_plumed_error finalize(h);
+    1748             :     /* grab the message */
+    1749             :     const char* msg=plumed_error_what(h);
+    1750           0 :     if(h.code==1) f(Plumed::Invalid(msg));
+    1751             :     /* logic errors */
+    1752           0 :     if(h.code>=10100 && h.code<10200) {
+    1753           0 :       if(h.code>=10105 && h.code<10110) f(::std::invalid_argument(msg));
+    1754           0 :       if(h.code>=10110 && h.code<10115) f(::std::domain_error(msg));
+    1755           0 :       if(h.code>=10115 && h.code<10120) f(::std::length_error(msg));
+    1756           0 :       if(h.code>=10120 && h.code<10125) f(::std::out_of_range(msg));
+    1757           0 :       f(::std::logic_error(msg));
+    1758             :     }
+    1759             :     /* runtime errors */
+    1760           0 :     if(h.code>=10200 && h.code<10300) {
+    1761           0 :       if(h.code>=10205 && h.code<10210) f(::std::range_error(msg));
+    1762           0 :       if(h.code>=10210 && h.code<10215) f(::std::overflow_error(msg));
+    1763           0 :       if(h.code>=10215 && h.code<10220) f(::std::underflow_error(msg));
+    1764             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1765             :       if(h.code==10220) f(::std::system_error(h.error_code,::std::generic_category(),msg));
+    1766             :       if(h.code==10221) f(::std::system_error(h.error_code,::std::system_category(),msg));
+    1767             :       if(h.code==10222) f(::std::system_error(h.error_code,::std::iostream_category(),msg));
+    1768             :       if(h.code==10223) f(::std::system_error(h.error_code,::std::future_category(),msg));
+    1769             : #endif
+    1770           0 :       if(h.code>=10230 && h.code<10240) {
+    1771             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1772             : // These cases are probably useless as it looks like this should always be std::iostream_category
+    1773             :         if(h.code==10230) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category())));
+    1774             :         if(h.code==10231) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category())));
+    1775             :         if(h.code==10232) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category())));
+    1776             :         if(h.code==10233) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category())));
+    1777             : #endif
+    1778           0 :         f(::std::ios_base::failure(msg));
+    1779             :       }
+    1780           0 :       f(::std::runtime_error(msg));
+    1781             :     }
+    1782             :     /* "bad" errors */
+    1783             :     /* "< ::" space required in C++ < 11 */
+    1784           0 :     if(h.code>=11000 && h.code<11100) f(add_buffer_to< ::std::bad_typeid>(msg));
+    1785           0 :     if(h.code>=11100 && h.code<11200) f(add_buffer_to< ::std::bad_cast>(msg));
+    1786             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1787             :     if(h.code>=11200 && h.code<11300) f(add_buffer_to< ::std::bad_weak_ptr>(msg));
+    1788             :     if(h.code>=11300 && h.code<11400) f(add_buffer_to< ::std::bad_function_call>(msg));
+    1789             : #endif
+    1790           0 :     if(h.code>=11400 && h.code<11500) {
+    1791             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1792             :       if(h.code>=11410 && h.code<11420) f(add_buffer_to< ::std::bad_array_new_length>(msg));
+    1793             : #endif
+    1794           0 :       f(add_buffer_to< ::std::bad_alloc>(msg));
+    1795             :     }
+    1796           0 :     if(h.code>=11500 && h.code<11600) f(add_buffer_to< ::std::bad_exception>(msg));
+    1797             :     /* lepton error */
+    1798           0 :     if(h.code>=19900 && h.code<20000) f(Plumed::LeptonException(msg));
+    1799             :     /* plumed exceptions */
+    1800           0 :     if(h.code>=20000 && h.code<30000) {
+    1801             :       /* debug - only raised with debug options */
+    1802           0 :       if(h.code>=20100 && h.code<20200) f(Plumed::ExceptionDebug(msg));
+    1803             :       /* error - runtime check */
+    1804           0 :       if(h.code>=20200 && h.code<20300) f(Plumed::ExceptionError(msg));
+    1805             :       /* error - type error */
+    1806           0 :       if(h.code>=20300 && h.code<20400) f(Plumed::ExceptionTypeError(msg));
+    1807           0 :       f(Plumed::Exception(msg));
+    1808             :     }
+    1809             :     /* fallback for any other exception */
+    1810           0 :     f(add_buffer_to< ::std::exception>(msg));
+    1811             :   }
+    1812             : 
+    1813             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    1814             :   /** Internal class used by exception_dispatch. */
+    1815             :   class rethrow_nested {
+    1816             :   public:
+    1817             :     template<typename E>
+    1818             :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1819           0 :       std::throw_with_nested(e);
+    1820             :     }
+    1821             :   };
+    1822             : #endif
+    1823             : 
+    1824             :   /** Internal class used by exception_dispatch. */
+    1825             :   class rethrow_not_nested {
+    1826             :   public:
+    1827             :     template<typename E>
+    1828           0 :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1829           0 :       throw e;
+    1830             :     }
+    1831             :   };
+    1832             : 
+    1833             :   /** Internal class to simplify plumed_error finalization */
+    1834             :   class finalize_plumed_error {
+    1835             :     plumed_error&e;
+    1836             :     finalize_plumed_error(const finalize_plumed_error&); //not implemented
+    1837             :   public:
+    1838             :     __PLUMED_WRAPPER_CXX_EXPLICIT finalize_plumed_error(plumed_error&e):
+    1839             :       e(e)
+    1840             :     {}
+    1841             :     ~finalize_plumed_error() {
+    1842           0 :       plumed_error_finalize(e);
+    1843           0 :       e.code=0; // make sure it's not finalized again
+    1844             :     }
+    1845             :   };
+    1846             : 
+    1847             :   /**
+    1848             :     Recursive function that rethrows an exception with all the nested ones.
+    1849             : 
+    1850             :     In order to do so, we start throwing from the first exception that was originally thrown
+    1851             :     and recursively throw the others using throw_with_nested.
+    1852             : 
+    1853             :     plumed_error h is finalized at exit by the exception_dispatch function, to avoid memory leaks
+    1854             :   */
+    1855           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(plumed_error&h) {
+    1856             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    1857             :     /*
+    1858             :       When using C++11 nested exceptions, we need to rethrow recursively
+    1859             :     */
+    1860             :     try {
+    1861           0 :       if(h.nested) rethrow(*h.nested); /* recursive throw */
+    1862           0 :     } catch(...) {
+    1863           0 :       exception_dispatch(h,rethrow_nested());
+    1864           0 :     }
+    1865           0 :     exception_dispatch(h,rethrow_not_nested());
+    1866             : #else
+    1867             :     /*
+    1868             :       When using C++<11 exceptions, we merge the message and then throw the resulting exception
+    1869             :     */
+    1870             :     if(h.nested) plumed_error_merge_with_nested(&h);
+    1871             :     exception_dispatch(h,rethrow_not_nested());
+    1872             : #endif
+    1873             :   }
+    1874             : 
+    1875             : public:
+    1876             :   /**
+    1877             :     This is a tool to rethrow an error as an exception and finalize the error.
+    1878             : 
+    1879             :     In practice, this makes it possible to write a code like this:
+    1880             :     ```
+    1881             :     Plumed p;
+    1882             :     plumed_error e;
+    1883             :     // store error in e if something wrong happes
+    1884             :     // notice that Plumed (C++) is implicitly converted to plumed (C) when calling plumed_cmd
+    1885             :     plumed_cmd(p,"init",&e);
+    1886             :     // do other things here
+    1887             :     // then throw the exception
+    1888             :     if(e.code) plumed_error_rethrow(e);
+    1889             : 
+    1890             :     It should be used through the macro plumed_error_rethrow.
+    1891             :     ```
+    1892             :   */
+    1893             :   __PLUMED_WRAPPER_CXX_NORETURN static void plumed_error_rethrow_cxx(plumed_error h) {
+    1894           0 :     rethrow(h);
+    1895             :   }
+    1896             : 
+    1897             : private:
+    1898             :   /**
+    1899             :     Rethrow the current exception.
+    1900             : 
+    1901             :     This is useful in order to handle an exception thrown by a kernel <=2.4.
+    1902             :     Only std exceptions are handled, though some of them are thrown as special
+    1903             :     Plumed exceptions in order to be attached a message.
+    1904             :   */
+    1905           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
+    1906             :     try {
+    1907           0 :       throw;
+    1908           0 :     } catch(const ::std::bad_exception & e) {
+    1909           0 :       throw add_buffer_to< ::std::bad_exception>(e.what());
+    1910             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1911             :     } catch(const ::std::bad_array_new_length & e) {
+    1912             :       throw add_buffer_to< ::std::bad_array_new_length>(e.what());
+    1913             : #endif
+    1914           0 :     } catch(const ::std::bad_alloc & e) {
+    1915           0 :       throw add_buffer_to< ::std::bad_alloc>(e.what());
+    1916             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1917             :     } catch(const ::std::bad_function_call & e) {
+    1918             :       throw add_buffer_to< ::std::bad_function_call>(e.what());
+    1919             :     } catch(const ::std::bad_weak_ptr & e) {
+    1920             :       throw add_buffer_to< ::std::bad_weak_ptr>(e.what());
+    1921             : #endif
+    1922           0 :     } catch(const ::std::bad_cast & e) {
+    1923           0 :       throw add_buffer_to< ::std::bad_cast>(e.what());
+    1924           0 :     } catch(const ::std::bad_typeid & e) {
+    1925           0 :       throw add_buffer_to< ::std::bad_typeid>(e.what());
+    1926             :       // not implemented yet: std::regex_error
+    1927             :       // we do not allow regex yet due to portability problems with gcc 4.8
+    1928             :       // as soon as we transition to using <regex> it should be straightforward to add
+    1929           0 :     } catch(const ::std::ios_base::failure & e) {
+    1930             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1931             :       throw ::std::ios_base::failure(e.what(),e.code());
+    1932             : #else
+    1933           0 :       throw ::std::ios_base::failure(e.what());
+    1934             : #endif
+    1935             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1936             :     } catch(const ::std::system_error & e) {
+    1937             :       throw ::std::system_error(e.code(),e.what());
+    1938             : #endif
+    1939           0 :     } catch(const ::std::underflow_error &e) {
+    1940           0 :       throw ::std::underflow_error(e.what());
+    1941           0 :     } catch(const ::std::overflow_error &e) {
+    1942           0 :       throw ::std::overflow_error(e.what());
+    1943           0 :     } catch(const ::std::range_error &e) {
+    1944           0 :       throw ::std::range_error(e.what());
+    1945           0 :     } catch(const ::std::runtime_error & e) {
+    1946           0 :       throw ::std::runtime_error(e.what());
+    1947             :       // not implemented yet: std::future_error
+    1948             :       // not clear how useful it would be.
+    1949           0 :     } catch(const ::std::out_of_range & e) {
+    1950           0 :       throw ::std::out_of_range(e.what());
+    1951           0 :     } catch(const ::std::length_error & e) {
+    1952           0 :       throw ::std::length_error(e.what());
+    1953           0 :     } catch(const ::std::domain_error & e) {
+    1954           0 :       throw ::std::domain_error(e.what());
+    1955           0 :     } catch(const ::std::invalid_argument & e) {
+    1956           0 :       throw ::std::invalid_argument(e.what());
+    1957           0 :     } catch(const ::std::logic_error & e) {
+    1958           0 :       throw ::std::logic_error(e.what());
+    1959           0 :     } catch(const ::std::exception & e) {
+    1960           0 :       throw add_buffer_to< ::std::exception>(e.what());
+    1961           0 :     } catch(...) {
+    1962           0 :       throw add_buffer_to< ::std::bad_exception>("plumed could not translate exception");
+    1963           0 :     }
+    1964             :   }
+    1965             : 
+    1966             : public:
+    1967             : 
+    1968             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    1969             :   using Exception = PLMD::Exception;
+    1970             : #else
+    1971             :   /**
+    1972             :     Base class used to rethrow PLUMED exceptions.
+    1973             :   */
+    1974             :   class Exception :
+    1975             :     public ::std::exception
+    1976             :   {
+    1977             :     ::std::string msg;
+    1978             :   public:
+    1979           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
+    1980           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    1981             : #if ! (__cplusplus > 199711L)
+    1982             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    1983             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    1984             :     ~Exception() throw() {}
+    1985             : #endif
+    1986             :   };
+    1987             : #endif
+    1988             : 
+    1989             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    1990             :   using ExceptionError = PLMD::ExceptionError;
+    1991             : #else
+    1992             :   /**
+    1993             :     Used to rethrow a PLMD::ExceptionError
+    1994             :   */
+    1995           0 :   class ExceptionError :
+    1996             :     public Exception {
+    1997             :   public:
+    1998           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
+    1999             : #if ! (__cplusplus > 199711L)
+    2000             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2001             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2002             :     ~ExceptionError() throw() {}
+    2003             : #endif
+    2004             :   };
+    2005             : #endif
+    2006             : 
+    2007             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2008             :   using ExceptionDebug = PLMD::ExceptionDebug;
+    2009             : #else
+    2010             :   /**
+    2011             :     Used to rethrow a PLMD::ExceptionDebug
+    2012             :   */
+    2013           0 :   class ExceptionDebug :
+    2014             :     public Exception {
+    2015             :   public:
+    2016           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
+    2017             : #if ! (__cplusplus > 199711L)
+    2018             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2019             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2020             :     ~ExceptionDebug() throw() {}
+    2021             : #endif
+    2022             :   };
+    2023             : #endif
+    2024             : 
+    2025             :   /**
+    2026             :     Thrown when trying to access an invalid plumed object
+    2027             :   */
+    2028             : 
+    2029           0 :   class Invalid :
+    2030             :     public Exception {
+    2031             :   public:
+    2032           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
+    2033             : #if ! (__cplusplus > 199711L)
+    2034             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2035             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2036             :     ~Invalid() throw() {}
+    2037             : #endif
+    2038             :   };
+    2039             : 
+    2040             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2041             :   using ExceptionTypeError = PLMD::ExceptionTypeError;
+    2042             : #else
+    2043             :   /**
+    2044             :     Thrown when a wrong pointer is passed to the PLUMED interface.
+    2045             :   */
+    2046           0 :   class ExceptionTypeError:
+    2047             :     public Exception {
+    2048             :   public:
+    2049           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
+    2050             : #if ! (__cplusplus > 199711L)
+    2051             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2052             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2053             :     ~ExceptionTypeError() throw() {}
+    2054             : #endif
+    2055             :   };
+    2056             : #endif
+    2057             : 
+    2058             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2059             :   using LeptonException = PLMD::lepton::Exception;
+    2060             : #else
+    2061             :   /**
+    2062             :     Class used to rethrow Lepton exceptions.
+    2063             :   */
+    2064             : 
+    2065             :   class LeptonException :
+    2066             :     public ::std::exception
+    2067             :   {
+    2068             :     ::std::string msg;
+    2069             :   public:
+    2070           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
+    2071           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2072             : #if ! (__cplusplus > 199711L)
+    2073             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2074             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2075             :     ~LeptonException() throw() {}
+    2076             : #endif
+    2077             :   };
+    2078             : #endif
+    2079             : 
+    2080             : private:
+    2081             :   /*
+    2082             :     These exceptions are declared as private as they are not supposed to be
+    2083             :     catched by value. they only exist to allow a buffer to be attached to
+    2084             :     the std::exceptions that do not contain it already.
+    2085             :     Notice that these exceptions are those whose constructor should never throw, and as
+    2086             :     such they use a fixed size buffer.
+    2087             :   */
+    2088             : 
+    2089             :   template<typename T>
+    2090           0 :   class add_buffer_to:
+    2091             :     public T
+    2092             :   {
+    2093             :     char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER]; \
+    2094             :   public:
+    2095           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT add_buffer_to(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2096           0 :       this->msg[0]='\0';
+    2097           0 :       __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
+    2098           0 :       this->msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1]='\0';
+    2099           0 :       if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
+    2100           0 :     }
+    2101           0 :     add_buffer_to(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2102           0 :       msg[0]='\0';
+    2103           0 :       __PLUMED_WRAPPER_STD memcpy(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER);
+    2104             :     }
+    2105             :     add_buffer_to & operator=(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2106             :       if(this==&other) return *this;
+    2107             :       msg[0]='\0';
+    2108             :       __PLUMED_WRAPPER_STD memcpy(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER);
+    2109             :       return *this;
+    2110             :     }
+    2111           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg;}
+    2112             : #if ! (__cplusplus > 199711L)
+    2113             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2114             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2115             :     ~add_buffer_to() throw() {}
+    2116             : #endif
+    2117             :   };
+    2118             : 
+    2119             : private:
+    2120             :   /// Small class that wraps plumed_safeptr in order to make its initialization easier
+    2121             :   class SafePtr {
+    2122             :     /// non copyable (copy would require managing buffer, could be added in the future if needed)
+    2123             :     SafePtr(const SafePtr&);
+    2124             :     /// non assignable (assignment would require managing buffer, could be added in the future if needed)
+    2125             :     SafePtr& operator=(SafePtr const&);
+    2126             :   public:
+    2127             :     plumed_safeptr safe;
+    2128             :     /// This buffer holds a copy of the data when they are passed by value.
+    2129             :     /// The size is sufficient to hold any primitive type.
+    2130             :     /// Notice that the buffer is required to enable conversions (e.g., passing a class that can be converted to int)
+    2131             :     /// and, at the same time, allow the object to exist after SafePtr constructor has completed.
+    2132             :     /// A perhaps cleaner implementation would require a base class containing
+    2133             :     /// the plumed_safeptr object, derived classes depending on the
+    2134             :     /// argument type as a template parameter, and overloaded functions
+    2135             :     /// returning this derived class.
+    2136             :     char buffer[32];
+    2137             :     /// Default constructor, nullptr
+    2138             :     SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2139             :       safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2140             :       safe.nelem=0;
+    2141             :       safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2142             :       safe.flags=0x10000*2;
+    2143             :       safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2144             :       buffer[0]='\0';
+    2145             :     }
+    2146             : 
+    2147         222 :     __PLUMED_WRAPPER_CXX_EXPLICIT SafePtr(const plumed_safeptr & safe,__PLUMED_WRAPPER_STD size_t nelem=0, const __PLUMED_WRAPPER_STD size_t* shape=__PLUMED_WRAPPER_CXX_NULLPTR) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2148         222 :       this->safe=safe;
+    2149         222 :       buffer[0]='\0';
+    2150             :       if(nelem>0) this->safe.nelem=nelem;
+    2151             :       if(shape) this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
+    2152             :     }
+    2153             : 
+    2154             : #if __cplusplus > 199711L
+    2155             :     /// Construct from null
+    2156             :     SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
+    2157             :       safe.ptr=nullptr;
+    2158             :       safe.nelem=0;
+    2159             :       safe.shape=nullptr;
+    2160             :       safe.flags=0x10000*2;
+    2161             :       safe.opt=nullptr;
+    2162             :       buffer[0]='\0';
+    2163             :       (void) nelem;
+    2164             :       (void) shape;
+    2165             :     }
+    2166             : #endif
+    2167             : 
+    2168             : /// Macro that generate a constructor with given type and flags
+    2169             : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
+    2170             :   SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2171             :     safe.ptr=ptr; \
+    2172             :     safe.nelem=nelem; \
+    2173             :     safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
+    2174             :     safe.flags=flags_; \
+    2175             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2176             :     buffer[0]='\0'; \
+    2177             :   }
+    2178             : 
+    2179             : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
+    2180             : /// all possible pointer-const combinations
+    2181             : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
+    2182             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type,             size | (0x10000*(code)) | (0x2000000*2)) \
+    2183             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+    2184             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+    2185             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+    2186             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+    2187             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
+    2188             : 
+    2189             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+    2190             : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
+    2191             : 
+    2192             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+    2193             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+    2194             : /// allow pass-by-value
+    2195             : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
+    2196             :   __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
+    2197             :   SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2198             :     assert(sizeof(type)<=32); \
+    2199             :     (void) nelem; \
+    2200             :     (void) shape; \
+    2201             :     safe.ptr=buffer; \
+    2202             :     safe.nelem=1; \
+    2203             :     safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2204             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    2205             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2206             :     __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
+    2207             :   }
+    2208             : 
+    2209             : /// Here we create all the required instances
+    2210             : /// 1: void
+    2211             : /// 3: integral
+    2212             : /// 4: floating
+    2213             : /// 5: FILE
+    2214             : /// 0x100: unsigned
+    2215         338 :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
+    2216        4133 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+    2217             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
+    2218             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
+    2219             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
+    2220             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
+    2221        8266 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
+    2222             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
+    2223             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
+    2224             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
+    2225             : #if __PLUMED_WRAPPER_CXX_LONGLONG
+    2226             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
+    2227             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
+    2228             : #endif
+    2229             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
+    2230             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
+    2231             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
+    2232             :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
+    2233             : 
+    2234             :     /// Return the contained plumed_safeptr
+    2235             :     plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2236       12959 :       return safe;
+    2237             :     }
+    2238             : 
+    2239             :   };
+    2240             : 
+    2241             : public:
+    2242             : 
+    2243             :   /**
+    2244             :      Check if plumed is installed (for runtime binding)
+    2245             :      \return true if plumed is installed, false otherwise
+    2246             :      \note Equivalent to plumed_installed() but returns a bool
+    2247             :   */
+    2248             :   static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2249             :     return plumed_installed();
+    2250             :   }
+    2251             :   /**
+    2252             :      Check if Plumed object is valid. Available as of PLUMED 2.5
+    2253             :      \return true if plumed is valid, false otherwise
+    2254             :      \note Equivalent to plumed_valid() but returns a bool
+    2255             :   */
+    2256             :   bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2257             :     return plumed_valid(main);
+    2258             :   }
+    2259             : #if __cplusplus > 199711L
+    2260             :   /**
+    2261             :      Same as \ref valid(). Available as of PLUMED 2.5.
+    2262             : 
+    2263             :   Allow code such as
+    2264             :   \verbatim
+    2265             :   Plumed p;
+    2266             :   if(!p) raise_error();
+    2267             :   p.cmd("init");
+    2268             :   \endverbatim
+    2269             : 
+    2270             :   In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
+    2271             :   where it is marked as explicit.
+    2272             :   */
+    2273             :   explicit
+    2274             :   operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2275             :     return plumed_valid(main);
+    2276             :   }
+    2277             : #endif
+    2278             : 
+    2279             :   /**
+    2280             :      Returns the number of references to this object. Available as of PLUMED 2.5.
+    2281             :     \note Equivalent to plumed_use_count()
+    2282             :   */
+    2283             :   int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2284             :     return plumed_use_count(main);
+    2285             :   }
+    2286             : 
+    2287             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2288             :   /**
+    2289             :      Check if global-plumed has been initialized
+    2290             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
+    2291             :              called), false otherwise.
+    2292             :      \note Equivalent to plumed_ginitialized() but returns a bool
+    2293             :   */
+    2294             :   static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2295             :     return plumed_ginitialized();
+    2296             :   }
+    2297             :   /**
+    2298             :      Check if global-plumed is valid
+    2299             :      \return true if global plumed object (see global()) is valid.
+    2300             :      \note Equivalent to plumed_gvalid() but returns a bool
+    2301             :   */
+    2302             :   static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2303             :     return plumed_gvalid();
+    2304             :   }
+    2305             :   /**
+    2306             :      Initialize global-plumed.
+    2307             :      \warning Using the global objects in C++ is not recommended since they are difficult to use in
+    2308             :               an exception safe manner. In particular, one should explicitly catch exceptions to
+    2309             :               properly call gfinalize()
+    2310             :      \note Equivalent to plumed_gcreate()
+    2311             :   */
+    2312             :   static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2313             :     plumed_gcreate();
+    2314             :   }
+    2315             :   /**
+    2316             :      Send a command to global-plumed
+    2317             :       \param key The name of the command to be executed
+    2318             :      \note Equivalent to plumed_gcmd()
+    2319             :   */
+    2320             :   static void gcmd(const char*key) {
+    2321             :     global().cmd(key);
+    2322             :   }
+    2323             :   /**
+    2324             :      Send a command to global-plumed
+    2325             :       \param key The name of the command to be executed
+    2326             :       \param val The argument.
+    2327             :      \note Equivalent to plumed_gcmd()
+    2328             :   */
+    2329             :   template<typename T>
+    2330             :   static void gcmd(const char*key,T val) {
+    2331             :     global().cmd(key,val);
+    2332             :   }
+    2333             :   /**
+    2334             :      Send a command to global-plumed
+    2335             :       \param key The name of the command to be executed
+    2336             :       \param val The argument.
+    2337             :       \param nelem Number of elements in the passed array, for typechecking.
+    2338             :      \note Equivalent to plumed_gcmd()
+    2339             :   */
+    2340             :   template<typename T>
+    2341             :   static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
+    2342             :     global().cmd(key,val,nelem);
+    2343             :   }
+    2344             : 
+    2345             :   /**
+    2346             :      Send a command to global-plumed
+    2347             :       \param key The name of the command to be executed
+    2348             :       \param val The argument.
+    2349             :       \param shape The shape of the argument.
+    2350             :      \note Equivalent to plumed_gcmd()
+    2351             :   */
+    2352             :   template<typename T>
+    2353             :   static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2354             :     global().cmd(key,val,shape);
+    2355             :   }
+    2356             : 
+    2357             : #if __cplusplus > 199711L
+    2358             :   /**
+    2359             :      Send a command to global-plumed
+    2360             :       \param key The name of the command to be executed
+    2361             :       \param val The argument.
+    2362             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2363             :      \note Equivalent to plumed_gcmd()
+    2364             :   */
+    2365             :   template<typename T>
+    2366             :   static void gcmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2367             :     global().cmd(key,val,shape);
+    2368             :   }
+    2369             : #endif
+    2370             : 
+    2371             :   /**
+    2372             :      Finalize global-plumed
+    2373             :   */
+    2374             :   static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2375             :     plumed_gfinalize();
+    2376             :   }
+    2377             :   /**
+    2378             :      Returns the Plumed global object
+    2379             : 
+    2380             :      Notice that the object is copied, thus increasing the reference counter of the
+    2381             :      global object. In this manner, the global object will survive after a call to
+    2382             :      \ref gfinalize() if the resulting object is still in scope.
+    2383             : 
+    2384             :      \return The Plumed global object
+    2385             :   */
+    2386             :   static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2387             :     return Plumed(plumed_global());
+    2388             :   }
+    2389             : #endif /*}*/
+    2390             :   /**
+    2391             :      Constructor.
+    2392             : 
+    2393             :     Notice that when using runtime binding the constructed object might be
+    2394             :     invalid. One might check it using the \ref valid() method.
+    2395             : 
+    2396             :     \note Performs the same task a plumed_create()
+    2397             :   */
+    2398        4133 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2399             : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+    2400             :   main(plumed_create_invalid())
+    2401             : #else
+    2402        4133 :   main(plumed_create())
+    2403             : #endif
+    2404             :   {
+    2405             :   }
+    2406             : 
+    2407             :   /**
+    2408             :      Clone a Plumed object from a FORTRAN char* handler.
+    2409             : 
+    2410             :      \param c The FORTRAN handler (a char[32]).
+    2411             : 
+    2412             :      The reference counter for the corresponding object will be increased
+    2413             :      to make sure that the object will be available after plumed_f_finalize is called
+    2414             :      if the created object is still in scope.
+    2415             :   */
+    2416             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2417             :   main(plumed_create_reference_f(c))
+    2418             :   {
+    2419             :   }
+    2420             : 
+    2421             :   /**
+    2422             :     Create a reference from a void* pointer. Available as of PLUMED 2.5.
+    2423             :   */
+    2424             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2425             :   main(plumed_create_reference_v(v))
+    2426             :   {
+    2427             :   }
+    2428             : 
+    2429             :   /**
+    2430             :      Clone a Plumed object from a C plumed structure
+    2431             : 
+    2432             :      \param p The C plumed structure.
+    2433             : 
+    2434             :      The reference counter for the corresponding object will be increased
+    2435             :      to make sure that the object will be available after plumed_finalize is called
+    2436             :      if the created object is still in scope.
+    2437             :   */
+    2438             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2439             :   main(plumed_create_reference(p))
+    2440             :   {
+    2441             :   }
+    2442             : 
+    2443             :   /** Copy constructor.
+    2444             : 
+    2445             :     Takes a reference, incrementing the reference counter of the corresponding object.
+    2446             :   */
+    2447             : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2448             :   main(plumed_create_reference(p.main))
+    2449             :   {
+    2450             :   }
+    2451             : 
+    2452             :   /** Assignment operator. Available as of PLUMED 2.5.
+    2453             : 
+    2454             :     Takes a reference,incrementing the reference counter of the corresponding object.
+    2455             :   */
+    2456             :   Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2457             :     if(this != &p) {
+    2458             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2459             :       if(main.p) plumed_finalize(main);
+    2460             :       main=plumed_create_reference(p.main);
+    2461             :     }
+    2462             :     return *this;
+    2463             :   }
+    2464             : 
+    2465             :   /*
+    2466             :     PLUMED >= 2.4 requires a C++11 compiler.
+    2467             :     Anyway, since Plumed.h file might be redistributed with other codes
+    2468             :     and it should be possible to combine it with earlier PLUMED versions,
+    2469             :     we here explicitly check if C+11 is available before enabling move semantics.
+    2470             :   */
+    2471             : #if __cplusplus > 199711L
+    2472             :   /** Move constructor. Available as of PLUMED 2.5.
+    2473             :     Only if move semantics is enabled.
+    2474             :   */
+    2475             : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2476             :   main(p.main)
+    2477             :   {
+    2478             :     p.main.p=nullptr;
+    2479             :   }
+    2480             :   /** Move assignment. Available as of PLUMED 2.5.
+    2481             :     Only if move semantics is enabled.
+    2482             :   */
+    2483             :   Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2484             :     if(this != &p) {
+    2485             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2486             :       if(main.p) plumed_finalize(main);
+    2487             :       main=p.main;
+    2488             :       p.main.p=nullptr;
+    2489             :     }
+    2490             :     return *this;
+    2491             :   }
+    2492             : #endif
+    2493             :   /**
+    2494             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2495             : 
+    2496             :     It returns an object created with \ref plumed_create_dlopen. The object is owned and
+    2497             :     is then finalized in the destructor. It can be used as follows:
+    2498             :   \verbatim
+    2499             :     PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2500             :   // or, equivalenty:
+    2501             :   //    PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
+    2502             :     p.cmd("init");
+    2503             :   \endverbatim
+    2504             :     or, equivalently, as
+    2505             :   \verbatim
+    2506             :     auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2507             :     p.cmd("init");
+    2508             :   \endverbatim
+    2509             :   */
+    2510             :   static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2511             :     plumed p=plumed_create_dlopen(path);
+    2512             :     Plumed pp(p);
+    2513             :     plumed_finalize(p);
+    2514             :     return pp;
+    2515             :   }
+    2516             : 
+    2517             :   /**
+    2518             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2519             : 
+    2520             :     Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
+    2521             :   */
+    2522             :   static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2523             :     plumed p=plumed_create_dlopen2(path,mode);
+    2524             :     Plumed pp(p);
+    2525             :     plumed_finalize(p);
+    2526             :     return pp;
+    2527             :   }
+    2528             :   /**
+    2529             :     Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
+    2530             : 
+    2531             :     Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
+    2532             :     See \ref plumed_create_dlsym.
+    2533             :   */
+    2534             :   static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2535             :     plumed p=plumed_create_dlsym(dlhandle);
+    2536             :     Plumed pp(p);
+    2537             :     plumed_finalize(p);
+    2538             :     return pp;
+    2539             :   }
+    2540             : 
+    2541             :   /** Invalid constructor. Available as of PLUMED 2.5.
+    2542             : 
+    2543             :     Can be used to initialize an invalid object. It might be useful to postpone
+    2544             :     the initialization of a Plumed object. Consider the following case
+    2545             :   \verbatim
+    2546             :     Plumed p;
+    2547             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2548             :     p.cmd("init")
+    2549             :   \endverbatim
+    2550             :     Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
+    2551             :     This can be particularly problematic if `p` is stored in some high level class.
+    2552             :     The following case would do the job
+    2553             :   \verbatim
+    2554             :     Plumed p;
+    2555             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2556             :     p=Plumed();
+    2557             :     p.cmd("init")
+    2558             :   \endverbatim
+    2559             :     However, there will be some error reported related to the attempt to load the kernel
+    2560             :     when `p` is initialized. The following solution is the optimal one:
+    2561             :   \verbatim
+    2562             :     Plumed p(Plumed::makeInvalid());
+    2563             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2564             :     p=Plumed();
+    2565             :     p.cmd("init")
+    2566             :   \endverbatim
+    2567             :   */
+    2568             :   static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2569             :     plumed p=plumed_create_invalid();
+    2570             :     Plumed pp(p);
+    2571             :     plumed_finalize(p);
+    2572             :     return pp;
+    2573             :   }
+    2574             : 
+    2575             :   /**
+    2576             :     Create a valid PLMD::Plumed object.
+    2577             : 
+    2578             :     Can be used to create a valid object e.g. when Plumed.h was compiled with
+    2579             :     `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
+    2580             :   */
+    2581             : 
+    2582             :   static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2583             :     plumed p=plumed_create();
+    2584             :     Plumed pp(p);
+    2585             :     plumed_finalize(p);
+    2586             :     return pp;
+    2587             :   }
+    2588             : 
+    2589             : 
+    2590             :   /**
+    2591             :      Retrieve the C plumed structure for this object.
+    2592             : 
+    2593             :      Notice that the resulting plumed structure is a weak reference and
+    2594             :      should NOT be finalized, unless a new reference is explicitly added
+    2595             :   \verbatim
+    2596             :   Plumed p;
+    2597             :   plumed c=p;
+    2598             :   plumed_finalize(c); // <- this is wrong
+    2599             :   \endverbatim
+    2600             :   \verbatim
+    2601             :   Plumed p;
+    2602             :   plumed c=plumed_create_reference(p);
+    2603             :   plumed_finalize(c); // <- this is right
+    2604             :   \endverbatim
+    2605             :   */
+    2606             :   operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2607             :     return main;
+    2608             :   }
+    2609             : 
+    2610             :   /**
+    2611             :      Retrieve a FORTRAN handler for this object
+    2612             :       \param c The FORTRAN handler (a char[32]).
+    2613             :     Notice that the resulting plumed structure is a weak reference and
+    2614             :     should NOT be finalized, unless a new reference is explicitly added.
+    2615             :   */
+    2616             :   void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2617             :     plumed_c2f(main,c);
+    2618             :   }
+    2619             : 
+    2620             :   /**
+    2621             :      Retrieve a void* handler for this object. Available as of PLUMED 2.5.
+    2622             :     Notice that the resulting plumed structure is a weak reference and
+    2623             :     should NOT be finalized, unless a new reference is explicitly added.
+    2624             :   */
+    2625             :   void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2626             :     return plumed_c2v(main);
+    2627             :   }
+    2628             : 
+    2629             :   /**
+    2630             :     Increase reference counter. Available as of PLUMED 2.5.
+    2631             : 
+    2632             :     Using this method improperly might interfere with correct object construction
+    2633             :     and destruction.
+    2634             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2635             : 
+    2636             :     A possible usage is to transfer the ownership of a temporary
+    2637             :     object when it is converted
+    2638             :   \verbatim
+    2639             :   plumed p=Plumed::dlopen(path).incref()
+    2640             :   // without incref(), the just constructed object will be destroyed
+    2641             :   // when the temporary object is deleted.
+    2642             :   ... do stuff ...
+    2643             :   plumed_finalize(p);
+    2644             :   \endverbatim
+    2645             : 
+    2646             :   */
+    2647             :   Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2648             :     plumed_create_reference(main);
+    2649             :     return *this;
+    2650             :   }
+    2651             : 
+    2652             :   /**
+    2653             :     Decrease reference counter. Available as of PLUMED 2.5.
+    2654             : 
+    2655             :     Using this method improperly might interfere with correct object construction
+    2656             :     and destruction.
+    2657             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2658             :   */
+    2659             :   Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2660             : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
+    2661             :     plumed_finalize(main);
+    2662             :     return *this;
+    2663             :   }
+    2664             : 
+    2665             : private:
+    2666             : 
+    2667             :   /**
+    2668             :     Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
+    2669             :   */
+    2670       12959 :   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) {
+    2671             : 
+    2672             :     plumed_error error_cxx;
+    2673             :     plumed_error_init(&error_cxx);
+    2674             : 
+    2675             :     plumed_nothrow_handler nothrow;
+    2676       12959 :     if(error) {
+    2677             :       plumed_error_init(error);
+    2678           0 :       nothrow.ptr=error;
+    2679             :     } else {
+    2680       12959 :       nothrow.ptr=&error_cxx;
+    2681             :     }
+    2682       12959 :     nothrow.handler=plumed_error_set;
+    2683             : 
+    2684             :     try {
+    2685       12959 :       if(safe) {
+    2686       12959 :         plumed_cmd_safe_nothrow(main,key,safe->get_safeptr(),nothrow);
+    2687             :       } else {
+    2688           0 :         plumed_cmd_nothrow(main,key,unsafe,nothrow);
+    2689             :       }
+    2690           0 :     } catch (...) {
+    2691             :       assert(error_cxx.code==0); /* no need to plumed_error_finalize here */
+    2692             :       /*
+    2693             :         When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
+    2694             :         If the exception is transmitted through the C interface and arrives here,
+    2695             :         we translate it so as to free the virtual tables of the loaded kernel.
+    2696             :       */
+    2697           0 :       rethrow();
+    2698           0 :     }
+    2699             :     /* plumed_error_rethrow is finalizing */
+    2700       12959 :     if(!error && error_cxx.code!=0) plumed_error_rethrow_cxx(error_cxx);
+    2701       12959 :   }
+    2702             : 
+    2703             : public:
+    2704             : 
+    2705             :   /**
+    2706             :      Send a command to this plumed object
+    2707             :       \param key The name of the command to be executed
+    2708             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2709             :             rethrow any exception raised within PLUMED.
+    2710             :   */
+    2711             :   void cmd(const char*key) {
+    2712             :     plumed_cmd_cxx(main,key);
+    2713             :   }
+    2714             : 
+    2715             :   /**
+    2716             :      Send a command to this plumed object
+    2717             :       \param key The name of the command to be executed
+    2718             :       \param val The argument, passed by value.
+    2719             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2720             :             rethrow any exception raised within PLUMED.
+    2721             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2722             :              the type of the argument is checked.
+    2723             :   */
+    2724             :   template<typename T>
+    2725             :   void cmd(const char*key,T val) {
+    2726       12737 :     plumed_cmd_cxx(main,key,val);
+    2727       12737 :   }
+    2728             : 
+    2729             :   /**
+    2730             :      Send a command to this plumed object
+    2731             :       \param key The name of the command to be executed
+    2732             :       \param val The argument, passed by pointer.
+    2733             :       \param shape A zero-terminated array containing the shape of the data.
+    2734             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2735             :             rethrow any exception raised within PLUMED.
+    2736             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2737             :              the type of the argument is checked. If shape is passed, it is also
+    2738             :              checked that PLUMED access only compatible indexes.
+    2739             :   */
+    2740             :   template<typename T>
+    2741             :   void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2742             :     plumed_cmd_cxx(main,key,val,shape);
+    2743             :   }
+    2744             : 
+    2745             : #if __cplusplus > 199711L
+    2746             :   /**
+    2747             :      Send a command to this plumed object
+    2748             :       \param key The name of the command to be executed
+    2749             :       \param val The argument, passed by pointer.
+    2750             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2751             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2752             :             rethrow any exception raised within PLUMED.
+    2753             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2754             :              the type of the argument is checked. If shape is passed, it is also
+    2755             :              checked that PLUMED access only compatible indexes.
+    2756             :   */
+    2757             :   template<typename T>
+    2758             :   void cmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2759             :     if(shape.size()>4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    2760             :     std::array<std::size_t,5> shape_;
+    2761             :     unsigned j=0;
+    2762             :     for(auto i : shape) {
+    2763             :       shape_[j]=i;
+    2764             :       j++;
+    2765             :     }
+    2766             :     shape_[j]=0;
+    2767             :     plumed_cmd_cxx(main,key,val,&shape_[0]);
+    2768             :   }
+    2769             : #endif
+    2770             :   /**
+    2771             :      Send a command to this plumed object
+    2772             :       \param key The name of the command to be executed
+    2773             :       \param val The argument, passed by pointer.
+    2774             :       \param nelem The number of elements passed.
+    2775             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2776             :             rethrow any exception raised within PLUMED.
+    2777             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2778             :              the type of the argument is checked.  nelem is used to check
+    2779             :              the maximum index interpreting the array as flattened.
+    2780             :   */
+    2781             :   template<typename T>
+    2782             :   void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    2783             :     plumed_cmd_cxx(main,key,val,nelem);
+    2784             :   }
+    2785             : 
+    2786             :   /**
+    2787             :      Destructor
+    2788             : 
+    2789             :      It calls \ref plumed_finalize(). Notice that this is done also if the
+    2790             :      constructor failed (that is, if it returned an invalid object). This allows
+    2791             :      declaring Plumed objects also if PLUMED is actually not available, provided
+    2792             :      one does not use the \ref cmd method.
+    2793             : 
+    2794             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
+    2795             :   */
+    2796             : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
+    2797             :   virtual
+    2798             : #endif
+    2799             :   ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2800             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2801        4133 :     if(main.p) plumed_finalize(main);
+    2802        4133 :   }
+    2803             : 
+    2804             :   /**
+    2805             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2806             :     namely implement typechecks and rethrowing exception.
+    2807             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2808             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2809             :     Available as of PLUMED 2.8.
+    2810             :   */
+    2811             :   static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2812             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2813             :     SafePtr s;
+    2814             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2815             : #else
+    2816             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2817             : #endif
+    2818             :   }
+    2819             : 
+    2820             :   /**
+    2821             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2822             :     namely implement typechecks and rethrowing exception.
+    2823             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2824             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2825             :     Available as of PLUMED 2.8.
+    2826             :   */
+    2827             :   template<typename T>
+    2828         222 :   static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2829             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2830             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2831         222 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2832             : #else
+    2833             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,&val,error);
+    2834             : #endif
+    2835         222 :   }
+    2836             : 
+    2837             :   /**
+    2838             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2839             :     namely implement typechecks and rethrowing exception.
+    2840             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2841             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2842             :     Available as of PLUMED 2.8.
+    2843             :   */
+    2844             :   template<typename T>
+    2845       12737 :   static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2846             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2847             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2848       12737 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2849             : #else
+    2850             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2851             : #endif
+    2852       12737 :   }
+    2853             : 
+    2854             :   /**
+    2855             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2856             :     namely implement typechecks and rethrowing exception.
+    2857             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2858             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2859             :     Available as of PLUMED 2.8.
+    2860             :   */
+    2861             :   template<typename T>
+    2862             :   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) {
+    2863             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2864             :     SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2865             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2866             : #else
+    2867             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2868             : #endif
+    2869             :   }
+    2870             : 
+    2871             :   /**
+    2872             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2873             :     namely implement typechecks and rethrowing exception.
+    2874             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2875             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2876             :     Available as of PLUMED 2.8.
+    2877             :   */
+    2878             :   template<typename T>
+    2879             :   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) {
+    2880             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2881             :     SafePtr s(val,0,shape);
+    2882             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2883             : #else
+    2884             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    2885             : #endif
+    2886             :   }
+    2887             : 
+    2888             : 
+    2889             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2890             :   /**
+    2891             :     \related Plumed
+    2892             :     This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
+    2893             :     namely implement typechecks and rethrowing exception.
+    2894             :     To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2895             :     Available as of PLUMED 2.8.
+    2896             :   */
+    2897             : 
+    2898             :   /**
+    2899             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2900             :     namely implement typechecks and rethrowing exception.
+    2901             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2902             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2903             :     Available as of PLUMED 2.8.
+    2904             :   */
+    2905             :   static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2906             :     plumed_cmd_cxx(plumed_global(),key,error);
+    2907             :   }
+    2908             : 
+    2909             :   /**
+    2910             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2911             :     namely implement typechecks and rethrowing exception.
+    2912             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2913             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2914             :     Available as of PLUMED 2.8.
+    2915             :   */
+    2916             :   template<typename T>
+    2917             :   static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2918             :     plumed_cmd_cxx(plumed_global(),key,val,error);
+    2919             :   }
+    2920             : 
+    2921             :   /**
+    2922             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2923             :     namely implement typechecks and rethrowing exception.
+    2924             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2925             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2926             :     Available as of PLUMED 2.8.
+    2927             :   */
+    2928             :   template<typename T>
+    2929             :   static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2930             :     plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
+    2931             :   }
+    2932             : 
+    2933             :   /**
+    2934             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2935             :     namely implement typechecks and rethrowing exception.
+    2936             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2937             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2938             :     Available as of PLUMED 2.8.
+    2939             :   */
+    2940             :   template<typename T>
+    2941             :   static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2942             :     plumed_cmd_cxx(plumed_global(),key,val,shape,error);
+    2943             :   }
+    2944             : 
+    2945             : #endif /*}*/
+    2946             : 
+    2947             : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
+    2948             : 
+    2949             : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
+    2950             : 
+    2951             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2952             : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
+    2953             : #endif /*}*/
+    2954             : 
+    2955             : #define __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW ::PLMD::Plumed::plumed_error_rethrow_cxx
+    2956             : 
+    2957             : #endif /*}*/
+    2958             : 
+    2959             : };
+    2960             : 
+    2961             : /**
+    2962             :   \related Plumed
+    2963             :   Comparison operator. Available as of PLUMED 2.5.
+    2964             : */
+    2965             : inline
+    2966             : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2967             :   return a.toVoid()==b.toVoid();
+    2968             : }
+    2969             : 
+    2970             : /**
+    2971             :   \related Plumed
+    2972             :   Comparison operator. Available as of PLUMED 2.5.
+    2973             : */
+    2974             : inline
+    2975             : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2976             :   return a.toVoid()!=b.toVoid();
+    2977             : }
+    2978             : 
+    2979             : /**
+    2980             :   \related Plumed
+    2981             :   Comparison operator. Available as of PLUMED 2.5.
+    2982             : */
+    2983             : inline
+    2984             : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2985             :   return a.toVoid()<=b.toVoid();
+    2986             : }
+    2987             : 
+    2988             : /**
+    2989             :   \related Plumed
+    2990             :   Comparison operator. Available as of PLUMED 2.5.
+    2991             : */
+    2992             : inline
+    2993             : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2994             :   return a.toVoid()<b.toVoid();
+    2995             : }
+    2996             : 
+    2997             : /**
+    2998             :   \related Plumed
+    2999             :   Comparison operator. Available as of PLUMED 2.5.
+    3000             : */
+    3001             : inline
+    3002             : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3003             :   return a.toVoid()>=b.toVoid();
+    3004             : }
+    3005             : 
+    3006             : /**
+    3007             :   \related Plumed
+    3008             :   Comparison operator. Available as of PLUMED 2.5.
+    3009             : */
+    3010             : inline
+    3011             : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3012             :   return a.toVoid()>b.toVoid();
+    3013             : }
+    3014             : 
+    3015             : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
+    3016             : 
+    3017             : }
+    3018             : 
+    3019             : #endif /*}*/
+    3020             : 
+    3021             : #endif /*}*/
+    3022             : 
+    3023             : /* END OF DECLARATIONS */
+    3024             : 
+    3025             : /*
+    3026             : 
+    3027             :   1: emit implementation
+    3028             :   0: do not emit implementation
+    3029             : 
+    3030             :   Allows an implementation to be emitted together with the declarations.
+    3031             : 
+    3032             :   Used to decide if definitions should be emitted. This macro could have a different
+    3033             :   value when Plumed.h is reincluded. As a consequence, we map it to a local
+    3034             :   macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
+    3035             : */
+    3036             : 
+    3037             : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
+    3038             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
+    3039             : #else
+    3040             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
+    3041             : #endif
+    3042             : 
+    3043             : /* BEGINNING OF DEFINITIONS */
+    3044             : 
+    3045             : #if __PLUMED_WRAPPER_IMPLEMENTATION_  /*{*/
+    3046             : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
+    3047             : #define __PLUMED_wrapper_Plumed_implementation
+    3048             : 
+    3049             : /*
+    3050             :   the following macros only control the implementation
+    3051             : */
+    3052             : 
+    3053             : /*
+    3054             :   1: enable the definition of plumed_symbol_table_reexport
+    3055             :   0: does not enable the definition of plumed_symbol_table_reexport
+    3056             : 
+    3057             :   This is only needed in the official plumed library to make
+    3058             :   the symbol table available. This is a hack to reexport the function table
+    3059             :   and is only needed when creating the library libplumed.so.
+    3060             : */
+    3061             : 
+    3062             : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3063             : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
+    3064             : #endif
+    3065             : 
+    3066             : /*
+    3067             :   1: write on stderr changes in reference counters
+    3068             :   0: do not write changes in reference counters
+    3069             : 
+    3070             :   Used for debugging.
+    3071             : 
+    3072             :   Only used in definitions.
+    3073             : */
+    3074             : 
+    3075             : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3076             : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
+    3077             : #endif
+    3078             : 
+    3079             : /*
+    3080             :   1: emit plumed_kernel_register function (default)
+    3081             :   0: do not emit plumed_kernel_register function
+    3082             : 
+    3083             :   This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
+    3084             :   We might change its default in the future.
+    3085             : 
+    3086             :   Used only in definitions.
+    3087             : */
+    3088             : 
+    3089             : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3090             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
+    3091             : #endif
+    3092             : 
+    3093             : /*
+    3094             :   1: emit Fortran wrappers
+    3095             :   0: do not emit Fortran wrappers (default)
+    3096             : 
+    3097             :   Used only in definitions.
+    3098             : */
+    3099             : 
+    3100             : #ifndef __PLUMED_WRAPPER_FORTRAN
+    3101             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3102             : #endif
+    3103             : 
+    3104             : /*
+    3105             :   With internal interface, it does not make sense to emit kernel register or fortran interfaces
+    3106             : */
+    3107             : 
+    3108             : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
+    3109             : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3110             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
+    3111             : #undef __PLUMED_WRAPPER_FORTRAN
+    3112             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3113             : #endif /*}*/
+    3114             : 
+    3115             : #ifdef __PLUMED_HAS_DLOPEN
+    3116             : #include <dlfcn.h> /* dlopen dlerror dlsym */
+    3117             : #endif
+    3118             : 
+    3119             : #if __PLUMED_WRAPPER_CXX_STD
+    3120             : #include <cstdio>  /* fprintf */
+    3121             : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
+    3122             : #include <cassert> /* assert */
+    3123             : #include <cstdlib> /* getenv malloc free abort */
+    3124             : #include <climits> /* CHAR_BIT */
+    3125             : #else
+    3126             : #include <stdio.h>
+    3127             : #include <string.h>
+    3128             : #include <assert.h>
+    3129             : #include <stdlib.h>
+    3130             : #include <limits.h>
+    3131             : #endif
+    3132             : 
+    3133             : /**
+    3134             :   Function pointer to plumed_create
+    3135             : */
+    3136             : 
+    3137             : typedef void*(*plumed_create_pointer)(void);
+    3138             : /**
+    3139             :   Function pointer to plumed_cmd
+    3140             : */
+    3141             : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
+    3142             : 
+    3143             : /**
+    3144             :   Function pointer to plumed_finalize
+    3145             : */
+    3146             : typedef void(*plumed_finalize_pointer)(void*);
+    3147             : 
+    3148             : /**
+    3149             :    Holder for plumedmain function pointers.
+    3150             : */
+    3151             : typedef struct {
+    3152             :   plumed_create_pointer create;
+    3153             :   plumed_cmd_pointer cmd;
+    3154             :   plumed_finalize_pointer finalize;
+    3155             : } plumed_plumedmain_function_holder;
+    3156             : 
+    3157             : /**
+    3158             :   Holder for plumed symbol table.
+    3159             : 
+    3160             :   The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
+    3161             :   Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
+    3162             :   functions should be explicitly motivated. Here's the addition:
+    3163             : 
+    3164             :   version=2, cmd_nothrow.
+    3165             : 
+    3166             :   This function accepts an extra argument `plumed_nothrow_handler*handler`.
+    3167             :   In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
+    3168             :   An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
+    3169             :   of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
+    3170             :   is very risky since and object created in that way would not report any error if manipulated from the C interface.
+    3171             :   So, it looks like this is the only possibility.
+    3172             : 
+    3173             :   version=3, cmd_safe and cmd_safe_nothrow
+    3174             : 
+    3175             :   These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
+    3176             :   Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
+    3177             : 
+    3178             :   version=4, thread-safe reference counter
+    3179             : 
+    3180             :   These functions allow to access a thread-safe reference counter that is stored within the PlumedMain object.
+    3181             :   This allows avoiding to enable atomic access also the C compiler used build Plumed.c. It's added here and not as a new
+    3182             :   cmd since this is a very low-level functionality.
+    3183             : */
+    3184             : typedef struct {
+    3185             :   /**
+    3186             :     Version number.
+    3187             : 
+    3188             :     Minimum value is 1.
+    3189             :   */
+    3190             :   int version;
+    3191             :   /**
+    3192             :     Pointers to standard plumed functions (create/cmd/finalize).
+    3193             : 
+    3194             :     Always available.
+    3195             :   */
+    3196             :   plumed_plumedmain_function_holder functions;
+    3197             :   /**
+    3198             :     Pointer to a cmd function guaranteed not to throw exceptions.
+    3199             : 
+    3200             :     Available with version>=2.
+    3201             :   */
+    3202             :   void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
+    3203             :   /**
+    3204             :     Pointer to a cmd function that accepts typeinfos.
+    3205             : 
+    3206             :     Available with version>=3.
+    3207             :   */
+    3208             :   void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
+    3209             : 
+    3210             :   /**
+    3211             :     Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
+    3212             : 
+    3213             :     Available with version>=3.
+    3214             :   */
+    3215             :   void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
+    3216             : 
+    3217             :   /**
+    3218             :     Pointer to a function that increments the internal reference counter.
+    3219             : 
+    3220             :     Available with version>=4.
+    3221             :   */
+    3222             :   unsigned (*create_reference)(void*);
+    3223             :   /**
+    3224             :     Pointer to a function that decrements the internal reference counter.
+    3225             : 
+    3226             :     Available with version>=4.
+    3227             :   */
+    3228             :   unsigned (*delete_reference)(void*);
+    3229             :   /**
+    3230             :     Pointer to a function that returns the internal reference counter.
+    3231             : 
+    3232             :     Available with version>=4.
+    3233             :   */
+    3234             :   unsigned (*use_count)(void*);
+    3235             : } plumed_symbol_table_type;
+    3236             : 
+    3237             : /* Utility to convert function pointers to pointers, just for the sake of printing them */
+    3238             : #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))); }
+    3239             : 
+    3240             : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
+    3241             : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
+    3242             : 
+    3243             : /**
+    3244             :   Historically (PLUMED<=2.4) register for plumedmain function pointers.
+    3245             :   As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
+    3246             :   something. It always returns NULL. The function should be here anyway to allow an incomplete
+    3247             :   libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
+    3248             : */
+    3249             : #if __PLUMED_WRAPPER_KERNEL_REGISTER
+    3250             : /* Since it is only called from outside, it must be hardcoded to be extern */
+    3251             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    3252             : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
+    3253          13 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
+    3254             :   void* tmpptr;
+    3255          13 :   if(f) {
+    3256          13 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
+    3257           0 :       __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(const void*)f);
+    3258             :       __PLUMED_CONVERT_FPTR(tmpptr,f->create);
+    3259           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3260             :       __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
+    3261           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3262             :       __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
+    3263           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3264             :     }
+    3265             :   }
+    3266          13 :   return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3267             : }
+    3268             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    3269             : #endif
+    3270             : 
+    3271             : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
+    3272             : /**
+    3273             : Try to dlopen a path with a given mode.
+    3274             : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
+    3275             : 
+    3276             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3277             : It is first declared then defined to make sure it is a regular C static function.
+    3278             : */
+    3279             : 
+    3280             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3281           9 : void* plumed_attempt_dlopen(const char*path,int mode) {
+    3282             :   char* pathcopy;
+    3283             :   void* p;
+    3284             :   char* pc;
+    3285             :   __PLUMED_WRAPPER_STD size_t strlenpath;
+    3286             :   FILE* fp;
+    3287             :   pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3288             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3289             :   pc=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3290             :   strlenpath=0;
+    3291           9 :   fp=__PLUMED_WRAPPER_STD fopen(path,"r");
+    3292           9 :   if(!fp) {
+    3293           0 :     __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",path);
+    3294           0 :     return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3295             :   }
+    3296           9 :   __PLUMED_WRAPPER_STD fclose(fp);
+    3297           9 :   dlerror();
+    3298           9 :   p=dlopen(path,mode);
+    3299           9 :   if(!p) {
+    3300             :     /*
+    3301             :       Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
+    3302             :       and load directly the shared library. Notice that this particular path is only expected
+    3303             :       to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
+    3304             :       not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
+    3305             :       should work correctly without entering here.
+    3306             :     */
+    3307           0 :     __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3308           0 :     strlenpath=__PLUMED_WRAPPER_STD strlen(path);
+    3309           0 :     pathcopy=(char*) plumed_malloc(strlenpath+1);
+    3310           0 :     if(!pathcopy) {
+    3311           0 :       __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3312           0 :       __PLUMED_WRAPPER_STD abort();
+    3313             :     }
+    3314             :     __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
+    3315           0 :     pc=pathcopy+strlenpath-6;
+    3316           0 :     while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
+    3317           0 :     if(pc>=pathcopy) {
+    3318           0 :       __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
+    3319           0 :       __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
+    3320           0 :       __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
+    3321           0 :       fp=__PLUMED_WRAPPER_STD fopen(path,"r");
+    3322           0 :       if(!fp) {
+    3323           0 :         __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",pathcopy);
+    3324           0 :         plumed_free(pathcopy);
+    3325           0 :         return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3326             :       }
+    3327           0 :       __PLUMED_WRAPPER_STD fclose(fp);
+    3328           0 :       dlerror();
+    3329           0 :       p=dlopen(pathcopy,mode);
+    3330           0 :       if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3331             :     }
+    3332           0 :     plumed_free(pathcopy);
+    3333             :   }
+    3334             :   return p;
+    3335             : }
+    3336             : __PLUMED_WRAPPER_INTERNALS_END
+    3337             : 
+    3338             : /**
+    3339             :   Utility to search for a function.
+    3340             : */
+    3341             : #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
+    3342             :   if(!func) { \
+    3343             :     tmpptr=dlsym(handle,name); \
+    3344             :     if(tmpptr) { \
+    3345             :       *(void **)(&func)=tmpptr; \
+    3346             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
+    3347             :     } else { \
+    3348             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
+    3349             :     } \
+    3350             :   }
+    3351             : 
+    3352             : /**
+    3353             : Search symbols in a dlopened library.
+    3354             : 
+    3355             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3356             : */
+    3357             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3358           9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
+    3359             :   plumed_plumedmain_function_holder functions;
+    3360             :   plumed_symbol_table_type* table_ptr;
+    3361             :   void* tmpptr;
+    3362             :   char* debug;
+    3363             :   functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3364             :   functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3365             :   functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3366             :   table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3367           9 :   tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3368             :   /*
+    3369             :     Notice that as of PLUMED 2.5 we ignore self registrations.
+    3370             :     Pointers are searched in the form of a single pointer to a structure, which
+    3371             :     is the standard way in PLUMED 2.5, as well as using alternative names used in
+    3372             :     PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
+    3373             :     PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
+    3374             :     unnecessary and might be removed at some point.
+    3375             :   */
+    3376           9 :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3377           9 :   table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
+    3378           9 :   if(table_ptr) functions=table_ptr->functions;
+    3379           9 :   if(debug) {
+    3380           0 :     if(table_ptr) {
+    3381           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
+    3382           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
+    3383             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
+    3384           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3385             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
+    3386           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3387             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
+    3388           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3389             :     } else {
+    3390           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
+    3391             :     }
+    3392             :   }
+    3393             :   /* only searches if they were not found already */
+    3394           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
+    3395           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
+    3396           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
+    3397           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
+    3398           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
+    3399           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
+    3400           9 :   if(functions.create && functions.cmd && functions.finalize) {
+    3401           9 :     if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
+    3402           9 :     *f=functions;
+    3403           9 :     if(table) *table=table_ptr;
+    3404             :   } else {
+    3405           0 :     if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
+    3406           0 :     if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
+    3407           0 :     if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
+    3408           0 :     f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3409           0 :     f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3410           0 :     f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3411           0 :     if(table) *table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3412             :   }
+    3413           9 : }
+    3414             : __PLUMED_WRAPPER_INTERNALS_END
+    3415             : 
+    3416             : #endif /*}*/
+    3417             : 
+    3418             : 
+    3419             : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3420             : 
+    3421             : /*
+    3422             :   Here is the case where plumed_symbol_table is
+    3423             :   visible as extern. We first declare it (together with plumed_symbol_table_init) ...
+    3424             : */
+    3425             : 
+    3426             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3427             : extern
+    3428             : plumed_symbol_table_type plumed_symbol_table;
+    3429             : __PLUMED_WRAPPER_EXTERN_C_END
+    3430             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3431             : extern
+    3432             : void plumed_symbol_table_init(void);
+    3433             : __PLUMED_WRAPPER_EXTERN_C_END
+    3434             : 
+    3435             : /*
+    3436             :   ... and then make available a function that returns the address
+    3437             :   of the symbol table.
+    3438             : */
+    3439             : __PLUMED_WRAPPER_C_BEGIN
+    3440      678211 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
+    3441             :   /* make sure the table is initialized */
+    3442      678211 :   plumed_symbol_table_init();
+    3443      728228 :   return &plumed_symbol_table;
+    3444             : }
+    3445             : __PLUMED_WRAPPER_C_END
+    3446             : 
+    3447             : #else
+    3448             : 
+    3449             : /*
+    3450             :   Here is the case where plumed_symbol_table is not
+    3451             :   visible as extern. We thus assume that plumed_symbol_table_reexport is
+    3452             :   available.
+    3453             : */
+    3454             : 
+    3455             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3456             : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
+    3457             : __PLUMED_WRAPPER_EXTERN_C_END
+    3458             : #endif
+    3459             : 
+    3460             : 
+    3461             : /*
+    3462             :   Returns the global pointers, either those available at link time or those
+    3463             :   found in the library loaded at PLUMED_KERNEL env var.
+    3464             :   If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
+    3465             :   (if available).
+    3466             :   Notice that problems can be detected checking if the functions have a NULL ptr.
+    3467             :   On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
+    3468             :   If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
+    3469             : */
+    3470             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3471      707688 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
+    3472             : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
+    3473             :   /*
+    3474             :     Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
+    3475             :     This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
+    3476             :   */
+    3477      707688 :   plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
+    3478      730565 :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
+    3479      730565 :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3480      730565 :   if(functions) *functions=ptr->functions;
+    3481             : #elif ! defined(__PLUMED_HAS_DLOPEN)
+    3482             :   /*
+    3483             :     When dlopen is not available, we hard code them to NULL
+    3484             :   */
+    3485             :   __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
+    3486             :   plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
+    3487             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3488             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3489             :   if(functions) *functions=g;
+    3490             : #else
+    3491             :   /*
+    3492             :     On the other hand, for runtime binding, we use dlsym to find the relevant functions.
+    3493             :   */
+    3494             :   plumed_plumedmain_function_holder g;
+    3495             :   /* search is done once and only once */
+    3496             :   const char* path;
+    3497             :   void* p;
+    3498             :   char* debug;
+    3499             :   int dlopenmode;
+    3500             :   g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3501             :   g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3502             :   g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3503             :   path=__PLUMED_GETENV("PLUMED_KERNEL");
+    3504             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3505             :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3506             :   dlopenmode=0;
+    3507             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3508             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3509             : #ifdef __PLUMED_DEFAULT_KERNEL
+    3510             :   /*
+    3511             :     This variable allows a default path for the kernel to be hardcoded.
+    3512             :     Can be useful for hardcoding the predefined plumed location
+    3513             :     still allowing the user to override this choice setting PLUMED_KERNEL.
+    3514             :     The path should be chosen at compile time adding e.g.
+    3515             :     -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
+    3516             :   */
+    3517             :   /* This is required to add quotes */
+    3518             : #define PLUMED_QUOTE_DIRECT(name) #name
+    3519             : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
+    3520             :   if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
+    3521             : #endif
+    3522             :   if(path && (*path)) {
+    3523             :     __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
+    3524             :     __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
+    3525             :     if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
+    3526             :     dlopenmode=RTLD_NOW;
+    3527             :     if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"LOCAL")) {
+    3528             :       dlopenmode=dlopenmode|RTLD_LOCAL;
+    3529             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
+    3530             :     } else {
+    3531             :       dlopenmode=dlopenmode|RTLD_GLOBAL;
+    3532             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
+    3533             :     }
+    3534             : #ifdef RTLD_DEEPBIND
+    3535             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3536             :     if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
+    3537             :       dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3538             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
+    3539             :     }
+    3540             : #endif
+    3541             : #endif
+    3542             :     if(debug) __PLUMED_FPRINTF(stderr," +++\n");
+    3543             :     p=plumed_attempt_dlopen(path,dlopenmode);
+    3544             :     if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
+    3545             :   }
+    3546             :   if(handle) *handle=p;
+    3547             :   if(functions) *functions=g;
+    3548             : #endif
+    3549      730565 : }
+    3550             : __PLUMED_WRAPPER_INTERNALS_END
+    3551             : 
+    3552             : /**
+    3553             :   Implementation.
+    3554             :   Small object used to store pointers directly into the plumed object defined in Plumed.h.
+    3555             :   This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
+    3556             :   at the cost of an extra indirection.
+    3557             : */
+    3558             : typedef struct {
+    3559             :   /* allows errors with pointers to be found when debugging */
+    3560             :   char magic[6];
+    3561             :   /* reference count. this is only used with PLUMED<=2.8. Later versions have an internal thread-safe reference counter. */
+    3562             :   int refcount;
+    3563             :   /* handler to dlopened library. NULL if there was no library opened */
+    3564             :   void* dlhandle;
+    3565             :   /* non zero if, upon destruction, the library should be dlclosed */
+    3566             :   int dlclose;
+    3567             :   /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
+    3568             :   int used_plumed_kernel;
+    3569             :   /* function pointers */
+    3570             :   plumed_plumedmain_function_holder functions;
+    3571             :   /* pointer to the symbol table. NULL if kernel <=2.4 */
+    3572             :   plumed_symbol_table_type* table;
+    3573             :   /* pointer to plumed object */
+    3574             :   void* p;
+    3575             : } plumed_implementation;
+    3576             : 
+    3577             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3578      737714 : plumed_implementation* plumed_malloc_pimpl() {
+    3579             :   plumed_implementation* pimpl;
+    3580             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3581      737713 :   pimpl=(plumed_implementation*) plumed_malloc(sizeof(plumed_implementation));
+    3582      731003 :   if(!pimpl) {
+    3583           0 :     __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3584           0 :     __PLUMED_WRAPPER_STD abort();
+    3585             :   }
+    3586      731003 :   __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
+    3587      731003 :   pimpl->refcount=1;
+    3588             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3589             :   __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",(void*)pimpl);
+    3590             : #endif
+    3591      731003 :   pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3592      731003 :   pimpl->dlclose=0;
+    3593      731003 :   pimpl->used_plumed_kernel=0;
+    3594      731003 :   pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3595      731003 :   pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3596      731003 :   pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3597      731003 :   pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3598      731003 :   pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3599      731003 :   return pimpl;
+    3600             : }
+    3601             : __PLUMED_WRAPPER_INTERNALS_END
+    3602             : 
+    3603             : #ifndef NDEBUG
+    3604             : 
+    3605             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3606             : int plumed_check_pimpl(plumed_implementation*pimpl) {
+    3607             :   if(!pimpl) return 0;
+    3608             :   if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
+    3609             :   return 1;
+    3610             : }
+    3611             : __PLUMED_WRAPPER_INTERNALS_END
+    3612             : #endif
+    3613             : 
+    3614             : /* C wrappers: */
+    3615             : 
+    3616             : __PLUMED_WRAPPER_C_BEGIN
+    3617      737744 : plumed plumed_create(void) {
+    3618             :   /* returned object */
+    3619             :   plumed p;
+    3620             :   /* pointer to implementation */
+    3621             :   plumed_implementation* pimpl;
+    3622             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3623      737744 :   pimpl=plumed_malloc_pimpl();
+    3624             :   /* store pointers in pimpl */
+    3625      722960 :   plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
+    3626             : #if __PLUMED_WRAPPER_LINK_RUNTIME
+    3627             :   /* note if PLUMED_KERNEL variable was used */
+    3628             :   pimpl->used_plumed_kernel=1;
+    3629             : #endif
+    3630             :   /* note if handle should not be dlclosed */
+    3631      742347 :   pimpl->dlclose=1;
+    3632      742347 :   if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
+    3633             :   /* in case of failure, return */
+    3634             :   /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
+    3635      799071 :   if(!pimpl->functions.create) {
+    3636             :     /* store pimpl in returned object */
+    3637             :     p.p=pimpl;
+    3638           0 :     return p;
+    3639             :   }
+    3640             :   assert(pimpl->functions.cmd);
+    3641             :   assert(pimpl->functions.finalize);
+    3642             :   /* obtain object */
+    3643      799071 :   pimpl->p=(*(pimpl->functions.create))();
+    3644             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3645             :   /* user might identify this using plumed_valid() */
+    3646             :   /* store pimpl in returned object */
+    3647             :   p.p=pimpl;
+    3648      785447 :   return p;
+    3649             : }
+    3650             : __PLUMED_WRAPPER_C_END
+    3651             : 
+    3652             : __PLUMED_WRAPPER_C_BEGIN
+    3653           9 : plumed plumed_create_dlopen(const char*path) {
+    3654             :   int dlopenmode;
+    3655             :   /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
+    3656             : #ifdef __PLUMED_HAS_DLOPEN
+    3657             :   dlopenmode=RTLD_NOW|RTLD_LOCAL;
+    3658             : #ifdef RTLD_DEEPBIND
+    3659             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3660           9 :   if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3661             : #endif
+    3662             : #endif
+    3663             : #else
+    3664             :   dlopenmode=0;
+    3665             : #endif
+    3666           9 :   return plumed_create_dlopen2(path,dlopenmode);
+    3667             : }
+    3668             : __PLUMED_WRAPPER_C_END
+    3669             : 
+    3670             : __PLUMED_WRAPPER_C_BEGIN
+    3671           9 : plumed plumed_create_dlsym(void* dlhandle) {
+    3672             :   /* returned object */
+    3673             :   plumed p;
+    3674             :   /* pointer to implementation */
+    3675             :   plumed_implementation* pimpl;
+    3676             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3677           9 :   pimpl=plumed_malloc_pimpl();
+    3678             : #ifdef __PLUMED_HAS_DLOPEN
+    3679           9 :   pimpl->dlhandle=dlhandle;
+    3680           9 :   plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
+    3681             : #endif
+    3682           9 :   if(!pimpl->functions.create) {
+    3683             :     p.p=pimpl;
+    3684           0 :     return p;
+    3685             :   }
+    3686             :   assert(pimpl->functions.cmd);
+    3687             :   assert(pimpl->functions.finalize);
+    3688             :   /* obtain object */
+    3689           9 :   pimpl->p=(*(pimpl->functions.create))();
+    3690             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3691             :   /* user might identify this using plumed_valid() */
+    3692             :   /* store pimpl in returned object */
+    3693             :   p.p=pimpl;
+    3694           9 :   return p;
+    3695             : }
+    3696             : __PLUMED_WRAPPER_C_END
+    3697             : 
+    3698             : __PLUMED_WRAPPER_C_BEGIN
+    3699           9 : plumed plumed_create_dlopen2(const char*path,int mode) {
+    3700             : #ifdef __PLUMED_HAS_DLOPEN
+    3701             :   /* returned object */
+    3702             :   plumed p;
+    3703             :   /* pointer to implementation */
+    3704             :   plumed_implementation* pimpl;
+    3705             :   /* handler */
+    3706             :   void* dlhandle;
+    3707             :   dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3708           9 :   if(path) dlhandle=plumed_attempt_dlopen(path,mode);
+    3709             :   /* a NULL handle implies the file could not be loaded */
+    3710           9 :   if(dlhandle) {
+    3711           9 :     p=plumed_create_dlsym(dlhandle);
+    3712             :     /* obtain pimpl */
+    3713           9 :     pimpl=(plumed_implementation*) p.p;
+    3714             :     /* make sure the handler is closed when plumed is finalized */
+    3715           9 :     pimpl->dlclose=1;
+    3716           9 :     return p;
+    3717             :   }
+    3718             : #else
+    3719             :   (void) path;
+    3720             :   (void) mode;
+    3721             : #endif
+    3722           0 :   return plumed_create_invalid();
+    3723             : }
+    3724             : __PLUMED_WRAPPER_C_END
+    3725             : 
+    3726             : __PLUMED_WRAPPER_C_BEGIN
+    3727     7642099 : plumed plumed_create_reference(plumed p) {
+    3728             :   plumed_implementation* pimpl;
+    3729             :   /* obtain pimpl */
+    3730     7642099 :   pimpl=(plumed_implementation*) p.p;
+    3731             :   assert(plumed_check_pimpl(pimpl));
+    3732             :   /* increase reference count */
+    3733             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    3734     7642099 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    3735     7557163 :     pimpl->table->create_reference(pimpl->p);
+    3736             :   } else {
+    3737       84936 :     pimpl->refcount++;
+    3738             :   }
+    3739             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3740             :   __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",(void*)pimpl);
+    3741             : #endif
+    3742     7651980 :   return p;
+    3743             : }
+    3744             : __PLUMED_WRAPPER_C_END
+    3745             : 
+    3746             : __PLUMED_WRAPPER_C_BEGIN
+    3747           2 : plumed plumed_create_reference_v(void*v) {
+    3748           2 :   return plumed_create_reference(plumed_v2c(v));
+    3749             : }
+    3750             : __PLUMED_WRAPPER_C_END
+    3751             : 
+    3752             : __PLUMED_WRAPPER_C_BEGIN
+    3753           8 : plumed plumed_create_reference_f(const char*f) {
+    3754           8 :   return plumed_create_reference(plumed_f2c(f));
+    3755             : }
+    3756             : __PLUMED_WRAPPER_C_END
+    3757             : 
+    3758             : __PLUMED_WRAPPER_C_BEGIN
+    3759           2 : plumed plumed_create_invalid() {
+    3760             :   plumed p;
+    3761             :   plumed_implementation* pimpl;
+    3762           2 :   pimpl=plumed_malloc_pimpl();
+    3763             :   p.p=pimpl;
+    3764           2 :   return p;
+    3765             : }
+    3766             : __PLUMED_WRAPPER_C_END
+    3767             : 
+    3768             : __PLUMED_WRAPPER_C_BEGIN
+    3769         357 : void plumed_cmd(plumed p,const char*key,const void*val) {
+    3770             :   plumed_implementation* pimpl;
+    3771             :   /* obtain pimpl */
+    3772         357 :   pimpl=(plumed_implementation*) p.p;
+    3773             :   assert(plumed_check_pimpl(pimpl));
+    3774         357 :   if(!pimpl->p) {
+    3775           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3776           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3777           0 :     __PLUMED_WRAPPER_STD abort();
+    3778             :   }
+    3779             :   assert(pimpl->functions.create);
+    3780             :   assert(pimpl->functions.cmd);
+    3781             :   assert(pimpl->functions.finalize);
+    3782             :   /* execute */
+    3783         357 :   (*(pimpl->functions.cmd))(pimpl->p,key,val);
+    3784         357 : }
+    3785             : __PLUMED_WRAPPER_C_END
+    3786             : 
+    3787             : __PLUMED_WRAPPER_C_BEGIN
+    3788       14297 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
+    3789             :   plumed_implementation* pimpl;
+    3790             :   /* This is to allow caller to use a null handler to imply that handling is not done */
+    3791       14297 :   if(!nothrow.handler) {
+    3792          37 :     plumed_cmd_safe(p,key,safe);
+    3793          37 :     return;
+    3794             :   }
+    3795             :   /* obtain pimpl */
+    3796       14260 :   pimpl=(plumed_implementation*) p.p;
+    3797             :   assert(plumed_check_pimpl(pimpl));
+    3798       14260 :   if(!pimpl->p) {
+    3799           0 :     if(pimpl->used_plumed_kernel) {
+    3800           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);
+    3801             :     } else {
+    3802           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3803             :     }
+    3804           0 :     return;
+    3805             :   }
+    3806             :   assert(pimpl->functions.create);
+    3807             :   assert(pimpl->functions.cmd);
+    3808             :   assert(pimpl->functions.finalize);
+    3809             :   /* execute */
+    3810       14260 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
+    3811           0 :   else if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
+    3812           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3813             : }
+    3814             : __PLUMED_WRAPPER_C_END
+    3815             : 
+    3816             : __PLUMED_WRAPPER_C_BEGIN
+    3817           0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
+    3818             :   plumed_safeptr safe;
+    3819           0 :   safe.ptr=val;
+    3820           0 :   safe.flags=0;
+    3821           0 :   safe.nelem=0;
+    3822           0 :   safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3823           0 :   safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3824           0 :   plumed_cmd_safe_nothrow(p,key,safe,nothrow);
+    3825           0 : }
+    3826             : __PLUMED_WRAPPER_C_END
+    3827             : 
+    3828             : __PLUMED_WRAPPER_C_BEGIN
+    3829          95 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
+    3830             :   plumed_implementation* pimpl;
+    3831             :   /* obtain pimpl */
+    3832          95 :   pimpl=(plumed_implementation*) p.p;
+    3833             :   assert(plumed_check_pimpl(pimpl));
+    3834          95 :   if(!pimpl->p) {
+    3835           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3836           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3837           0 :     __PLUMED_WRAPPER_STD abort();
+    3838             :   }
+    3839             :   assert(pimpl->functions.create);
+    3840             :   assert(pimpl->functions.cmd);
+    3841             :   assert(pimpl->functions.finalize);
+    3842             :   /* execute */
+    3843          95 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
+    3844           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3845          95 : }
+    3846             : __PLUMED_WRAPPER_C_END
+    3847             : 
+    3848             : 
+    3849             : __PLUMED_WRAPPER_C_BEGIN
+    3850     8376024 : void plumed_finalize(plumed p) {
+    3851             :   plumed_implementation* pimpl;
+    3852             :   /* obtain pimpl */
+    3853     8376024 :   pimpl=(plumed_implementation*) p.p;
+    3854             :   assert(plumed_check_pimpl(pimpl));
+    3855             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3856             :   __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",(void*)pimpl);
+    3857             : #endif
+    3858             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    3859     8376024 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    3860     8348117 :     if(pimpl->table->delete_reference(pimpl->p)>0) return;
+    3861             :   } else {
+    3862       27907 :     if(--pimpl->refcount>0) return;
+    3863             :   }
+    3864             :   /* to allow finalizing an invalid plumed object, we only call
+    3865             :      finalize if the object is valid */
+    3866      778315 :   if(pimpl->p) {
+    3867             :     assert(pimpl->functions.create);
+    3868             :     assert(pimpl->functions.cmd);
+    3869             :     assert(pimpl->functions.finalize);
+    3870             :     /* finalize */
+    3871      778313 :     (*(pimpl->functions.finalize))(pimpl->p);
+    3872             :   }
+    3873             : #ifdef __PLUMED_HAS_DLOPEN
+    3874             :   /* dlclose library */
+    3875      761914 :   if(pimpl->dlhandle && pimpl->dlclose) {
+    3876           9 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
+    3877           9 :     dlclose(pimpl->dlhandle);
+    3878             :   }
+    3879             : #endif
+    3880             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3881             :   __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",(void*)pimpl);
+    3882             : #endif
+    3883             :   /* free pimpl space */
+    3884      761913 :   plumed_free(pimpl);
+    3885             : }
+    3886             : __PLUMED_WRAPPER_C_END
+    3887             : 
+    3888             : __PLUMED_WRAPPER_C_BEGIN
+    3889          23 : int plumed_valid(plumed p) {
+    3890             :   plumed_implementation* pimpl;
+    3891             :   /* obtain pimpl */
+    3892          23 :   pimpl=(plumed_implementation*) p.p;
+    3893             :   assert(plumed_check_pimpl(pimpl));
+    3894          24 :   if(pimpl->p) return 1;
+    3895           2 :   else return 0;
+    3896             : }
+    3897             : __PLUMED_WRAPPER_C_END
+    3898             : 
+    3899             : __PLUMED_WRAPPER_C_BEGIN
+    3900          42 : int plumed_use_count(plumed p) {
+    3901             :   plumed_implementation* pimpl;
+    3902             :   /* obtain pimpl */
+    3903          42 :   pimpl=(plumed_implementation*) p.p;
+    3904             :   assert(plumed_check_pimpl(pimpl));
+    3905             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    3906          42 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    3907          42 :     return pimpl->table->use_count(pimpl->p);
+    3908             :   } else {
+    3909           0 :     return pimpl->refcount;
+    3910             :   }
+    3911             : }
+    3912             : __PLUMED_WRAPPER_C_END
+    3913             : 
+    3914             : __PLUMED_WRAPPER_C_BEGIN
+    3915           9 : int plumed_installed(void) {
+    3916             :   plumed p;
+    3917             :   int result;
+    3918           9 :   p=plumed_create();
+    3919           9 :   result=plumed_valid(p);
+    3920           9 :   plumed_finalize(p);
+    3921           9 :   return result;
+    3922             : }
+    3923             : __PLUMED_WRAPPER_C_END
+    3924             : 
+    3925             : __PLUMED_WRAPPER_C_BEGIN
+    3926      735661 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size) {
+    3927             :   void* ptr;
+    3928      735662 :   ptr=__PLUMED_WRAPPER_STD malloc(size);
+    3929             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3930             :   if(ptr) fprintf(stderr,"plumed_malloc: %p\n",ptr);
+    3931             : #endif
+    3932      735661 :   return ptr;
+    3933             : }
+    3934             : __PLUMED_WRAPPER_C_END
+    3935             : 
+    3936             : __PLUMED_WRAPPER_C_BEGIN
+    3937      751876 : void plumed_free(void* ptr) {
+    3938      751876 :   __PLUMED_WRAPPER_STD free(ptr);
+    3939             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3940             :   fprintf(stderr,"plumed_free: %p\n",ptr);
+    3941             : #endif
+    3942      751877 : }
+    3943             : __PLUMED_WRAPPER_C_END
+    3944             : 
+    3945             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3946             : 
+    3947             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3948             : 
+    3949             : /* we declare a Plumed_g_main object here, in such a way that it is always available */
+    3950             : 
+    3951             : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
+    3952             : 
+    3953          41 : plumed plumed_global(void) {
+    3954          41 :   return plumed_gmain;
+    3955             : }
+    3956             : 
+    3957          22 : void plumed_gcreate(void) {
+    3958             :   /* should be created once */
+    3959             :   assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
+    3960          22 :   plumed_gmain=plumed_create();
+    3961          22 : }
+    3962             : 
+    3963          78 : void plumed_gcmd(const char*key,const void*val) {
+    3964          78 :   plumed_cmd(plumed_gmain,key,val);
+    3965          78 : }
+    3966             : 
+    3967             : /* cppcheck-suppress passedByValue */
+    3968           0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
+    3969           0 :   plumed_cmd_safe(plumed_gmain,key,safe);
+    3970           0 : }
+    3971             : 
+    3972          22 : void plumed_gfinalize(void) {
+    3973          22 :   plumed_finalize(plumed_gmain);
+    3974          22 :   plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3975          22 : }
+    3976             : 
+    3977          24 : int plumed_ginitialized(void) {
+    3978          24 :   if(plumed_gmain.p) return 1;
+    3979          16 :   else        return 0;
+    3980             : }
+    3981             : 
+    3982           8 : int plumed_gvalid() {
+    3983             :   assert(plumed_gmain.p);
+    3984           8 :   return plumed_valid(plumed_gmain);
+    3985             : }
+    3986             : 
+    3987             : __PLUMED_WRAPPER_EXTERN_C_END
+    3988             : 
+    3989             : #endif /*}*/
+    3990             : 
+    3991             : __PLUMED_WRAPPER_C_BEGIN
+    3992          56 : void plumed_c2f(plumed p,char*c) {
+    3993             :   unsigned i;
+    3994             :   unsigned char* cc;
+    3995             :   /*
+    3996             :     Convert the address stored in p.p into a proper FORTRAN string
+    3997             :     made of only ASCII characters. For this to work, the two following
+    3998             :     assertions should be satisfied:
+    3999             :   */
+    4000             :   assert(CHAR_BIT<=12);
+    4001             :   assert(sizeof(p.p)<=16);
+    4002             : 
+    4003             :   assert(c);
+    4004             :   cc=(unsigned char*)&p.p;
+    4005         504 :   for(i=0; i<sizeof(p.p); i++) {
+    4006             :     /*
+    4007             :       characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
+    4008             :     */
+    4009         448 :     c[2*i]=cc[i]/64+48;
+    4010         448 :     c[2*i+1]=cc[i]%64+48;
+    4011             :   }
+    4012         504 :   for(; i<16; i++) {
+    4013         448 :     c[2*i]=' ';
+    4014         448 :     c[2*i+1]=' ';
+    4015             :   }
+    4016          56 : }
+    4017             : __PLUMED_WRAPPER_C_END
+    4018             : 
+    4019             : __PLUMED_WRAPPER_C_BEGIN
+    4020         373 : plumed plumed_f2c(const char*c) {
+    4021             :   plumed p;
+    4022             :   unsigned i;
+    4023             :   unsigned char* cc;
+    4024             : 
+    4025             :   assert(CHAR_BIT<=12);
+    4026             :   assert(sizeof(p.p)<=16);
+    4027             : 
+    4028             :   assert(c);
+    4029             : 
+    4030             :   /*
+    4031             :      needed to avoid cppcheck warning on uninitialized p
+    4032             :   */
+    4033         373 :   p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4034             :   cc=(unsigned char*)&p.p;
+    4035        3357 :   for(i=0; i<sizeof(p.p); i++) {
+    4036             :     assert(c[2*i]>=48 && c[2*i]<48+64);
+    4037             :     assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
+    4038             :     /*
+    4039             :       perform the reversed transform
+    4040             :     */
+    4041        2984 :     cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
+    4042             :   }
+    4043        3357 :   for(; i<16; i++) {
+    4044             :     assert(c[2*i]==' ');
+    4045             :     assert(c[2*i+1]==' ');
+    4046             :   }
+    4047         373 :   return p;
+    4048             : }
+    4049             : __PLUMED_WRAPPER_C_END
+    4050             : 
+    4051             : __PLUMED_WRAPPER_C_BEGIN
+    4052           2 : void* plumed_c2v(plumed p) {
+    4053             :   assert(plumed_check_pimpl((plumed_implementation*)p.p));
+    4054           2 :   return p.p;
+    4055             : }
+    4056             : __PLUMED_WRAPPER_C_END
+    4057             : 
+    4058             : __PLUMED_WRAPPER_C_BEGIN
+    4059           2 : plumed plumed_v2c(void* v) {
+    4060             :   assert(plumed_check_pimpl((plumed_implementation*)v));
+    4061             :   plumed p;
+    4062             :   p.p=v;
+    4063           2 :   return p;
+    4064             : }
+    4065             : __PLUMED_WRAPPER_C_END
+    4066             : 
+    4067             : #if __PLUMED_WRAPPER_FORTRAN /*{*/
+    4068             : 
+    4069             : /*
+    4070             :   Fortran wrappers
+    4071             :   These are just like the global C wrappers. They are
+    4072             :   just defined here and not declared since they
+    4073             :   should not be used from c/c++ anyway.
+    4074             : 
+    4075             :   We use a macro that does the following:
+    4076             :   - declare a static function named NAME_static
+    4077             :   - declare a number of functions named NAME_ etc, with all possible
+    4078             :     fortran mangling schemes (zero, one, or two underscores, lower and upper case)
+    4079             :   - define the NAME_static function.
+    4080             : 
+    4081             :   The static function is used basically as an inline function in a C-compatible manner.
+    4082             : */
+    4083             : 
+    4084             : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
+    4085             :   static void lower ## _static arg1; \
+    4086             :   extern void lower      arg1 {lower ## _static arg2;} \
+    4087             :   extern void lower ##_  arg1 {lower ## _static arg2;} \
+    4088             :   extern void lower ##__ arg1 {lower ## _static arg2;} \
+    4089             :   extern void upper      arg1 {lower ## _static arg2;} \
+    4090             :   extern void upper ##_  arg1 {lower ## _static arg2;} \
+    4091             :   extern void upper ##__ arg1 {lower ## _static arg2;} \
+    4092             :   static void lower ## _static arg1
+    4093             : 
+    4094             : /* FORTRAN wrappers would only make sense as extern "C" */
+    4095             : 
+    4096             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4097             : 
+    4098          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
+    4099          18 :   plumed_c2f(plumed_create(),c);
+    4100          18 : }
+    4101             : 
+    4102          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
+    4103           6 :   plumed_c2f(plumed_create_dlopen(path),c);
+    4104           6 : }
+    4105             : 
+    4106          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
+    4107           6 :   plumed_c2f(plumed_create_reference_f(r),c);
+    4108           6 : }
+    4109             : 
+    4110           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
+    4111           0 :   plumed_c2f(plumed_create_invalid(),c);
+    4112           0 : }
+    4113             : 
+    4114         558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
+    4115         279 :   plumed_cmd(plumed_f2c(c),key,val);
+    4116         279 : }
+    4117             : 
+    4118          60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
+    4119          30 :   plumed_finalize(plumed_f2c(c));
+    4120          30 : }
+    4121             : 
+    4122          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
+    4123             :   assert(i);
+    4124           6 :   *i=plumed_installed();
+    4125           6 : }
+    4126             : 
+    4127             : /* New in PLUMED 2.5 */
+    4128           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
+    4129             :   assert(i);
+    4130           0 :   *i=plumed_valid(plumed_f2c(c));
+    4131           0 : }
+    4132             : 
+    4133          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
+    4134             :   assert(i);
+    4135          18 :   *i=plumed_use_count(plumed_f2c(c));
+    4136          18 : }
+    4137             : 
+    4138             : /* New in PLUMED 2.8 */
+    4139             : 
+    4140             : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
+    4141             : 
+    4142             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
+    4143             : 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) {\
+    4144             :   plumed_safeptr safe; \
+    4145             :   safe.ptr=val; \
+    4146             :   safe.nelem=nelem; \
+    4147             :   safe.shape=shape; \
+    4148             :   safe.flags= (flags & (~0x1ffffffu)) + 0x10000*code + size; \
+    4149             :   safe.opt=opt; \
+    4150             :   return safe; \
+    4151             : }
+    4152             : 
+    4153             : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
+    4154             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
+    4155             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
+    4156             : 
+    4157             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
+    4158             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
+    4159             : 
+    4160             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
+    4161             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
+    4162             : 
+    4163          24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
+    4164           1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
+    4165          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
+    4166           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
+    4167          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
+    4168           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
+    4169           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
+    4170          20 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
+    4171             : 
+    4172             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4173             : 
+    4174          48 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
+    4175          24 :   plumed_c2f(plumed_gmain,c);
+    4176          24 : }
+    4177             : 
+    4178          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
+    4179             :   assert(i);
+    4180          18 :   *i=plumed_ginitialized();
+    4181          18 : }
+    4182             : 
+    4183          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
+    4184          14 :   plumed_gcreate();
+    4185          14 : }
+    4186             : 
+    4187         156 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
+    4188          78 :   plumed_gcmd(key,val);
+    4189          78 : }
+    4190             : 
+    4191          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
+    4192          14 :   plumed_gfinalize();
+    4193          14 : }
+    4194             : 
+    4195             : /* New in PLUMED 2.5 */
+    4196          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
+    4197             :   assert(i);
+    4198           6 :   *i=plumed_gvalid();
+    4199           6 : }
+    4200             : 
+    4201             : #endif /*}*/
+    4202             : 
+    4203             : __PLUMED_WRAPPER_EXTERN_C_END
+    4204             : 
+    4205             : #endif /*}*/
+    4206             : 
+    4207             : #endif /*}*/
+    4208             : 
+    4209             : #endif /*}*/
+    4210             : 
+    4211             : /* END OF DEFINITIONS */
+    4212             : 
+    4213             : /* reset variable to allow it to be redefined upon re-inclusion */
+    4214             : 
+    4215             : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
+    4216             : 
+    4217             : /* this macro is set in declarations */
+    4218             : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
+    4219             : #if defined(plumed_cmd)
+    4220             : #undef plumed_cmd
+    4221             : #endif
+    4222             : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
+    4223             : #endif
+    4224             : 
+    4225             : /* this macro is set in declarations */
+    4226             : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
+    4227             : #if defined(plumed_gcmd)
+    4228             : #undef plumed_gcmd
+    4229             : #endif
+    4230             : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
+    4231             : #endif
+    4232             : 
+    4233             : /* this macro is set in declarations */
+    4234             : #ifdef __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4235             : #if defined(plumed_error_rethrow)
+    4236             : #undef plumed_error_rethrow
+    4237             : #endif
+    4238             : #define plumed_error_rethrow __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4239             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-f.html b/coverage/wrapper/index-sort-f.html new file mode 100644 index 0000000000..c04acc57e0 --- /dev/null +++ b/coverage/wrapper/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
52.7%52.7%
+
52.7 %247 / 46957.1 %144 / 252
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-l.html b/coverage/wrapper/index-sort-l.html new file mode 100644 index 0000000000..17e899fcdb --- /dev/null +++ b/coverage/wrapper/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
52.7%52.7%
+
52.7 %247 / 46957.1 %144 / 252
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index.html b/coverage/wrapper/index.html new file mode 100644 index 0000000000..0586499b47 --- /dev/null +++ b/coverage/wrapper/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:24746952.7 %
Date:2024-05-27 13:05:14Functions:14425257.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
52.7%52.7%
+
52.7 %247 / 46957.1 %144 / 252
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + 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. + +